cm-admin 1.1.7 → 1.1.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.vscode/settings.json +3 -0
- data/Gemfile.lock +1 -1
- data/app/assets/javascripts/cm_admin/scaffolds.js +1 -1
- data/app/assets/stylesheets/cm_admin/base/navbar.scss +13 -39
- data/app/assets/stylesheets/cm_admin/base/quicksearch.scss +3 -4
- data/app/assets/stylesheets/cm_admin/base/show.scss +4 -15
- data/app/assets/stylesheets/cm_admin/base/table.scss +2 -14
- data/app/assets/stylesheets/cm_admin/cm_admin.css.scss +1 -0
- data/app/assets/stylesheets/cm_admin/components/_buttons.scss +29 -135
- data/app/assets/stylesheets/cm_admin/dependency/bootstrap.min.css +4 -5
- data/app/assets/stylesheets/cm_admin/dependency/jquery-jgrowl.min.css +1 -0
- data/app/assets/stylesheets/cm_admin/helpers/_variable.scss +31 -30
- data/app/assets/stylesheets/cm_admin/pages/import_page.scss +3 -10
- data/app/controllers/cm_admin/resource_controller.rb +13 -9
- data/app/views/cm_admin/main/_actions_dropdown.html.slim +1 -3
- data/app/views/cm_admin/main/_associated_table.html.slim +1 -1
- data/app/views/cm_admin/main/_nested_fields.html.slim +2 -1
- data/app/views/cm_admin/main/_nested_table_form.html.slim +1 -1
- data/app/views/cm_admin/main/_tabs.html.slim +1 -1
- data/app/views/cm_admin/main/_top_navbar.html.slim +11 -17
- data/app/views/cm_admin/main/history.html.slim +3 -4
- data/app/views/cm_admin/main/import_form.html.slim +2 -2
- data/app/views/cm_admin/main/new.html.slim +1 -1
- data/app/views/cm_admin/main/show.html.slim +3 -4
- data/app/views/layouts/_cm_flash_message.html.slim +3 -3
- data/app/views/layouts/_quick_links.html.slim +2 -2
- data/app/views/layouts/cm_admin.html.slim +10 -12
- data/lib/cm_admin/models/filter.rb +55 -29
- data/lib/cm_admin/models/form_field.rb +18 -3
- data/lib/cm_admin/models/utils/helpers.rb +14 -0
- data/lib/cm_admin/version.rb +1 -1
- data/lib/cm_admin/view_helpers/filter_helper.rb +1 -1
- data/lib/cm_admin/view_helpers/form_field_helper.rb +16 -17
- data/lib/cm_admin/view_helpers/form_helper.rb +2 -1
- data/lib/cm_admin/view_helpers/manage_column_popup_helper.rb +2 -2
- data/lib/cm_admin/view_helpers/page_info_helper.rb +4 -4
- data/lib/cm_admin/view_helpers.rb +2 -1
- metadata +5 -2
@@ -0,0 +1 @@
|
|
1
|
+
.jGrowl{z-index:9999;color:#fff;font-size:12px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;position:fixed}.jGrowl.top-left{left:0;top:0}.jGrowl.top-right{right:0;top:0}.jGrowl.bottom-left{left:0;bottom:0}.jGrowl.bottom-right{right:0;bottom:0}.jGrowl.center{top:0;width:50%;left:25%}.jGrowl.center .jGrowl-closer,.jGrowl.center .jGrowl-notification{margin-left:auto;margin-right:auto}.jGrowl-notification{background-color:#000;opacity:.9;zoom:1;width:250px;padding:10px;margin:10px;text-align:left;display:none;border-radius:5px;min-height:40px}.jGrowl-notification .ui-state-highlight,.jGrowl-notification .ui-widget-content .ui-state-highlight,.jGrowl-notification .ui-widget-header .ui-state-highlight{border:1px solid #000;background:#000;color:#fff}.jGrowl-notification .jGrowl-header{font-weight:700;font-size:.85em}.jGrowl-notification .jGrowl-close{background-color:transparent;color:inherit;border:none;z-index:99;float:right;font-weight:700;font-size:1em;cursor:pointer}.jGrowl-closer{background-color:#000;opacity:.9;zoom:1;width:250px;padding:10px;margin:10px;text-align:left;display:none;border-radius:5px;padding-top:4px;padding-bottom:4px;cursor:pointer;font-size:.9em;font-weight:700;text-align:center}.jGrowl-closer .ui-state-highlight,.jGrowl-closer .ui-widget-content .ui-state-highlight,.jGrowl-closer .ui-widget-header .ui-state-highlight{border:1px solid #000;background:#000;color:#fff}@media print{.jGrowl{display:none}}
|
@@ -1,54 +1,55 @@
|
|
1
1
|
/* ==== Color Variables ==== */
|
2
2
|
|
3
3
|
/* Brand Color */
|
4
|
-
$brand-color: #
|
4
|
+
$brand-color: #6554e0;
|
5
|
+
$brand-hover-color: #e6e4fa;
|
5
6
|
|
6
7
|
/* Semantic Color */
|
7
|
-
$informative-clr: #
|
8
|
-
$error-clr: #
|
9
|
-
$warning-clr: #
|
10
|
-
$positive-clr: #
|
11
|
-
$disabled-clr: #
|
8
|
+
$informative-clr: #2f80ed;
|
9
|
+
$error-clr: #f83636;
|
10
|
+
$warning-clr: #ffc845;
|
11
|
+
$positive-clr: #30c39e;
|
12
|
+
$disabled-clr: #9ca7ae;
|
12
13
|
|
13
14
|
/* Blue Colors */
|
14
|
-
$blue-regular-clr: #
|
15
|
-
$blue-light-clr: #
|
16
|
-
$blue-lightest-clr: #
|
15
|
+
$blue-regular-clr: #2f80ed;
|
16
|
+
$blue-light-clr: #cde1fb;
|
17
|
+
$blue-lightest-clr: #eef5fe;
|
17
18
|
|
18
19
|
/* Red Colors */
|
19
|
-
$red-regular-clr: #
|
20
|
-
$red-light-clr: #
|
21
|
-
$red-lightest-clr: #
|
20
|
+
$red-regular-clr: #f83636;
|
21
|
+
$red-light-clr: #fdcfcf;
|
22
|
+
$red-lightest-clr: #feefef;
|
22
23
|
|
23
24
|
/* Yellow Colors */
|
24
|
-
$yellow-regular-clr: #
|
25
|
-
$yellow-light-clr: #
|
26
|
-
$yellow-lightest-clr: #
|
25
|
+
$yellow-regular-clr: #ffc845;
|
26
|
+
$yellow-light-clr: #ffefc7;
|
27
|
+
$yellow-lightest-clr: #fff8e9;
|
27
28
|
|
28
29
|
/* Green Colors */
|
29
|
-
$green-regular-clr: #
|
30
|
-
$green-light-clr: #
|
31
|
-
$green-lightest-clr: #
|
30
|
+
$green-regular-clr: #30c39e;
|
31
|
+
$green-light-clr: #c1ede2;
|
32
|
+
$green-lightest-clr: #eefaf7;
|
32
33
|
|
33
34
|
/* Grey Colors */
|
34
|
-
$grey-regular-clr: #
|
35
|
-
$grey-light-clr: #
|
36
|
-
$grey-lighter-clr: #
|
37
|
-
$grey-lightest-clr: #
|
35
|
+
$grey-regular-clr: #c7ced5;
|
36
|
+
$grey-light-clr: #d9dee3;
|
37
|
+
$grey-lighter-clr: #f3f4f6;
|
38
|
+
$grey-lightest-clr: #f8f9fa;
|
38
39
|
$grey-dark-clr: #828282;
|
39
40
|
|
40
41
|
/* Ink Colors */
|
41
|
-
$ink-regular-clr: #
|
42
|
-
$ink-light-clr: #
|
43
|
-
$ink-lighter-clr: #
|
44
|
-
$ink-lightest-clr: #
|
42
|
+
$ink-regular-clr: #1d2129;
|
43
|
+
$ink-light-clr: #3b4352;
|
44
|
+
$ink-lighter-clr: #6b7586;
|
45
|
+
$ink-lightest-clr: #9ca7ae;
|
45
46
|
|
46
47
|
/* Text Colors */
|
47
|
-
$primary-text-clr: #
|
48
|
-
$subdued-text-clr: #
|
48
|
+
$primary-text-clr: #1d2129;
|
49
|
+
$subdued-text-clr: #d9dee3;
|
49
50
|
|
50
51
|
/* Common Colors */
|
51
|
-
$white: #
|
52
|
+
$white: #ffffff;
|
52
53
|
$black: #000000;
|
53
54
|
|
54
55
|
// Gradient Colors
|
@@ -56,7 +57,7 @@ $gradient-one: linear-gradient(270deg, $grey-lighter-clr 81.75%, rgba(243, 244,
|
|
56
57
|
$cta-hover-gradient: linear-gradient(0deg, rgba(0, 0, 0, 0.24), rgba(0, 0, 0, 0.24)), $brand-color;
|
57
58
|
|
58
59
|
/* Typography */
|
59
|
-
$primary-font:
|
60
|
+
$primary-font: "Open Sans", sans-serif;
|
60
61
|
$font-size: (
|
61
62
|
24: 24px,
|
62
63
|
18: 18px,
|
@@ -25,7 +25,7 @@
|
|
25
25
|
line-height: 22px;
|
26
26
|
margin-bottom: 0;
|
27
27
|
}
|
28
|
-
}
|
28
|
+
}
|
29
29
|
&__body {
|
30
30
|
padding: 16px 24px;
|
31
31
|
.body-title {
|
@@ -63,9 +63,6 @@
|
|
63
63
|
|
64
64
|
.actions-wrapper {
|
65
65
|
margin-top: 32px;
|
66
|
-
button {
|
67
|
-
padding: 5px 10px;
|
68
|
-
}
|
69
66
|
}
|
70
67
|
|
71
68
|
//form UI
|
@@ -90,7 +87,7 @@
|
|
90
87
|
margin-bottom: 16px;
|
91
88
|
text-transform: uppercase;
|
92
89
|
}
|
93
|
-
.steps-wrapper
|
90
|
+
.steps-wrapper {
|
94
91
|
.steps-title {
|
95
92
|
@include font($size: size(16), $weight: bold);
|
96
93
|
font-family: $primary-font;
|
@@ -116,10 +113,6 @@
|
|
116
113
|
}
|
117
114
|
}
|
118
115
|
}
|
119
|
-
.import-btn {
|
120
|
-
padding: 5px 10px;
|
121
|
-
}
|
122
116
|
}
|
123
|
-
|
124
117
|
}
|
125
|
-
}
|
118
|
+
}
|
@@ -137,15 +137,19 @@ module CmAdmin
|
|
137
137
|
data = @action.parent == "index" ? @ar_object.data : @ar_object
|
138
138
|
format.html { render @action.partial }
|
139
139
|
else
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
140
|
+
begin
|
141
|
+
response_object = @action.code_block.call(@response_object)
|
142
|
+
if response_object.class == Hash
|
143
|
+
format.json { render json: response_object }
|
144
|
+
elsif response_object.errors.empty?
|
145
|
+
redirect_url = @model.current_action.redirection_url || @action.redirection_url || request.referrer || "/cm_admin/#{@model.ar_model.table_name}/#{@response_object.id}"
|
146
|
+
format.html { redirect_to redirect_url, notice: "#{@action.name.titleize} is successful" }
|
147
|
+
else
|
148
|
+
error_messages = response_object.errors.full_messages.map{|error_message| "<li>#{error_message}</li>"}.join
|
149
|
+
format.html { redirect_to request.referrer, alert: "<b>#{@action.name.titleize} is unsuccessful</b><br /><ul>#{error_messages}</ul>" }
|
150
|
+
end
|
151
|
+
rescue => exception
|
152
|
+
format.html { redirect_to request.referrer, alert: "<b>#{@action.name.titleize} is unsuccessful</b><br /><p>#{exception.message}</p>" }
|
149
153
|
end
|
150
154
|
end
|
151
155
|
end
|
@@ -5,11 +5,9 @@
|
|
5
5
|
- if custom_actions.any? || edit_action.present? || destroy_action.present?
|
6
6
|
td.row-action-cell
|
7
7
|
.row-action-tool
|
8
|
-
button.
|
8
|
+
button.btn-ghost.dropdown-toggle
|
9
9
|
span
|
10
10
|
i.fa.fa-bars.bolder
|
11
|
-
span
|
12
|
-
i.fa.fa-angle-down
|
13
11
|
.popup-card.table-export-popup.hidden
|
14
12
|
- if edit_action.present?
|
15
13
|
= link_to cm_admin.send("#{current_model.name.underscore}_edit_path", ar_object.id) do
|
@@ -8,7 +8,7 @@
|
|
8
8
|
- association = @ar_object.class.reflect_on_all_associations.select{|x| x.name == @associated_model.name.tableize.to_sym }.first
|
9
9
|
- polymorphic_name = (association && association.inverse_of && association.inverse_of.options[:polymorphic]) ? association.inverse_of.name : ''
|
10
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.
|
11
|
+
button.btn-secondary Add
|
12
12
|
/ button.secondary-btn.column-btn data-target="#columnActionModal" data-toggle="modal" type="button"
|
13
13
|
/ span
|
14
14
|
/ i.fa.fa-columns.bolder
|
@@ -15,7 +15,8 @@
|
|
15
15
|
| Chapter 1
|
16
16
|
.field-remove-action
|
17
17
|
- if @reflections.select {|x| x if x.name == assoc_name}.first.macro == :has_many
|
18
|
-
|
18
|
+
.accordion-delete-btn
|
19
|
+
= link_to_remove_association "", f, class: 'fa fa-trash btn-ghost'
|
19
20
|
div.accordion-collapse.collapse.show[aria-labelledby="headingOne" id="#{assoc_name}-#{f.object.id}"]
|
20
21
|
.accordion-body
|
21
22
|
- fields.each do |field|
|
@@ -7,4 +7,4 @@
|
|
7
7
|
= render partial: '/cm_admin/main/nested_fields', locals: { f: record, assoc_name: assoc_name, section: section }
|
8
8
|
- if @reflections.select {|x| x if x.name == assoc_name}.first.macro == :has_many
|
9
9
|
.links
|
10
|
-
= link_to_add_association "+ Add #{assoc_name.to_s.titleize}", f, table_name, partial: '/cm_admin/main/nested_fields', render_options: {locals: { assoc_name: assoc_name, section: section }}, class: 'd-inline-block secondary
|
10
|
+
= link_to_add_association "+ Add #{assoc_name.to_s.titleize}", f, table_name, partial: '/cm_admin/main/nested_fields', render_options: {locals: { assoc_name: assoc_name, section: section }}, class: 'd-inline-block btn-secondary mt-2'
|
@@ -1,4 +1,4 @@
|
|
1
|
-
ul.
|
1
|
+
ul.tabs
|
2
2
|
- @model.available_tabs.each do |nav_item|
|
3
3
|
- if nav_item.display_if.call(@ar_object)
|
4
4
|
- if nav_item.custom_action.empty? || (nav_item.custom_action.present? && policy([:cm_admin, @model.name.classify.constantize]).send(:"#{nav_item.custom_action}?"))
|
@@ -1,33 +1,27 @@
|
|
1
|
-
.
|
2
|
-
.
|
1
|
+
.entity-header
|
2
|
+
.entity-header__info
|
3
3
|
- if cm_admin.method_defined?(:"#{@model.name.underscore}_index_path") && (@model.current_action.name == 'show' || @model.current_action.layout_type.present?)
|
4
|
-
.
|
5
|
-
.
|
6
|
-
|
7
|
-
.
|
8
|
-
|
9
|
-
p.title-sub-text = action_description
|
10
|
-
.cm-navbar__rhs
|
4
|
+
.breadcrumb
|
5
|
+
= link_to "#{@model.name.titleize.pluralize} /", cm_admin.send(:"#{@model.name.underscore}_index_path"), class: 'text-reset'
|
6
|
+
h4 = action_title
|
7
|
+
p.mb-0.text-body-secondary = action_description
|
8
|
+
.entity-header__actions
|
11
9
|
- if @model.current_action.name == 'index'
|
12
10
|
- if has_valid_policy(@model.name, :exportable)
|
13
11
|
.export-container
|
14
12
|
.dropdown
|
15
|
-
button.secondary-
|
16
|
-
span
|
13
|
+
button.btn-secondary.dropdown-toggle data-bs-toggle='dropdown'
|
17
14
|
i.fa.fa-arrow-down
|
18
|
-
span
|
19
15
|
| Export
|
20
|
-
span
|
21
|
-
i.fa.fa-angle-down
|
22
16
|
ul.dropdown-menu.export-popup
|
23
17
|
li
|
24
18
|
.popup-option.pointer data-bs-toggle='modal' data-bs-target='#exportmodal'
|
25
19
|
span Export
|
26
20
|
- if @model.importer && has_valid_policy(@model.name, :importable)
|
27
|
-
= link_to 'Import', cm_admin.send(:"#{@model.name.underscore}_import_path"), class: 'primary
|
21
|
+
= link_to 'Import', cm_admin.send(:"#{@model.name.underscore}_import_path"), class: 'btn-primary ml-2'
|
28
22
|
- new_action = @model.available_actions.select{|act| act if act.action_type.eql?(:default) && act.name.eql?('new')}
|
29
23
|
- if new_action.any? && policy([:cm_admin, @model.name.classify.constantize]).new?
|
30
|
-
= link_to 'Add', cm_admin.send(:"#{@model.name.underscore}_new_path"), class: 'primary
|
24
|
+
= link_to 'Add', cm_admin.send(:"#{@model.name.underscore}_new_path"), class: 'btn-primary ml-2'
|
31
25
|
- @model.available_actions.select{|act| act if act.route_type == 'collection'}.each do |custom_action|
|
32
26
|
= custom_action_items(custom_action, 'index')
|
33
27
|
- elsif @model.current_action.name == 'show'
|
@@ -36,4 +30,4 @@
|
|
36
30
|
|
37
31
|
- edit_action = @model.available_actions.select{|act| act if act.action_type.eql?(:default) && act.name.eql?('edit')}
|
38
32
|
- if edit_action.any? && policy([:cm_admin, @model.name.classify.constantize]).edit?
|
39
|
-
= link_to "Edit #{@model.name.titleize.pluralize}", cm_admin.send(:"#{@model.name.underscore}_edit_path", @ar_object), class: 'primary
|
33
|
+
= link_to "Edit #{@model.name.titleize.pluralize}", cm_admin.send(:"#{@model.name.underscore}_edit_path", @ar_object), class: 'btn-primary ml-2'
|
@@ -1,8 +1,7 @@
|
|
1
1
|
.show-page.cm-page-container
|
2
|
-
.show-
|
3
|
-
|
4
|
-
|
5
|
-
== render 'cm_admin/main/tabs'
|
2
|
+
.show-page__header.sticky-container.page-top-bar
|
3
|
+
== render 'cm_admin/main/top_navbar'
|
4
|
+
== render 'cm_admin/main/tabs'
|
6
5
|
.show-page__inner.scrollable
|
7
6
|
.history-box
|
8
7
|
- @ar_object.action_trails.each do |at|
|
@@ -12,7 +12,7 @@
|
|
12
12
|
p.success-msg Your file has been uploaded and it will be processed soon.
|
13
13
|
/ p.success-msg-info An email will be sent once the process is completed. If there are any problems with the import, we'll let you know through an email.
|
14
14
|
.actions-wrapper
|
15
|
-
a.secondary
|
15
|
+
a.btn-secondary href="#{cm_admin.send(:"#{@model.name.underscore}_import_path")}" Import new data
|
16
16
|
/ button.cta-btn.ml-2 Back to Page_Name
|
17
17
|
- else
|
18
18
|
= simple_form_for(FileImport.new, url: "/admin/#{@model.ar_model.table_name}/import", method: :post, html: { class: "csv-import-form" }) do |f|
|
@@ -32,4 +32,4 @@
|
|
32
32
|
li Add your data on the file without changing the format
|
33
33
|
li Save the file as a csv
|
34
34
|
li Upload the file in the field above
|
35
|
-
= f.button :submit, class: "
|
35
|
+
= f.button :submit, class: "btn-cta", value: 'Import data'
|
@@ -1,8 +1,7 @@
|
|
1
1
|
.show-page.cm-page-container
|
2
|
-
.show-
|
3
|
-
|
4
|
-
|
5
|
-
== render 'cm_admin/main/tabs'
|
2
|
+
.show-page__header.sticky-container.page-top-bar
|
3
|
+
== render 'cm_admin/main/top_navbar'
|
4
|
+
== render 'cm_admin/main/tabs'
|
6
5
|
.show-page__inner.scrollable
|
7
6
|
- if @action.partial
|
8
7
|
== render @action.partial
|
@@ -1,9 +1,9 @@
|
|
1
1
|
- if flash[:notice].present?
|
2
2
|
javascript:
|
3
|
-
$.jGrowl("#{flash[:notice]}", {theme: 'notice'})
|
3
|
+
$.jGrowl("#{flash[:notice]}", { theme: 'notice' })
|
4
4
|
- elsif flash[:success].present?
|
5
5
|
javascript:
|
6
|
-
$.jGrowl("#{flash[:success]}", {theme: 'success'})
|
6
|
+
$.jGrowl("#{flash[:success]}", { theme: 'success' })
|
7
7
|
- elsif flash[:alert].present?
|
8
8
|
javascript:
|
9
|
-
$.jGrowl("#{flash[:alert].html_safe}", {theme: 'error'})
|
9
|
+
$.jGrowl("#{flash[:alert].html_safe}", { theme: 'error' })
|
@@ -25,22 +25,20 @@ html
|
|
25
25
|
.panel-area
|
26
26
|
- if defined?(@action) && (@action&.layout_type.to_s == 'cm_association_show' || @action.parent == "show")
|
27
27
|
.show-page.cm-page-container
|
28
|
-
.show-
|
29
|
-
|
30
|
-
|
31
|
-
== render 'cm_admin/main/tabs'
|
28
|
+
.show-page__header.sticky-container.page-top-bar
|
29
|
+
== render 'cm_admin/main/top_navbar'
|
30
|
+
== render 'cm_admin/main/tabs'
|
32
31
|
.show-page__inner.scrollable
|
33
32
|
= yield
|
34
33
|
- elsif defined?(@action) && (@action&.layout_type.to_s == 'cm_association_index' || @action.parent == "index")
|
35
34
|
.show-page.cm-page-container
|
36
|
-
.show-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
.filters
|
43
|
-
== render partial: 'cm_admin/main/filters', locals: { filters: @associated_model.filters }
|
35
|
+
.show-page__header.sticky-container.page-top-bar
|
36
|
+
== render 'cm_admin/main/top_navbar'
|
37
|
+
- if @ar_object.model_name
|
38
|
+
== render 'cm_admin/main/tabs'
|
39
|
+
- if @associated_model && @associated_model.filters.present?
|
40
|
+
.filters-bar
|
41
|
+
== render partial: 'cm_admin/main/filters', locals: { filters: @associated_model.filters }
|
44
42
|
= yield
|
45
43
|
- else
|
46
44
|
= yield
|
@@ -1,6 +1,10 @@
|
|
1
|
+
require_relative 'utils/helpers'
|
2
|
+
|
1
3
|
module CmAdmin
|
2
4
|
module Models
|
3
5
|
class Filter
|
6
|
+
include Utils::Helpers
|
7
|
+
|
4
8
|
attr_accessor :db_column_name, :filter_type, :placeholder, :collection
|
5
9
|
|
6
10
|
VALID_FILTER_TYPES = Set[:date, :multi_select, :range, :search, :single_select].freeze
|
@@ -8,37 +12,55 @@ module CmAdmin
|
|
8
12
|
def initialize(db_column_name:, filter_type:, options: {})
|
9
13
|
raise TypeError, "Can't have array of multiple columns for #{filter_type} filter" if db_column_name.is_a?(Array) && db_column_name.size > 1 && !filter_type.to_sym.eql?(:search)
|
10
14
|
raise ArgumentError, "Kindly select a valid filter type like #{VALID_FILTER_TYPES.sort.to_sentence(last_word_connector: ', or ')} instead of #{filter_type} for column #{db_column_name}" unless VALID_FILTER_TYPES.include?(filter_type.to_sym)
|
15
|
+
|
11
16
|
@db_column_name, @filter_type = structure_data(db_column_name, filter_type)
|
17
|
+
set_default_values
|
12
18
|
options.each do |key, value|
|
13
|
-
|
19
|
+
send("#{key}=", value)
|
14
20
|
end
|
15
21
|
end
|
16
22
|
|
17
23
|
def structure_data(db_column_name, filter_type)
|
18
24
|
filter_type = filter_type.is_a?(Array) ? filter_type[0].to_sym : filter_type.to_sym
|
19
25
|
|
20
|
-
case filter_type
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
+
db_column_name = case filter_type
|
27
|
+
when :search
|
28
|
+
([] << db_column_name).flatten.map { |x| x.instance_of?(Hash) ? x : x.to_sym }
|
29
|
+
else
|
30
|
+
db_column_name.is_a?(Array) ? db_column_name[0].to_sym : db_column_name.to_sym
|
31
|
+
end
|
26
32
|
[db_column_name, filter_type]
|
27
33
|
end
|
28
34
|
|
35
|
+
# Set default placeholder for the filter.
|
36
|
+
# Date and range filter will not have any placeholder.
|
37
|
+
# Else condition is added for fallback.
|
38
|
+
def set_default_values
|
39
|
+
placeholder = case filter_type
|
40
|
+
when :search
|
41
|
+
'Search'
|
42
|
+
when :single_select, :multi_select
|
43
|
+
"Select/search #{humanized_field_value(db_column_name)}"
|
44
|
+
else
|
45
|
+
"Enter #{humanized_field_value(db_column_name)}"
|
46
|
+
end
|
47
|
+
self.placeholder = placeholder
|
48
|
+
end
|
49
|
+
|
29
50
|
# Methods to filter the records based on the filter type.
|
30
51
|
class << self
|
31
52
|
def filtered_data(filter_params, records, filters)
|
32
53
|
if filter_params
|
33
54
|
filter_params.each do |scope_type, scope_value|
|
34
|
-
scope_name =
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
55
|
+
scope_name = case scope_type
|
56
|
+
when 'date', 'range'
|
57
|
+
'date_and_range'
|
58
|
+
when 'single_select', 'multi_select'
|
59
|
+
'dropdown'
|
60
|
+
else
|
61
|
+
scope_type
|
62
|
+
end
|
63
|
+
records = send("cm_#{scope_name}_filter", scope_value, records, filters) if scope_value.present?
|
42
64
|
end
|
43
65
|
end
|
44
66
|
records
|
@@ -46,15 +68,17 @@ module CmAdmin
|
|
46
68
|
|
47
69
|
def cm_search_filter(scope_value, records, filters)
|
48
70
|
return nil if scope_value.blank?
|
71
|
+
|
49
72
|
table_name = records.table_name
|
50
|
-
filters.select{|x| x if x.filter_type.eql?(:search)}.each do |filter|
|
73
|
+
filters.select { |x| x if x.filter_type.eql?(:search) }.each do |filter|
|
51
74
|
query_variables = []
|
52
75
|
filter.db_column_name.each do |col|
|
53
|
-
|
76
|
+
case col
|
77
|
+
when Symbol
|
54
78
|
query_variables << "#{table_name.pluralize}.#{col}"
|
55
|
-
|
79
|
+
when Hash
|
56
80
|
col.map do |key, value|
|
57
|
-
value.map {|val| query_variables << "#{key.to_s.pluralize}.#{val}" }
|
81
|
+
value.map { |val| query_variables << "#{key.to_s.pluralize}.#{val}" }
|
58
82
|
end
|
59
83
|
end
|
60
84
|
end
|
@@ -62,14 +86,14 @@ module CmAdmin
|
|
62
86
|
terms = terms.map { |e|
|
63
87
|
(e.gsub('*', '%').prepend('%') + '%').gsub(/%+/, '%')
|
64
88
|
}
|
65
|
-
sql =
|
89
|
+
sql = ''
|
66
90
|
query_variables.each.with_index do |column, i|
|
67
91
|
sql.concat("#{column} ILIKE ?")
|
68
|
-
sql.concat(' OR ') unless query_variables.size.eql?(i+1)
|
92
|
+
sql.concat(' OR ') unless query_variables.size.eql?(i + 1)
|
69
93
|
end
|
70
94
|
|
71
|
-
if filter.db_column_name.map{|x| x.is_a?(Hash)}.include?(true)
|
72
|
-
associations_hash = filter.db_column_name.select{|x| x if x.is_a?(Hash)}.last
|
95
|
+
if filter.db_column_name.map { |x| x.is_a?(Hash) }.include?(true)
|
96
|
+
associations_hash = filter.db_column_name.select { |x| x if x.is_a?(Hash) }.last
|
73
97
|
records = records.left_joins(associations_hash.keys).distinct
|
74
98
|
end
|
75
99
|
|
@@ -85,19 +109,21 @@ module CmAdmin
|
|
85
109
|
|
86
110
|
def cm_date_and_range_filter(scope_value, records, filters)
|
87
111
|
return nil if scope_value.nil?
|
112
|
+
|
88
113
|
scope_value.each do |key, value|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
114
|
+
next unless value.present?
|
115
|
+
|
116
|
+
value = value.split(' to ')
|
117
|
+
from = value[0].presence
|
118
|
+
to = value[1].presence
|
119
|
+
records = records.where(key => from..to)
|
95
120
|
end
|
96
121
|
records
|
97
122
|
end
|
98
123
|
|
99
124
|
def cm_dropdown_filter(scope_value, records, filters)
|
100
125
|
return nil if scope_value.nil?
|
126
|
+
|
101
127
|
scope_value.each do |key, value|
|
102
128
|
records = records.where(key => value) if value.present?
|
103
129
|
end
|
@@ -1,6 +1,10 @@
|
|
1
|
+
require_relative 'utils/helpers'
|
2
|
+
|
1
3
|
module CmAdmin
|
2
4
|
module Models
|
3
5
|
class FormField
|
6
|
+
include Utils::Helpers
|
7
|
+
|
4
8
|
attr_accessor :field_name, :label, :header, :input_type, :collection, :disabled, :helper_method,
|
5
9
|
:placeholder, :display_if, :html_attr, :target
|
6
10
|
|
@@ -13,9 +17,10 @@ module CmAdmin
|
|
13
17
|
@field_name = field_name
|
14
18
|
set_default_values
|
15
19
|
attributes.each do |key, value|
|
16
|
-
|
20
|
+
send("#{key}=", value)
|
17
21
|
end
|
18
|
-
|
22
|
+
set_default_placeholder
|
23
|
+
self.display_if = lambda { |arg| return true } if display_if.nil?
|
19
24
|
raise ArgumentError, "Kindly select a valid input type like #{VALID_INPUT_TYPES.sort.to_sentence(last_word_connector: ', or ')} instead of #{self.input_type} for form field #{field_name}" unless VALID_INPUT_TYPES.include?(self.input_type.to_sym)
|
20
25
|
end
|
21
26
|
|
@@ -23,10 +28,20 @@ module CmAdmin
|
|
23
28
|
self.disabled = false
|
24
29
|
self.label = self.field_name.to_s.titleize
|
25
30
|
self.input_type = :string
|
26
|
-
self.placeholder = "Enter #{self.field_name.to_s.downcase.gsub('_', ' ')}"
|
27
31
|
self.html_attr = {}
|
28
32
|
self.target = {}
|
29
33
|
end
|
34
|
+
|
35
|
+
def set_default_placeholder
|
36
|
+
return unless placeholder.nil?
|
37
|
+
|
38
|
+
self.placeholder = case input_type&.to_sym
|
39
|
+
when :single_select, :multi_select, :date, :date_time
|
40
|
+
"Select #{humanized_field_value(field_name)}"
|
41
|
+
else
|
42
|
+
"Enter #{humanized_field_value(field_name)}"
|
43
|
+
end
|
44
|
+
end
|
30
45
|
end
|
31
46
|
end
|
32
47
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module CmAdmin
|
2
|
+
module Models
|
3
|
+
module Utils
|
4
|
+
module Helpers
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
# Returns the humanized value of the field.
|
8
|
+
def humanized_field_value(name, capitalize: false)
|
9
|
+
name.to_s.humanize(capitalize: capitalize)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/cm_admin/version.rb
CHANGED