cm-admin 0.8.8 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/.stylelintrc.json +3 -0
- data/.github/workflows/linters.yml +31 -0
- data/Gemfile +5 -1
- data/Gemfile.lock +20 -9
- data/app/assets/stylesheets/cm_admin/base/auth.scss +1 -1
- data/app/assets/stylesheets/cm_admin/base/common.scss +3 -3
- data/app/assets/stylesheets/cm_admin/base/filters.scss +11 -17
- data/app/assets/stylesheets/cm_admin/base/form.scss +6 -12
- data/app/assets/stylesheets/cm_admin/base/main-nav.scss +3 -7
- data/app/assets/stylesheets/cm_admin/base/navbar.scss +3 -2
- data/app/assets/stylesheets/cm_admin/base/quicksearch.scss +4 -6
- data/app/assets/stylesheets/cm_admin/base/scaffold.scss +45 -2
- data/app/assets/stylesheets/cm_admin/base/show.scss +11 -9
- data/app/assets/stylesheets/cm_admin/base/sidebar.scss +9 -19
- data/app/assets/stylesheets/cm_admin/base/table.scss +258 -325
- data/app/assets/stylesheets/cm_admin/base/tabs.scss +1 -2
- data/app/assets/stylesheets/cm_admin/components/_buttons.scss +19 -6
- data/app/assets/stylesheets/cm_admin/components/_drawer.scss +4 -8
- data/app/assets/stylesheets/cm_admin/components/_dropdown-popup.scss +1 -2
- data/app/assets/stylesheets/cm_admin/components/_input.scss +1 -1
- data/app/assets/stylesheets/cm_admin/components/_status-tag.scss +3 -2
- data/app/assets/stylesheets/cm_admin/helpers/_variable.scss +4 -0
- data/app/assets/stylesheets/cm_admin/scaffold.scss +2 -2
- data/app/controllers/cm_admin/resource_controller.rb +4 -2
- data/app/helpers/cm_admin/application_helper.rb +6 -0
- data/app/javascript/packs/cm_admin/filters.js +1 -1
- data/app/javascript/packs/cm_admin/scaffolds.js +4 -1
- data/app/models/concerns/cm_admin/file_import.rb +13 -7
- data/app/views/cm_admin/main/_actions_dropdown.html.slim +2 -2
- data/app/views/cm_admin/main/_associated_table.html.slim +25 -23
- data/app/views/cm_admin/main/_member_custom_action_modal.html.slim +1 -1
- data/app/views/cm_admin/main/_table.html.slim +14 -15
- data/app/views/cm_admin/main/associated_index.html.slim +4 -5
- data/app/views/cm_admin/main/index.html.slim +13 -14
- data/app/views/cm_admin/main/show.html.slim +2 -2
- data/app/views/layouts/cm_admin.html.slim +5 -5
- data/lib/cm_admin/model.rb +6 -1
- data/lib/cm_admin/models/action.rb +1 -1
- data/lib/cm_admin/models/column.rb +16 -3
- data/lib/cm_admin/models/dsl_method.rb +17 -4
- data/lib/cm_admin/models/field.rb +7 -1
- data/lib/cm_admin/models/utils/associations.rb +25 -0
- data/lib/cm_admin/version.rb +1 -1
- data/lib/cm_admin/view_helpers/field_display_helper.rb +25 -1
- data/lib/cm_admin/view_helpers/page_info_helper.rb +7 -3
- data/package-lock.json +2801 -158
- data/package.json +2 -0
- data/tmp/cache/webpacker/last-compilation-digest-development +1 -1
- data/yarn.lock +6949 -5133
- metadata +6 -3
@@ -1,14 +1,16 @@
|
|
1
1
|
@import '../helpers/index.scss';
|
2
2
|
|
3
3
|
.cta-btn {
|
4
|
-
padding:
|
4
|
+
padding: 5px 10px;
|
5
5
|
@include font($size: $t4-text, $color: $white, $weight: bold);
|
6
6
|
background-color: $brand-color;
|
7
7
|
border: none;
|
8
8
|
border-radius: $radius-4;
|
9
9
|
transition: all .2s linear;
|
10
10
|
&:hover {
|
11
|
-
|
11
|
+
color: $white;
|
12
|
+
background: $cta-hover-gradient;
|
13
|
+
transform: scale(1.05);
|
12
14
|
}
|
13
15
|
&:focus {
|
14
16
|
outline: 3px auto rgba(47, 128, 237, 0.3);
|
@@ -25,14 +27,16 @@
|
|
25
27
|
}
|
26
28
|
|
27
29
|
.primary-btn {
|
28
|
-
padding:
|
30
|
+
padding: 5px 10px;
|
29
31
|
@include font($size: $t4-text, $color: $brand-color, $weight: bold);
|
30
32
|
background-color: $white;
|
31
33
|
border: 1px solid $brand-color;
|
32
34
|
border-radius: $radius-4;
|
33
35
|
transition: all .2s linear;
|
34
36
|
&:hover {
|
37
|
+
color: $brand-color;
|
35
38
|
background-color: #E6E4FA;
|
39
|
+
transform: scale(1.05);
|
36
40
|
}
|
37
41
|
&:focus {
|
38
42
|
outline: 3px auto rgba(47, 128, 237, 0.3);
|
@@ -50,14 +54,16 @@
|
|
50
54
|
}
|
51
55
|
|
52
56
|
.secondary-btn {
|
53
|
-
padding:
|
57
|
+
padding: 5px 10px;
|
54
58
|
@include font($size: $t4-text, $color: $primary-text-clr, $weight: bold);
|
55
59
|
background-color: $white;
|
56
60
|
border: 1px solid $ink-regular-clr;
|
57
61
|
border-radius: $radius-4;
|
58
62
|
transition: all .2s linear;
|
59
63
|
&:hover {
|
64
|
+
color: $primary-text-clr;
|
60
65
|
background-color: $grey-light-clr;
|
66
|
+
transform: scale(1.05);
|
61
67
|
}
|
62
68
|
&:focus {
|
63
69
|
outline: 3px auto rgba(47, 128, 237, 0.3);
|
@@ -75,17 +81,22 @@
|
|
75
81
|
span:nth-child(2) {
|
76
82
|
margin: 0 4px 0 8px;
|
77
83
|
}
|
84
|
+
span:nth-child(3) {
|
85
|
+
@include font($size: 10px, $color: $ink-lighter-clr, $weight: bold);
|
86
|
+
}
|
78
87
|
}
|
79
88
|
|
80
89
|
.gray-border-btn {
|
81
|
-
padding:
|
90
|
+
padding: 5px 10px;
|
82
91
|
@include font($size: $t4-text, $color: $primary-text-clr, $weight: bold);
|
83
92
|
background-color: $white;
|
84
93
|
border: 1px solid $ink-regular-clr;
|
85
94
|
border-radius: $radius-4;
|
86
95
|
transition: all .2s linear;
|
87
96
|
&:hover {
|
97
|
+
color: $primary-text-clr;
|
88
98
|
background-color: $grey-light-clr;
|
99
|
+
transform: scale(1.05);
|
89
100
|
}
|
90
101
|
&:focus {
|
91
102
|
outline: 3px auto rgba(47, 128, 237, 0.3);
|
@@ -103,14 +114,16 @@
|
|
103
114
|
}
|
104
115
|
|
105
116
|
.ghost-btn {
|
106
|
-
padding:
|
117
|
+
padding: 5px 10px;
|
107
118
|
@include font($size: $t4-text, $color: $primary-text-clr, $weight: bold);
|
108
119
|
background-color: transparent;
|
109
120
|
border: none;
|
110
121
|
border-radius: $radius-4;
|
111
122
|
transition: all .2s linear;
|
112
123
|
&:hover {
|
124
|
+
color: $primary-text-clr;
|
113
125
|
background: $grey-light-clr;
|
126
|
+
transform: scale(1.05);
|
114
127
|
}
|
115
128
|
&:focus {
|
116
129
|
outline: 3px auto rgba(47, 128, 237, 0.3);
|
@@ -21,21 +21,18 @@
|
|
21
21
|
align-items: center;
|
22
22
|
justify-content: space-between;
|
23
23
|
padding: 24px;
|
24
|
-
background:
|
24
|
+
background: $grey-lightest-clr;
|
25
25
|
&__lhs {
|
26
26
|
.title {
|
27
|
+
@include font($size: $t1-text, $color: $primary-text-clr, $weight: 600);
|
27
28
|
font-family: $primary-font;
|
28
|
-
font-size: $t1-text;
|
29
|
-
font-weight: 600;
|
30
29
|
line-height: 28px;
|
31
|
-
color: $primary-text-clr;
|
32
30
|
margin-bottom: 8px;
|
33
31
|
}
|
34
32
|
.description {
|
33
|
+
@include font($size: $t4-text, $color: $primary-text-clr);
|
35
34
|
font-family: $primary-font;
|
36
|
-
font-size: $t4-text;
|
37
35
|
line-height: 22px;
|
38
|
-
color: $primary-text-clr;
|
39
36
|
margin-bottom: 0;
|
40
37
|
}
|
41
38
|
}
|
@@ -46,10 +43,9 @@
|
|
46
43
|
.body {
|
47
44
|
padding: 24px;
|
48
45
|
.info-text {
|
46
|
+
@include font($size: $t4-text, $color: $primary-text-clr);
|
49
47
|
font-family: $primary-font;
|
50
|
-
font-size: $t4-text;
|
51
48
|
line-height: 22px;
|
52
|
-
color: $primary-text-clr;
|
53
49
|
}
|
54
50
|
}
|
55
51
|
}
|
@@ -6,6 +6,7 @@
|
|
6
6
|
padding: 4px;
|
7
7
|
color: $primary-text-clr;
|
8
8
|
background: $grey-lighter-clr;
|
9
|
+
border-radius: 2px;
|
9
10
|
&.success {
|
10
11
|
color: $green-regular-clr;
|
11
12
|
background: $green-lightest-clr;
|
@@ -25,7 +26,7 @@
|
|
25
26
|
cursor: pointer;
|
26
27
|
user-select: none;
|
27
28
|
&:hover {
|
28
|
-
background-color:
|
29
|
+
background-color: $grey-lighter-clr;
|
29
30
|
.filter-chip-remove {
|
30
31
|
display: block;
|
31
32
|
}
|
@@ -42,7 +43,7 @@
|
|
42
43
|
top: 0;
|
43
44
|
right: 0;
|
44
45
|
padding: 4px 16px;
|
45
|
-
background:
|
46
|
+
background: $gradient-one;
|
46
47
|
border-radius: $radius-4;
|
47
48
|
i {
|
48
49
|
font-size: 10px;
|
@@ -51,6 +51,10 @@ $subdued-text-clr: #D9DEE3;
|
|
51
51
|
$white: #FFFFFF;
|
52
52
|
$black: #000000;
|
53
53
|
|
54
|
+
// Gradient Colors
|
55
|
+
$gradient-one: linear-gradient(270deg, $grey-lighter-clr 81.75%, rgba(243, 244, 246, 0) 100%);
|
56
|
+
$cta-hover-gradient: linear-gradient(0deg, rgba(0, 0, 0, 0.24), rgba(0, 0, 0, 0.24)), $brand-color;
|
57
|
+
|
54
58
|
/* Typography */
|
55
59
|
$primary-font: 'Open Sans', sans-serif;
|
56
60
|
$font-size: (
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
.jGrowl {
|
4
4
|
color: $ink-regular-clr !important;
|
5
|
-
font-size:
|
5
|
+
font-size: $t4-text !important;
|
6
6
|
.success{
|
7
7
|
background-color: $green-light-clr !important;
|
8
8
|
}
|
@@ -17,7 +17,7 @@
|
|
17
17
|
|
18
18
|
.nested-field-wrapper {
|
19
19
|
label {
|
20
|
-
font-size:
|
20
|
+
font-size: $t4-text;
|
21
21
|
margin-bottom: 16px;
|
22
22
|
}
|
23
23
|
.nested-fields {
|
@@ -193,7 +193,9 @@ module CmAdmin
|
|
193
193
|
end
|
194
194
|
|
195
195
|
def resource_params(params)
|
196
|
-
|
196
|
+
columns = @model.ar_model.column_names
|
197
|
+
columns += @model.ar_model.stored_attributes.values.flatten
|
198
|
+
permittable_fields = @model.additional_permitted_fields + columns.reject { |i| CmAdmin::REJECTABLE_FIELDS.include?(i) }.map(&:to_sym)
|
197
199
|
permittable_fields += @model.ar_model.name.constantize.reflect_on_all_associations.map {|x|
|
198
200
|
next if x.options[:polymorphic]
|
199
201
|
if x.class.name.include?('HasOne')
|
@@ -207,7 +209,7 @@ module CmAdmin
|
|
207
209
|
nested_fields = nested_tables.uniq.map {|table|
|
208
210
|
Hash[
|
209
211
|
table.to_s + '_attributes',
|
210
|
-
table.to_s.classify.constantize.
|
212
|
+
table.to_s.classify.constantize.column_names.reject { |i| CmAdmin::REJECTABLE_FIELDS.include?(i) }.map(&:to_sym) + [:id, :_destroy]
|
211
213
|
]
|
212
214
|
}
|
213
215
|
permittable_fields += nested_fields
|
@@ -54,7 +54,7 @@ var getFilteredData = function(filterType, filterValue, filterColumn=null) {
|
|
54
54
|
success: function(data) {
|
55
55
|
var queryParam = jQuery.param(queryString)
|
56
56
|
window.history.pushState("", "", url + '?' + queryParam);
|
57
|
-
$('.index-page__table-container').html(data);
|
57
|
+
$('.cm-index-page__table-container').html(data);
|
58
58
|
},
|
59
59
|
error: function(jqxhr, textStatus, errorThrown) {
|
60
60
|
console.log(errorThrown, textStatus);
|
@@ -16,6 +16,9 @@ $(document).on('turbolinks:load', function () {
|
|
16
16
|
animation: 150
|
17
17
|
});
|
18
18
|
}
|
19
|
+
var headerElemHeight = $('.page-top-bar').height() + 64
|
20
|
+
var calculatedHeight = "calc(100vh - " + headerElemHeight+"px"+")"
|
21
|
+
$('.new-admin-table').css("maxHeight", calculatedHeight);
|
19
22
|
});
|
20
23
|
|
21
24
|
$(document).on("keypress keyup blur", "[data-behaviour='decimal-only'], [data-behaviour='filter'][data-filter-type='range']", function (e) {
|
@@ -70,4 +73,4 @@ $(document).on('click', '.drawer-close', function(e) {
|
|
70
73
|
setTimeout(() => {
|
71
74
|
$('.cm-drawer').addClass('hidden');
|
72
75
|
}, 300);
|
73
|
-
});
|
76
|
+
});
|
@@ -9,23 +9,29 @@ module CmAdmin::FileImport
|
|
9
9
|
page_title 'File Import'
|
10
10
|
page_description 'Manage all file import progress here'
|
11
11
|
|
12
|
+
filter [:id, :associated_model_name], :search, placeholder: 'ID, Table Name'
|
13
|
+
filter :status, :single_select,
|
14
|
+
collection: %w[in_progress success failed],
|
15
|
+
placeholder: 'Status'
|
16
|
+
filter :created_at, :date, placeholder: 'Created At'
|
17
|
+
|
12
18
|
column :id
|
13
19
|
column :imported_file_name, header: 'File'
|
14
|
-
column :created_at, header: '
|
15
|
-
column :completed_at, header: 'Completed At', field_type: :datetime, format: '%B %d, %Y, %H:%M %p'
|
16
|
-
column :associated_model_name, header: 'Model name'
|
17
|
-
column :added_by_name, header: 'Uploaded By'
|
20
|
+
column :created_at, header: 'Created At', field_type: :datetime, format: '%B %d, %Y, %H:%M %p'
|
18
21
|
column :status, field_type: :tag, tag_class: STATUS_TAG_COLOR
|
22
|
+
column :associated_model_name, header: 'Table name'
|
23
|
+
column :added_by_name, header: 'Uploaded By'
|
24
|
+
|
19
25
|
end
|
20
26
|
|
21
27
|
cm_show page_title: :id do
|
22
28
|
tab :profile, '' do
|
23
29
|
cm_show_section 'Import details' do
|
24
30
|
field :id, label: 'Import ID'
|
25
|
-
field :
|
26
|
-
field :created_at, header: '
|
31
|
+
field :import_file, label: 'File', field_type: :attachment
|
32
|
+
field :created_at, header: 'Created At', field_type: :datetime, format: '%B %d, %Y, %H:%M %p'
|
27
33
|
field :completed_at, header: 'Completed At', field_type: :datetime, format: '%B %d, %Y, %H:%M %p'
|
28
|
-
field :associated_model_name, header: '
|
34
|
+
field :associated_model_name, header: 'Table name'
|
29
35
|
field :added_by_name, header: 'Uploaded By'
|
30
36
|
field :status, field_type: :tag, tag_class: STATUS_TAG_COLOR
|
31
37
|
end
|
@@ -38,10 +38,10 @@
|
|
38
38
|
.popup-option
|
39
39
|
span
|
40
40
|
i class="#{custom_action.icon_name}"
|
41
|
-
= custom_action
|
41
|
+
= custom_action_title(custom_action)
|
42
42
|
- when :modal
|
43
43
|
= link_to '', data: { bs_toggle: 'modal', bs_target: "##{custom_action.name.classify}Modal-#{ar_object.id.to_s}" } do
|
44
44
|
.popup-option
|
45
45
|
span
|
46
46
|
i class="#{custom_action.icon_name}"
|
47
|
-
= custom_action
|
47
|
+
= custom_action_title(custom_action)
|
@@ -1,20 +1,19 @@
|
|
1
|
-
.
|
2
|
-
.
|
3
|
-
-
|
4
|
-
.
|
5
|
-
|
6
|
-
|
7
|
-
.
|
8
|
-
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
/ i.fa.fa-angle-down
|
1
|
+
.table-top
|
2
|
+
- if @associated_model.filters.present? && @action.partial.nil?
|
3
|
+
.cm-index-page__filters
|
4
|
+
== render partial: 'cm_admin/main/filters', locals: { filters: @associated_model.filters }
|
5
|
+
p.table-top__total-count = "#{humanized_ar_collection_count(@associated_ar_object.pagy.count, @action.child_records.to_s)}"
|
6
|
+
.table-top__column-action
|
7
|
+
- if @associated_model && @associated_model.available_actions.map(&:name).include?('new') && has_valid_policy(@associated_model.name, 'new')
|
8
|
+
- association = @ar_object.class.reflect_on_all_associations.select{|x| x.name == @associated_model.name.tableize.to_sym }.first
|
9
|
+
- polymorphic_name = (association && association.inverse_of && association.inverse_of.options[:polymorphic]) ? association.inverse_of.name : ''
|
10
|
+
a href="#{CmAdmin::Engine.mount_path}/#{@associated_model.name.tableize}/new?associated_id=#{@ar_object.id}&associated_class=#{@ar_object.class.name.underscore}&polymorphic_name=#{polymorphic_name}&referrer=#{request.path}"
|
11
|
+
button.secondary-btn.column-btn Add
|
12
|
+
/ button.secondary-btn.column-btn data-target="#columnActionModal" data-toggle="modal" type="button"
|
13
|
+
/ span
|
14
|
+
/ i.fa.fa-columns.bolder
|
15
|
+
/ span
|
16
|
+
/ i.fa.fa-angle-down
|
18
17
|
|
19
18
|
.new-admin-table.scrollable
|
20
19
|
table.cm-table
|
@@ -35,17 +34,20 @@
|
|
35
34
|
/ input.cm-checkbox type="checkbox"
|
36
35
|
- @model.available_fields[@action.name.to_sym].each_with_index do |column, index|
|
37
36
|
td class="text-ellipsis"
|
38
|
-
span class="#{column.cm_css_class}"
|
39
|
-
- if index == 0 && @associated_model
|
37
|
+
span class="#{column.field_type.to_s} #{column.cm_css_class} "
|
38
|
+
- if index == 0 && is_show_action_available(@associated_model)
|
40
39
|
a href="#{CmAdmin::Engine.mount_path}/#{@associated_model.name.tableize}/#{ar_object.id}" = show_field_value(ar_object, column)
|
41
40
|
- else
|
42
41
|
= show_field_value(ar_object, column)
|
42
|
+
- if column.field_type == :drawer
|
43
|
+
= render partial: column.drawer_partial, locals: { ar_object: ar_object }
|
44
|
+
|
43
45
|
- if @associated_model
|
44
46
|
== render partial: 'cm_admin/main/actions_dropdown', locals: { cm_model: @associated_model, ar_object: ar_object }
|
45
47
|
|
46
|
-
.cm-pagination
|
47
|
-
|
48
|
-
|
49
|
-
|
48
|
+
.cm-pagination
|
49
|
+
.cm-pagination__lhs Showing #{@associated_ar_object.pagy.from} to #{@associated_ar_object.pagy.to} out of #{@associated_ar_object.pagy.count}
|
50
|
+
.cm-pagination__rhs
|
51
|
+
== render partial: 'cm_admin/main/cm_pagy_nav', locals: { pagy: @associated_ar_object.pagy }
|
50
52
|
|
51
53
|
= render partial: 'cm_admin/main/member_custom_action_modal', locals: { cm_model: @associated_model, ar_collection: @associated_ar_object }
|
@@ -7,7 +7,7 @@
|
|
7
7
|
.modal-dialog
|
8
8
|
.modal-content
|
9
9
|
.modal-header
|
10
|
-
h5.modal-title id="#{custom_action.name.classify}ModalLabel" = custom_action
|
10
|
+
h5.modal-title id="#{custom_action.name.classify}ModalLabel" = custom_action_title(custom_action)
|
11
11
|
button.btn-close aria-label='Close' data-bs-dismiss='modal'
|
12
12
|
.modal-body
|
13
13
|
= render partial: custom_action.partial, locals: { ar_object: ar_object }
|
@@ -1,13 +1,12 @@
|
|
1
|
-
.
|
2
|
-
.table-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
.new-admin-table.scrollable
|
1
|
+
.table-top
|
2
|
+
p.table-top__total-count = "#{humanized_ar_collection_count(@ar_object.pagy.count, @model.ar_model.table_name)}"
|
3
|
+
// .table-top__column-action
|
4
|
+
// button.secondary-btn.column-btn data-bs-target="#columnActionModal" data-bs-toggle="modal"
|
5
|
+
// span
|
6
|
+
// i.fa.fa-columns.bolder
|
7
|
+
// span
|
8
|
+
// i.fa.fa-angle-down
|
9
|
+
.new-admin-table
|
11
10
|
table.cm-table
|
12
11
|
thead.cm-table__header
|
13
12
|
tr.header-row
|
@@ -28,7 +27,7 @@
|
|
28
27
|
- if column.display_if.call(Current.user)
|
29
28
|
td.text-ellipsis
|
30
29
|
span class="#{column.field_type.to_s} #{column.cm_css_class} "
|
31
|
-
- if index == 0 && !([:link, :custom, :attachment, :drawer, :image].include?(column.field_type))
|
30
|
+
- if index == 0 && is_show_action_available(@model) && !([:link, :custom, :attachment, :drawer, :image].include?(column.field_type))
|
32
31
|
= link_to ar_object.send(column.field_name), cm_admin.send("#{ar_object.model_name.singular}_show_path", ar_object.id)
|
33
32
|
- else
|
34
33
|
= show_field_value(ar_object, column)
|
@@ -37,9 +36,9 @@
|
|
37
36
|
- if @model
|
38
37
|
== render partial: 'cm_admin/main/actions_dropdown', locals: { cm_model: @model, ar_object: ar_object }
|
39
38
|
|
40
|
-
.cm-pagination
|
41
|
-
|
42
|
-
|
43
|
-
|
39
|
+
.cm-pagination
|
40
|
+
.cm-pagination__lhs Showing #{@ar_object.pagy.from} to #{@ar_object.pagy.to} out of #{@ar_object.pagy.count}
|
41
|
+
.cm-pagination__rhs
|
42
|
+
== render partial: 'cm_admin/main/cm_pagy_nav', locals: { pagy: @ar_object.pagy }
|
44
43
|
|
45
44
|
= render partial: 'cm_admin/main/member_custom_action_modal', locals: { cm_model: @model, ar_collection: @ar_object }
|
@@ -1,6 +1,5 @@
|
|
1
|
-
.cm-index-page
|
2
|
-
.index-
|
3
|
-
|
4
|
-
== render partial: 'cm_admin/main/associated_table'
|
1
|
+
.cm-index-page.associated-index
|
2
|
+
.cm-index-page__table-container
|
3
|
+
== render partial: 'cm_admin/main/associated_table'
|
5
4
|
|
6
|
-
|
5
|
+
// = column_pop_up(@associated_model)
|
@@ -1,16 +1,15 @@
|
|
1
|
-
.cm-index-page
|
2
|
-
.
|
3
|
-
|
4
|
-
|
5
|
-
-
|
6
|
-
.
|
7
|
-
|
8
|
-
.
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
== render 'cm_admin/main/table'
|
1
|
+
.cm-index-page.cm-page-container
|
2
|
+
.sticky-container.page-top-bar
|
3
|
+
== render 'cm_admin/main/top_navbar'
|
4
|
+
- if @model.filters.present? && @action.partial.nil?
|
5
|
+
.cm-index-page__filters
|
6
|
+
== render partial: 'cm_admin/main/filters', locals: { filters: @model.filters }
|
7
|
+
.cm-index-page__table-container
|
8
|
+
- if @action.partial
|
9
|
+
== render @action.partial
|
10
|
+
- else
|
11
|
+
== render 'cm_admin/main/table'
|
13
12
|
|
14
|
-
|
15
|
-
|
13
|
+
= column_pop_up(@model)
|
14
|
+
= manage_column_pop_up(@model)
|
16
15
|
|
@@ -19,21 +19,21 @@ html
|
|
19
19
|
= render 'layouts/left_sidebar_nav'
|
20
20
|
.panel-area
|
21
21
|
- if defined?(@action) && (@action&.layout_type.to_s == 'cm_association_show' || @action.parent == "show")
|
22
|
-
.show-page.page-container
|
23
|
-
.show-page__tabs.sticky-container
|
22
|
+
.show-page.cm-page-container
|
23
|
+
.show-page__tabs.sticky-container.page-top-bar
|
24
24
|
.cm-tabs-bar
|
25
25
|
== render 'cm_admin/main/top_navbar'
|
26
26
|
== render 'cm_admin/main/tabs'
|
27
27
|
.show-page__inner.scrollable
|
28
28
|
= yield
|
29
29
|
- elsif defined?(@action) && (@action&.layout_type.to_s == 'cm_association_index' || @action.parent == "index")
|
30
|
-
.show-page.page-container
|
31
|
-
.show-page__tabs.sticky-container
|
30
|
+
.show-page.cm-page-container
|
31
|
+
.show-page__tabs.sticky-container.page-top-bar
|
32
32
|
.cm-tabs-bar
|
33
33
|
== render 'cm_admin/main/top_navbar'
|
34
34
|
== render 'cm_admin/main/tabs'
|
35
35
|
- if @associated_model && @associated_model.filters.present?
|
36
|
-
.
|
36
|
+
.filters-bar
|
37
37
|
== render partial: 'cm_admin/main/filters', locals: { filters: @associated_model.filters }
|
38
38
|
= yield
|
39
39
|
- else
|
data/lib/cm_admin/model.rb
CHANGED
@@ -23,7 +23,7 @@ module CmAdmin
|
|
23
23
|
include Pagy::Backend
|
24
24
|
include Models::Blocks
|
25
25
|
include Models::DslMethod
|
26
|
-
attr_accessor :available_actions, :actions_set, :available_fields, :
|
26
|
+
attr_accessor :available_actions, :actions_set, :available_fields, :additional_permitted_fields,
|
27
27
|
:current_action, :params, :filters, :available_tabs, :icon_name
|
28
28
|
attr_reader :name, :ar_model, :is_visible_on_sidebar, :importer
|
29
29
|
|
@@ -33,6 +33,7 @@ module CmAdmin
|
|
33
33
|
@is_visible_on_sidebar = true
|
34
34
|
@icon_name = 'fa fa-th-large'
|
35
35
|
@available_actions ||= []
|
36
|
+
@additional_permitted_fields ||= []
|
36
37
|
@current_action = nil
|
37
38
|
@available_tabs ||= []
|
38
39
|
@available_fields ||= {index: [], show: [], edit: {fields: []}, new: {fields: []}}
|
@@ -94,6 +95,10 @@ module CmAdmin
|
|
94
95
|
@icon_name = name
|
95
96
|
end
|
96
97
|
|
98
|
+
def permit_additional_fields(fields=[])
|
99
|
+
@additional_permitted_fields = fields
|
100
|
+
end
|
101
|
+
|
97
102
|
# Shared between export controller and resource controller
|
98
103
|
def filter_params(params)
|
99
104
|
# OPTIMIZE: Need to check if we can permit the filter_params in a better way
|
@@ -4,7 +4,7 @@ module CmAdmin
|
|
4
4
|
module Models
|
5
5
|
class Action
|
6
6
|
include Actions::Blocks
|
7
|
-
attr_accessor :name, :verb, :layout_type, :layout, :partial, :path, :page_title, :page_description,
|
7
|
+
attr_accessor :name, :display_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
9
|
:display_type, :action_type, :redirection_url, :sort_direction, :sort_column, :icon_name
|
10
10
|
|
@@ -1,8 +1,13 @@
|
|
1
|
+
require_relative 'utils/associations'
|
2
|
+
|
1
3
|
module CmAdmin
|
2
4
|
module Models
|
3
5
|
class Column
|
6
|
+
include Utils::Associations
|
7
|
+
|
4
8
|
attr_accessor :field_name, :field_type, :header, :format, :prefix, :suffix, :exportable, :round, :height, :width,
|
5
|
-
:cm_css_class, :link, :url, :custom_method, :helper_method, :managable, :lockable, :drawer_partial, :tag_class,
|
9
|
+
:cm_css_class, :link, :url, :custom_method, :helper_method, :managable, :lockable, :drawer_partial, :tag_class,
|
10
|
+
:display_if, :association_name, :association_type
|
6
11
|
|
7
12
|
def initialize(field_name, attributes = {})
|
8
13
|
@field_name = field_name
|
@@ -16,11 +21,20 @@ module CmAdmin
|
|
16
21
|
self.height = 50 if self.field_type == :image && self.height.nil?
|
17
22
|
self.width = 50 if self.field_type == :image && self.width.nil?
|
18
23
|
self.display_if = lambda { |arg| return true } if self.display_if.nil?
|
24
|
+
|
25
|
+
validation_for_association
|
19
26
|
end
|
20
27
|
|
21
28
|
#returns a string value as a header (either field_name or value present in header attribute)
|
22
29
|
def format_header
|
23
|
-
self.header.present?
|
30
|
+
header_value = if self.header.present?
|
31
|
+
self.header
|
32
|
+
elsif self.field_type.to_s == 'association'
|
33
|
+
self.association_name
|
34
|
+
else
|
35
|
+
self.field_name
|
36
|
+
end
|
37
|
+
header_value.to_s.titleize.upcase
|
24
38
|
end
|
25
39
|
|
26
40
|
def set_default_values
|
@@ -35,7 +49,6 @@ module CmAdmin
|
|
35
49
|
model.available_fields.find { |i| i.name == search_hash[:name] }
|
36
50
|
end
|
37
51
|
end
|
38
|
-
|
39
52
|
end
|
40
53
|
end
|
41
54
|
end
|
@@ -77,10 +77,23 @@ module CmAdmin
|
|
77
77
|
def column(field_name, options={})
|
78
78
|
@available_fields[@current_action.name.to_sym] ||= []
|
79
79
|
if @available_fields[@current_action.name.to_sym].select{|x| x.lockable}.size > 0 && options[:lockable]
|
80
|
-
raise
|
80
|
+
raise 'Only one column can be locked in a table.'
|
81
81
|
end
|
82
82
|
|
83
|
-
|
83
|
+
duplicate_columns = @available_fields[@current_action.name.to_sym].filter{|x| x.field_name.to_sym == field_name}
|
84
|
+
terminate = false
|
85
|
+
|
86
|
+
if duplicate_columns.size.positive?
|
87
|
+
duplicate_columns.each do |column|
|
88
|
+
if options[:field_type].to_s != 'association'
|
89
|
+
terminate = true
|
90
|
+
elsif options[:field_type].to_s == 'association' && column.association_name.to_s == options[:association_name].to_s
|
91
|
+
terminate = true
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
unless terminate
|
84
97
|
@available_fields[@current_action.name.to_sym] << CmAdmin::Models::Column.new(field_name, options)
|
85
98
|
end
|
86
99
|
end
|
@@ -107,9 +120,9 @@ module CmAdmin
|
|
107
120
|
# end
|
108
121
|
# end
|
109
122
|
# end
|
110
|
-
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)
|
123
|
+
def custom_action(name: nil, display_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)
|
111
124
|
action = CmAdmin::Models::CustomAction.new(
|
112
|
-
name: name, verb: verb, layout: layout, layout_type: layout_type, partial: partial, path: path,
|
125
|
+
name: name, display_name: display_name, verb: verb, layout: layout, layout_type: layout_type, partial: partial, path: path,
|
113
126
|
parent: self.current_action.name, display_type: display_type, display_if: display_if,
|
114
127
|
action_type: :custom, route_type: route_type, icon_name: icon_name, &block)
|
115
128
|
@available_actions << action
|