cm-admin 2.1.2 → 2.1.4
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/.github/workflows/linters.yml +4 -8
- data/Gemfile.lock +14 -18
- data/app/assets/javascripts/cm_admin/exports.js +27 -1
- data/app/assets/stylesheets/cm_admin/dependency/bootstrap/scss/_modal.scss +6 -0
- data/app/models/cm_permission.rb +5 -6
- data/docs/RoleManagement.md +49 -35
- data/lib/cm_admin/models/dsl_method.rb +2 -1
- data/lib/cm_admin/models/filter.rb +49 -51
- data/lib/cm_admin/models/form_field.rb +6 -5
- data/lib/cm_admin/version.rb +1 -1
- data/lib/cm_admin/view_helpers/filter_helper.rb +8 -4
- data/lib/cm_admin/view_helpers/form_field_helper.rb +15 -0
- data/lib/cm_admin/view_helpers.rb +5 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ea557439972b4bf69c93412b81415aed76726933fde6e45599ee6f08bdc9e5be
|
4
|
+
data.tar.gz: f1b704b48795f36a0b8efe342dc4f4de49351112c47a2e6fd6dfbec982fa5bc1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ce7a4d687dcbcd2db7eafaaf77fa45f0d0048b3ba3bfef259c5eb9c7510a569d7c2d9e4876342973d343aca20d295959df33455dbd150e684bea4deb17418f7b
|
7
|
+
data.tar.gz: 4c823776edeb548873d43caf016c402cf102eac48d41b5c9d94e6a7bfd8fbd31ab61dea523215d3d55192312387c0f56465bd5591fb6461f69a771240a81d411
|
@@ -11,12 +11,12 @@ jobs:
|
|
11
11
|
uses: actions/checkout@v4
|
12
12
|
- uses: ruby/setup-ruby@v1
|
13
13
|
with:
|
14
|
-
ruby-version: 3.
|
14
|
+
ruby-version: 3.3
|
15
15
|
- name: rubocop
|
16
|
-
uses: reviewdog/action-rubocop@
|
16
|
+
uses: reviewdog/action-rubocop@v2
|
17
17
|
with:
|
18
|
-
rubocop_version: 1.
|
19
|
-
rubocop_extensions: rubocop-rails:2.
|
18
|
+
rubocop_version: 1.66.1
|
19
|
+
rubocop_extensions: rubocop-rails:2.26.2
|
20
20
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
21
21
|
reporter: github-pr-check # Possible values are github-pr-check, github-pr-review
|
22
22
|
- uses: actions/checkout@v4
|
@@ -25,7 +25,3 @@ jobs:
|
|
25
25
|
with:
|
26
26
|
reporter: github-pr-review # Change reporter.
|
27
27
|
stylelint_input: '**/*.scss'
|
28
|
-
- name: coffeelint
|
29
|
-
uses: reviewdog/action-coffeelint@v1
|
30
|
-
with:
|
31
|
-
reporter: github-pr-review
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
cm-admin (2.1.
|
4
|
+
cm-admin (2.1.4)
|
5
5
|
caxlsx_rails
|
6
6
|
cocoon (~> 1.2.15)
|
7
7
|
csv-importer (~> 0.8.2)
|
@@ -98,7 +98,7 @@ GEM
|
|
98
98
|
cocoon (1.2.15)
|
99
99
|
coercible (1.0.0)
|
100
100
|
descendants_tracker (~> 0.0.1)
|
101
|
-
concurrent-ruby (1.3.
|
101
|
+
concurrent-ruby (1.3.4)
|
102
102
|
crass (1.0.6)
|
103
103
|
csv-importer (0.8.2)
|
104
104
|
virtus
|
@@ -110,7 +110,7 @@ GEM
|
|
110
110
|
globalid (1.2.1)
|
111
111
|
activesupport (>= 6.1)
|
112
112
|
htmlentities (4.3.4)
|
113
|
-
i18n (1.14.
|
113
|
+
i18n (1.14.6)
|
114
114
|
concurrent-ruby (~> 1.0)
|
115
115
|
ice_nine (0.11.2)
|
116
116
|
importmap-rails (2.0.1)
|
@@ -132,7 +132,7 @@ GEM
|
|
132
132
|
method_source (1.1.0)
|
133
133
|
mini_mime (1.1.5)
|
134
134
|
mini_portile2 (2.8.7)
|
135
|
-
minitest (5.
|
135
|
+
minitest (5.25.1)
|
136
136
|
net-imap (0.4.12)
|
137
137
|
date
|
138
138
|
net-protocol
|
@@ -151,13 +151,13 @@ GEM
|
|
151
151
|
nokogiri (1.16.5-x86_64-linux)
|
152
152
|
racc (~> 1.4)
|
153
153
|
pagy (4.11.0)
|
154
|
-
parallel (1.
|
155
|
-
parser (3.3.
|
154
|
+
parallel (1.26.3)
|
155
|
+
parser (3.3.5.0)
|
156
156
|
ast (~> 2.4.1)
|
157
157
|
racc
|
158
158
|
pundit (2.2.0)
|
159
159
|
activesupport (>= 3.0.0)
|
160
|
-
racc (1.8.
|
160
|
+
racc (1.8.1)
|
161
161
|
rack (2.2.9)
|
162
162
|
rack-proxy (0.7.7)
|
163
163
|
rack
|
@@ -194,8 +194,6 @@ GEM
|
|
194
194
|
rainbow (3.1.1)
|
195
195
|
rake (12.3.3)
|
196
196
|
regexp_parser (2.9.2)
|
197
|
-
rexml (3.3.0)
|
198
|
-
strscan
|
199
197
|
rspec (3.10.0)
|
200
198
|
rspec-core (~> 3.10.0)
|
201
199
|
rspec-expectations (~> 3.10.0)
|
@@ -209,26 +207,25 @@ GEM
|
|
209
207
|
diff-lcs (>= 1.2.0, < 2.0)
|
210
208
|
rspec-support (~> 3.10.0)
|
211
209
|
rspec-support (3.10.2)
|
212
|
-
rubocop (1.
|
210
|
+
rubocop (1.66.1)
|
213
211
|
json (~> 2.3)
|
214
212
|
language_server-protocol (>= 3.17.0)
|
215
213
|
parallel (~> 1.10)
|
216
214
|
parser (>= 3.3.0.2)
|
217
215
|
rainbow (>= 2.2.2, < 4.0)
|
218
|
-
regexp_parser (>=
|
219
|
-
|
220
|
-
rubocop-ast (>= 1.31.1, < 2.0)
|
216
|
+
regexp_parser (>= 2.4, < 3.0)
|
217
|
+
rubocop-ast (>= 1.32.2, < 2.0)
|
221
218
|
ruby-progressbar (~> 1.7)
|
222
219
|
unicode-display_width (>= 2.4.0, < 3.0)
|
223
|
-
rubocop-ast (1.
|
220
|
+
rubocop-ast (1.32.3)
|
224
221
|
parser (>= 3.3.1.0)
|
225
222
|
rubocop-performance (1.21.1)
|
226
223
|
rubocop (>= 1.48.1, < 2.0)
|
227
224
|
rubocop-ast (>= 1.31.1, < 2.0)
|
228
|
-
rubocop-rails (2.
|
225
|
+
rubocop-rails (2.26.2)
|
229
226
|
activesupport (>= 4.2.0)
|
230
227
|
rack (>= 1.1)
|
231
|
-
rubocop (>= 1.
|
228
|
+
rubocop (>= 1.52.0, < 2.0)
|
232
229
|
rubocop-ast (>= 1.31.1, < 2.0)
|
233
230
|
ruby-progressbar (1.13.0)
|
234
231
|
rubyzip (2.3.2)
|
@@ -236,7 +233,6 @@ GEM
|
|
236
233
|
slim (4.1.0)
|
237
234
|
temple (>= 0.7.6, < 0.9)
|
238
235
|
tilt (>= 2.0.6, < 2.1)
|
239
|
-
strscan (3.1.0)
|
240
236
|
temple (0.8.2)
|
241
237
|
thor (1.3.1)
|
242
238
|
thread_safe (0.3.6)
|
@@ -244,7 +240,7 @@ GEM
|
|
244
240
|
timeout (0.4.1)
|
245
241
|
tzinfo (2.0.6)
|
246
242
|
concurrent-ruby (~> 1.0)
|
247
|
-
unicode-display_width (2.
|
243
|
+
unicode-display_width (2.6.0)
|
248
244
|
virtus (2.0.0)
|
249
245
|
axiom-types (~> 0.1)
|
250
246
|
coercible (~> 1.0)
|
@@ -4,4 +4,30 @@ $(document).on('click', '.export-to-file-btn', function(e) {
|
|
4
4
|
var action = $('#export-to-file-form').get(0).getAttribute('action')
|
5
5
|
$('#export-to-file-form').get(0).setAttribute('action', action + '?' + query_param);
|
6
6
|
$("#export-to-file-form").submit();
|
7
|
-
});
|
7
|
+
});
|
8
|
+
|
9
|
+
$(document).on(
|
10
|
+
"click",
|
11
|
+
'[data-behaviour="export-select-all"]',
|
12
|
+
function (e) {
|
13
|
+
if($(this).is(':checked')){
|
14
|
+
$('[data-behaviour="export-checkbox"]').prop('checked', true)
|
15
|
+
|
16
|
+
} else {
|
17
|
+
$('[data-behaviour="export-checkbox"]').prop('checked', false)
|
18
|
+
}
|
19
|
+
}
|
20
|
+
);
|
21
|
+
|
22
|
+
$(document).on(
|
23
|
+
"click",
|
24
|
+
'[data-behaviour="export-checkbox"]',
|
25
|
+
function (e) {
|
26
|
+
const container = $(this).closest('.row');
|
27
|
+
if (container.find('[data-behaviour="export-checkbox"]:checked').length == container.find('[data-behaviour="export-checkbox"]').length) {
|
28
|
+
$('[data-behaviour="export-select-all"]').prop('checked', true);
|
29
|
+
} else {
|
30
|
+
$('[data-behaviour="export-select-all"]').prop('checked', false);
|
31
|
+
}
|
32
|
+
}
|
33
|
+
);
|
@@ -151,6 +151,12 @@
|
|
151
151
|
// when there should be a fixed height on `.modal-dialog`.
|
152
152
|
flex: 1 1 auto;
|
153
153
|
padding: var(--#{$prefix}modal-padding);
|
154
|
+
|
155
|
+
.export-select-container {
|
156
|
+
display: flex;
|
157
|
+
gap: 5px;
|
158
|
+
}
|
159
|
+
|
154
160
|
}
|
155
161
|
|
156
162
|
// Footer (for actions)
|
data/app/models/cm_permission.rb
CHANGED
@@ -1,23 +1,22 @@
|
|
1
1
|
class CmPermission < ApplicationRecord
|
2
|
-
|
3
2
|
after_create :create_hidden_permission
|
4
3
|
after_destroy :destroy_hidden_permission
|
5
4
|
|
6
|
-
validates :action_name, presence: true, uniqueness: {scope:
|
5
|
+
validates :action_name, presence: true, uniqueness: { scope: %i[ar_model_name cm_role_id] }
|
7
6
|
|
8
7
|
def create_hidden_permission
|
9
8
|
if action_name == 'new'
|
10
|
-
CmPermission.where(action_name: 'create', ar_model_name
|
9
|
+
CmPermission.where(action_name: 'create', ar_model_name:, cm_role_id:).first_or_create
|
11
10
|
elsif action_name == 'edit'
|
12
|
-
CmPermission.where(action_name: 'update', ar_model_name
|
11
|
+
CmPermission.where(action_name: 'update', ar_model_name:, cm_role_id:).first_or_create
|
13
12
|
end
|
14
13
|
end
|
15
14
|
|
16
15
|
def destroy_hidden_permission
|
17
16
|
if action_name == 'new'
|
18
|
-
CmPermission.where(action_name: 'create', ar_model_name
|
17
|
+
CmPermission.where(action_name: 'create', ar_model_name:, cm_role_id:).first&.destroy
|
19
18
|
elsif action_name == 'edit'
|
20
|
-
CmPermission.where(action_name: 'update', ar_model_name
|
19
|
+
CmPermission.where(action_name: 'update', ar_model_name:, cm_role_id:).first&.destroy
|
21
20
|
end
|
22
21
|
end
|
23
22
|
end
|
data/docs/RoleManagement.md
CHANGED
@@ -1,38 +1,46 @@
|
|
1
|
-
# Role and Permission Management
|
1
|
+
# Role and Permission Management 🎭
|
2
2
|
|
3
3
|
## Overview
|
4
4
|
|
5
|
-
|
5
|
+
Role and permission management is facilitated through CmAdmin, which dynamically creates Pundit policies. This tool allows us to manage permissions via an intuitive interface.
|
6
6
|
|
7
7
|
## Features
|
8
8
|
|
9
|
-
- **Create Role:**
|
10
|
-
- **Manage Permissions:**
|
9
|
+
- **Create Role:** Easily create any role needed for the application.
|
10
|
+
- **Manage Permissions:** View and modify all possible actions for each role, enabling or disabling permissions as necessary.
|
11
11
|
|
12
12
|
## Usage
|
13
13
|
|
14
|
-
|
14
|
+
### Adding Role and Permission Table
|
15
15
|
|
16
|
-
|
17
|
-
|
16
|
+
Run the following command to add the role and permission table:
|
17
|
+
|
18
|
+
```bash
|
19
|
+
rails g cm_admin:install_role
|
18
20
|
```
|
19
21
|
|
20
|
-
|
22
|
+
This Rake task generates a default migration.
|
21
23
|
|
22
|
-
|
24
|
+
**Note:** Ensure that you have the `paper_trail` gem installed before running the command.
|
23
25
|
|
24
|
-
|
26
|
+
### Creating Role Column on User Table
|
27
|
+
|
28
|
+
To create a role column in the user table, execute:
|
29
|
+
|
30
|
+
```bash
|
25
31
|
rails g migration AddCmRoleToUser cm_role:references
|
26
32
|
```
|
27
33
|
|
28
|
-
|
34
|
+
**Note:** The column name must be `cm_role_id`, or the policy will fail.
|
29
35
|
|
30
|
-
|
31
|
-
|
32
|
-
|
36
|
+
### Assigning Roles to Users
|
37
|
+
|
38
|
+
Currently, each user can be assigned only one role. To set the current request parameters:
|
33
39
|
|
34
|
-
In
|
40
|
+
1. In `app/models/current.rb`, add `request_params` as an attribute.
|
41
|
+
2. In `app/controllers/concerns/authentication.rb`, set the request parameters to help CmAdmin identify the action in the Pundit policy.
|
35
42
|
|
43
|
+
```ruby
|
36
44
|
module Authentication
|
37
45
|
extend ActiveSupport::Concern
|
38
46
|
|
@@ -40,39 +48,45 @@ module Authentication
|
|
40
48
|
before_action :check_current_user
|
41
49
|
before_action :set_params
|
42
50
|
end
|
43
|
-
|
51
|
+
|
44
52
|
def set_params
|
45
|
-
if params
|
46
|
-
Current.request_params = params
|
47
|
-
end
|
53
|
+
Current.request_params = params if params
|
48
54
|
end
|
55
|
+
|
56
|
+
# Add other methods here
|
57
|
+
|
49
58
|
end
|
50
59
|
```
|
51
60
|
|
61
|
+
3. Add `belongs_to :cm_role, optional: true` in the `User` model.
|
62
|
+
4. Include `CmRole` in the `config.included_models` section of `config/initializers/zcm_admin.rb`.
|
63
|
+
5. Assign `cm_role_id` to `1` for any user in the `User` Model, and use that user to log in.
|
52
64
|
|
53
|
-
##
|
65
|
+
## Overriding Policies
|
54
66
|
|
55
|
-
By default,
|
67
|
+
By default, roles and policies are enabled for all models in the application. To override a policy, use the following syntax:
|
56
68
|
|
69
|
+
```ruby
|
70
|
+
...
|
71
|
+
cm_admin do
|
72
|
+
actions only: []
|
73
|
+
set_icon "fa fa-user"
|
74
|
+
override_pundit_policy true
|
75
|
+
cm_index do
|
76
|
+
page_title 'User'
|
77
|
+
end
|
78
|
+
end
|
57
79
|
```
|
58
|
-
...
|
59
|
-
cm_admin do
|
60
|
-
actions only: []
|
61
|
-
set_icon "fa fa-user"
|
62
|
-
override_pundit_policy true
|
63
|
-
cm_index do
|
64
|
-
page_title 'User'
|
65
|
-
....
|
66
|
-
```
|
67
|
-
|
68
|
-
and create a policy file on the application for the respective model. eg: `app/policies/cm_admin/user_policy.rb`
|
69
|
-
```
|
70
|
-
class CmAdmin::UserPolicy < ApplicationPolicy
|
71
80
|
|
81
|
+
Then, create a policy file for the respective model, e.g., `app/policies/cm_admin/user_policy.rb`:
|
72
82
|
|
83
|
+
```ruby
|
84
|
+
class CmAdmin::UserPolicy < ApplicationPolicy
|
73
85
|
def index?
|
74
86
|
true
|
75
87
|
end
|
76
|
-
|
88
|
+
# Add other actions here
|
77
89
|
end
|
78
90
|
```
|
91
|
+
|
92
|
+
This structure helps ensure that your application's role and permission management is both flexible and secure.
|
@@ -307,6 +307,7 @@ module CmAdmin
|
|
307
307
|
# @param placeholder [String] the placeholder of filter
|
308
308
|
# @param helper_method [String] the helper method for filter, should be defined in custom_helper.rb file
|
309
309
|
# @param filter_with [Symbol] filter with scope name on model
|
310
|
+
# @param active_by_default [Boolean] make filter active by default
|
310
311
|
# @param collection [Array] the collection of filter, use with single_select or multi_select
|
311
312
|
# @example Creating a filter
|
312
313
|
# filter('name', :search)
|
@@ -371,7 +372,7 @@ module CmAdmin
|
|
371
372
|
# @see file:docs/AddingAlert.md For more information on how to add alerts to your model.
|
372
373
|
#
|
373
374
|
def alert_box(header: nil, body: nil, type: nil, partial: nil, display_if: nil, html_attrs: {})
|
374
|
-
@section_fields << CmAdmin::Models::Alert.new(header, body, type, partial
|
375
|
+
@section_fields << CmAdmin::Models::Alert.new(header, body, type, partial:, display_if:, html_attrs:)
|
375
376
|
end
|
376
377
|
end
|
377
378
|
end
|
@@ -5,7 +5,8 @@ module CmAdmin
|
|
5
5
|
class Filter
|
6
6
|
include Utils::Helpers
|
7
7
|
|
8
|
-
attr_accessor :db_column_name, :filter_type, :placeholder, :collection, :filter_with, :helper_method,
|
8
|
+
attr_accessor :db_column_name, :filter_type, :placeholder, :collection, :filter_with, :helper_method,
|
9
|
+
:display_name, :active_by_default
|
9
10
|
|
10
11
|
VALID_FILTER_TYPES = Set[:date, :multi_select, :range, :search, :single_select].freeze
|
11
12
|
|
@@ -55,13 +56,13 @@ module CmAdmin
|
|
55
56
|
if filter_params
|
56
57
|
filter_params.each do |scope_type, scope_value|
|
57
58
|
filter_method = case scope_type
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
59
|
+
when 'date', 'range'
|
60
|
+
'date_and_range'
|
61
|
+
when 'single_select', 'multi_select'
|
62
|
+
'dropdown'
|
63
|
+
else
|
64
|
+
scope_type
|
65
|
+
end
|
65
66
|
records = send("cm_#{filter_method}_filter", scope_value, records, filters) if scope_value.present?
|
66
67
|
end
|
67
68
|
end
|
@@ -73,43 +74,41 @@ module CmAdmin
|
|
73
74
|
|
74
75
|
table_name = records.table_name
|
75
76
|
filters.select { |x| x if x.filter_type.eql?(:search) }.each do |filter|
|
76
|
-
if filter.filter_with.present?
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
value.map { |val| query_variables << "#{key.to_s.pluralize}.#{val}" }
|
87
|
-
end
|
77
|
+
return records.send(filter.filter_with, scope_value) if filter.filter_with.present?
|
78
|
+
|
79
|
+
query_variables = []
|
80
|
+
filter.db_column_name.each do |col|
|
81
|
+
case col
|
82
|
+
when Symbol
|
83
|
+
query_variables << "#{table_name.pluralize}.#{col}"
|
84
|
+
when Hash
|
85
|
+
col.map do |key, value|
|
86
|
+
value.map { |val| query_variables << "#{key.to_s.pluralize}.#{val}" }
|
88
87
|
end
|
89
88
|
end
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
if filter.db_column_name.map { |x| x.is_a?(Hash) }.include?(true)
|
101
|
-
associations_hash = filter.db_column_name.select { |x| x if x.is_a?(Hash) }.last
|
102
|
-
records = records.left_joins(associations_hash.keys).distinct
|
103
|
-
end
|
89
|
+
end
|
90
|
+
terms = scope_value.downcase.split(/\s+/)
|
91
|
+
terms = terms.map do |e|
|
92
|
+
(e.gsub('*', '%').prepend('%') + '%').gsub(/%+/, '%')
|
93
|
+
end
|
94
|
+
sql = ''
|
95
|
+
query_variables.each.with_index do |column, i|
|
96
|
+
sql.concat("#{column}::TEXT ILIKE ?")
|
97
|
+
sql.concat(' OR ') unless query_variables.size.eql?(i + 1)
|
98
|
+
end
|
104
99
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
}.join(' AND '),
|
109
|
-
*terms.map { |e| [e] * query_variables.size }.flatten
|
110
|
-
)
|
111
|
-
return records
|
100
|
+
if filter.db_column_name.map { |x| x.is_a?(Hash) }.include?(true)
|
101
|
+
associations_hash = filter.db_column_name.select { |x| x if x.is_a?(Hash) }.last
|
102
|
+
records = records.left_joins(associations_hash.keys).distinct
|
112
103
|
end
|
104
|
+
|
105
|
+
records = records.where(
|
106
|
+
terms.map do |_term|
|
107
|
+
sql
|
108
|
+
end.join(' AND '),
|
109
|
+
*terms.map { |e| [e] * query_variables.size }.flatten
|
110
|
+
)
|
111
|
+
return records
|
113
112
|
end
|
114
113
|
end
|
115
114
|
|
@@ -117,18 +116,17 @@ module CmAdmin
|
|
117
116
|
return nil if scope_value.nil?
|
118
117
|
|
119
118
|
scope_value.each do |key, value|
|
120
|
-
filters.select { |x| x if [
|
121
|
-
|
119
|
+
filters.select { |x| x if %i[date range].include?(x.filter_type) && x.db_column_name.to_s == key.to_s }.each do |filter|
|
122
120
|
next unless value.present?
|
123
121
|
|
124
122
|
value = value.split(' to ')
|
125
123
|
from = value[0].presence
|
126
124
|
to = value[1].presence
|
127
|
-
if filter.filter_with.present?
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
125
|
+
records = if filter.filter_with.present?
|
126
|
+
records.send(filter.filter_with, from, to)
|
127
|
+
else
|
128
|
+
records.where(key => from..to)
|
129
|
+
end
|
132
130
|
end
|
133
131
|
end
|
134
132
|
records
|
@@ -138,11 +136,11 @@ module CmAdmin
|
|
138
136
|
return nil if scope_value.nil?
|
139
137
|
|
140
138
|
scope_value.each do |key, value|
|
141
|
-
filters.select { |x| x if [
|
139
|
+
filters.select { |x| x if %i[single_select multi_select].include?(x.filter_type) && x.db_column_name.to_s == key.to_s }.each do |filter|
|
142
140
|
if filter.filter_with.present?
|
143
141
|
records = records.send(filter.filter_with, value) if value.present?
|
144
|
-
|
145
|
-
records = records.where(key => value)
|
142
|
+
elsif value.present?
|
143
|
+
records = records.where(key => value)
|
146
144
|
end
|
147
145
|
end
|
148
146
|
end
|
@@ -11,22 +11,23 @@ module CmAdmin
|
|
11
11
|
VALID_INPUT_TYPES = %i[
|
12
12
|
integer decimal string single_select multi_select date date_time text switch custom_single_select checkbox_group
|
13
13
|
single_file_upload multi_file_upload hidden rich_text check_box radio_button custom_string custom_date
|
14
|
+
radio_button_group
|
14
15
|
].freeze
|
15
16
|
|
16
|
-
def initialize(field_name,
|
17
|
+
def initialize(field_name, _input_type, attributes = {})
|
17
18
|
@field_name = field_name
|
18
19
|
set_default_values
|
19
20
|
attributes.each do |key, value|
|
20
21
|
send("#{key}=", value)
|
21
22
|
end
|
22
23
|
set_default_placeholder
|
23
|
-
self.display_if =
|
24
|
-
raise ArgumentError, "Kindly select a valid input type like #{VALID_INPUT_TYPES.sort.to_sentence(last_word_connector: ', or ')} instead of #{
|
24
|
+
self.display_if = ->(_arg) { true } if display_if.nil?
|
25
|
+
raise ArgumentError, "Kindly select a valid input type like #{VALID_INPUT_TYPES.sort.to_sentence(last_word_connector: ', or ')} instead of #{input_type} for form field #{field_name}" unless VALID_INPUT_TYPES.include?(input_type.to_sym)
|
25
26
|
end
|
26
27
|
|
27
28
|
def set_default_values
|
28
|
-
self.disabled =
|
29
|
-
self.label =
|
29
|
+
self.disabled = ->(_arg) { false } if display_if.nil?
|
30
|
+
self.label = field_name.to_s.titleize
|
30
31
|
self.input_type = :string
|
31
32
|
self.html_attrs = {}
|
32
33
|
self.target = {}
|
data/lib/cm_admin/version.rb
CHANGED
@@ -96,7 +96,8 @@ module CmAdmin
|
|
96
96
|
|
97
97
|
def add_range_filter(filter)
|
98
98
|
value = params.dig(:filters, :range, :"#{filter.db_column_name}")
|
99
|
-
|
99
|
+
is_active = value || filter.active_by_default
|
100
|
+
concat(content_tag(:div, class: "position-relative me-3 #{is_active ? '' : 'hidden'}") do
|
100
101
|
concat filter_chip(value, filter)
|
101
102
|
|
102
103
|
concat(content_tag(:div, class: 'position-absolute mt-2 range-container hidden') do
|
@@ -109,7 +110,8 @@ module CmAdmin
|
|
109
110
|
|
110
111
|
def add_date_filter(filter)
|
111
112
|
value = params.dig(:filters, :date, :"#{filter.db_column_name}")
|
112
|
-
|
113
|
+
is_active = value || filter.active_by_default
|
114
|
+
concat(content_tag(:div, class: "position-relative me-3 #{is_active ? '' : 'hidden'}") do
|
113
115
|
concat filter_chip(value, filter)
|
114
116
|
|
115
117
|
concat(content_tag(:div, class: 'date-filter-wrapper w-100') do
|
@@ -121,6 +123,7 @@ module CmAdmin
|
|
121
123
|
|
122
124
|
def add_single_select_filter(filter)
|
123
125
|
value = params.dig(:filters, :"#{filter.filter_type}", :"#{filter.db_column_name}")
|
126
|
+
is_active = value || filter.active_by_default
|
124
127
|
select_options = if filter.helper_method
|
125
128
|
send(filter.helper_method)
|
126
129
|
elsif filter.collection
|
@@ -128,7 +131,7 @@ module CmAdmin
|
|
128
131
|
else
|
129
132
|
[]
|
130
133
|
end
|
131
|
-
concat(content_tag(:div, class: "position-relative me-3 #{
|
134
|
+
concat(content_tag(:div, class: "position-relative me-3 #{is_active ? '' : 'hidden'}") do
|
132
135
|
selected_value_text = if value && select_options[0].class == Array
|
133
136
|
select_options.map { |collection| collection[0] if collection[1].to_s.eql?(value) }.compact.join(', ')
|
134
137
|
else
|
@@ -164,6 +167,7 @@ module CmAdmin
|
|
164
167
|
|
165
168
|
def add_multi_select_filter(filter)
|
166
169
|
value = params.dig(:filters, :"#{filter.filter_type}", :"#{filter.db_column_name}")
|
170
|
+
is_active = value || filter.active_by_default
|
167
171
|
select_options = if filter.helper_method
|
168
172
|
send(filter.helper_method)
|
169
173
|
elsif filter.collection
|
@@ -180,7 +184,7 @@ module CmAdmin
|
|
180
184
|
value_mapped_text = value
|
181
185
|
end
|
182
186
|
|
183
|
-
concat(content_tag(:div, class: "position-relative me-3 #{
|
187
|
+
concat(content_tag(:div, class: "position-relative me-3 #{is_active ? '' : 'hidden'}") do
|
184
188
|
concat filter_chip(value_mapped_text, filter)
|
185
189
|
|
186
190
|
concat(content_tag(:div, class: 'position-absolute mt-2 dropdown-popup hidden') do
|
@@ -277,6 +277,14 @@ module CmAdmin
|
|
277
277
|
end
|
278
278
|
end
|
279
279
|
|
280
|
+
def cm_radio_button_group_field(form_obj, cm_field, value, _required_class, _target_action, _ajax_url)
|
281
|
+
content_tag :div, class: 'btn-group', role: 'group' do
|
282
|
+
value.each do |key, val|
|
283
|
+
format_radio_button_group_option(val || key, key, cm_field, form_obj)
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
280
288
|
def cm_hidden_field(form_obj, cm_field, value, _required_class, _target_action, _ajax_url)
|
281
289
|
form_obj.hidden_field cm_field.field_name,
|
282
290
|
merge_wrapper_options(
|
@@ -319,6 +327,13 @@ module CmAdmin
|
|
319
327
|
end
|
320
328
|
end
|
321
329
|
|
330
|
+
def format_radio_button_group_option(val, key, cm_field, form_obj)
|
331
|
+
id = "#{cm_field.field_name}_#{val}"
|
332
|
+
concat form_obj.radio_button cm_field.field_name, val, merge_wrapper_options({ id:, class: 'btn-check' },
|
333
|
+
cm_field.html_attrs)
|
334
|
+
concat content_tag(:label, key, class: 'btn btn-outline-dark btn-sm', for: id)
|
335
|
+
end
|
336
|
+
|
322
337
|
def merge_wrapper_options(options, html_attrs)
|
323
338
|
if html_attrs
|
324
339
|
options.merge(html_attrs) do |key, oldval, newval|
|
@@ -50,6 +50,10 @@ module CmAdmin
|
|
50
50
|
def pop_up_body(klass, _required_filters)
|
51
51
|
tag.div class: 'modal-body' do
|
52
52
|
form_tag cm_admin.send('export_to_file_path'), id: 'export-to-file-form', style: 'width: 100%;', class: 'cm-admin-csv-export-form' do
|
53
|
+
concat(content_tag(:div, class: 'column export-select-container') do
|
54
|
+
concat check_box_tag('select_all', '1', false, data: { behaviour: 'export-select-all' })
|
55
|
+
concat 'All'
|
56
|
+
end)
|
53
57
|
concat hidden_field_tag 'class_name', klass.name.to_s, id: 'export-to-file-klass'
|
54
58
|
concat checkbox_row(klass)
|
55
59
|
concat tag.hr
|
@@ -69,7 +73,7 @@ module CmAdmin
|
|
69
73
|
|
70
74
|
def create_checkbox(column)
|
71
75
|
tag.div class: 'col-md-4' do
|
72
|
-
concat check_box_tag
|
76
|
+
concat check_box_tag('columns[]', column.field_name, false, id: column.field_name.to_s.gsub('/', '-'), data: { behaviour: 'export-checkbox' })
|
73
77
|
concat " #{column.header.to_s.gsub('/', '_').humanize}"
|
74
78
|
end
|
75
79
|
end
|
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: 2.1.
|
4
|
+
version: 2.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael
|
@@ -14,7 +14,7 @@ authors:
|
|
14
14
|
autorequire:
|
15
15
|
bindir: exe
|
16
16
|
cert_chain: []
|
17
|
-
date: 2024-09-
|
17
|
+
date: 2024-09-24 00:00:00.000000000 Z
|
18
18
|
dependencies:
|
19
19
|
- !ruby/object:Gem::Dependency
|
20
20
|
name: caxlsx_rails
|