cm-admin 1.1.7 → 1.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.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