cm-admin 4.4.0 → 4.4.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2f2cbd6a0eb88a1b484b7dd22581707ba8ace583b855e7d8fddc70a7f707c982
4
- data.tar.gz: 3e16b540f328160794ee09d1f2851bd9b017265a033806c56f76902eb8060cb1
3
+ metadata.gz: 36b4a98af23560b5a7dcd5e05df922d4ea1dcf3d3eaf1a4d9dda5186f7c75458
4
+ data.tar.gz: 22cec496c00f00ddaab1f4ba8bf42d0a30d7d11c892e81d2b5eb1e97103d1e4c
5
5
  SHA512:
6
- metadata.gz: f75af6089fa15c0d7e3e9d914a3aa2c2c2248b9ae45bc833238677de6c82761717beca49515f0ade78890e9495f1c714e80e9de4c9abb116b6c62f576fba8cc8
7
- data.tar.gz: d22b094320cd0a841675b222c20529dc6ab6eb0e136afd73a31ac0bd877714c01cd135a2ac0dd68ee47dbbb0a997877a2f3eb5a9db18e6ff7d7984ac25c4a768
6
+ metadata.gz: 0a06402c208970fdcb9b4a5477cc42f8dca00904e006bd06f8a7fcb283e61fbd90a30f64c48cde6445bb983d03445ff401a97c7bd4b60fe8f3213be6c417fe74
7
+ data.tar.gz: d8dab6bffd90f7f22d86669c1f3f1bbfc12516b6c9008e5fad7dc93bc6d6a0b4326edc27a7159575b2f3144a64a2f6a32e8dde5c42524254abbe9e906f24baa8
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cm-admin (4.4.0)
4
+ cm-admin (4.4.6)
5
5
  caxlsx_rails
6
6
  cocoon (~> 1.2.15)
7
7
  csv (>= 3.3.0)
@@ -158,13 +158,13 @@ GEM
158
158
  timeout
159
159
  net-smtp (0.5.0)
160
160
  net-protocol
161
- nio4r (2.7.4)
162
- nokogiri (1.16.7)
161
+ nio4r (2.7.3)
162
+ nokogiri (1.18.1)
163
163
  mini_portile2 (~> 2.8.2)
164
164
  racc (~> 1.4)
165
- nokogiri (1.16.7-arm64-darwin)
165
+ nokogiri (1.18.1-arm64-darwin)
166
166
  racc (~> 1.4)
167
- nokogiri (1.16.7-x86_64-linux)
167
+ nokogiri (1.18.1-x86_64-linux-gnu)
168
168
  racc (~> 1.4)
169
169
  pagy (4.11.0)
170
170
  parallel (1.26.3)
@@ -68,26 +68,45 @@
68
68
  margin-left: 8px;
69
69
  vertical-align: text-bottom;
70
70
  }
71
+
71
72
  &:hover {
72
73
  color: $white;
73
- background: rgba(255, 255, 255, 0.1);
74
+ @include white-rgba($opacity: 0.3);
74
75
  }
75
- }
76
- .menu-sub-list {
77
- .menu-sub-item {
78
- @include font($size: $t4-text, $color: $ink-lightest-clr);
79
- padding: 8px 8px 8px 45px;
80
- transition: all 0.2s linear;
81
- &:hover {
82
- color: $white;
83
- background: rgba(255, 255, 255, 0.1);
76
+
77
+ .menu-sub-list {
78
+ .menu-sub-item {
79
+ @include font($size: $t4-text, $color: $ink-lightest-clr);
80
+ padding: 8px 8px 8px 45px;
81
+ transition: all 0.2s linear;
82
+ &:hover {
83
+ color: $white;
84
+ @include white-rgba($opacity: 0.1);
85
+ }
84
86
  }
85
87
  }
86
88
  }
89
+
90
+ .submenu-item{
91
+ padding: 8px 24px 8px 46px;
92
+ }
93
+
87
94
  .menu-link {
88
95
  color: inherit;
89
96
  text-decoration: none;
90
97
  }
98
+
99
+ .selected-item {
100
+ @include white-rgba($opacity: 0.1);
101
+ font-weight: bold;
102
+ }
103
+
104
+
105
+
106
+ .sidebar-dropdown-svg {
107
+ padding-left: 8px;
108
+ height: 12px;
109
+ }
91
110
  }
92
111
 
93
112
  &__tabs-wrapper {
@@ -20,7 +20,7 @@
20
20
  }
21
21
 
22
22
  .cm-admin .btn-secondary {
23
- @extend .btn, .btn-outline-secondary, .btn-sm, .btn-icon-spacing;
23
+ @extend .btn, .btn-outline-dark, .btn-sm, .btn-icon-spacing;
24
24
  }
25
25
 
26
26
  .cm-admin .btn-ghost {
@@ -18,3 +18,7 @@
18
18
  transition: all .2s linear;
19
19
  }
20
20
 
21
+ @mixin white-rgba($opacity: 0.3) {
22
+ background: rgba(255, 255, 255, $opacity);
23
+ }
24
+
@@ -402,7 +402,7 @@ module CmAdmin
402
402
  next if page.to_i > (total_count.to_i / per_page.to_f).ceil
403
403
 
404
404
  _, records = pagy(final_data.send(column), items: per_page.to_i)
405
- filtered_result.data[column] = render_to_string partial: 'cm_admin/main/kanban_card', locals: { ar_collection: records }
405
+ filtered_result.data[column] = render_to_string partial: 'cm_admin/main/kanban_card', locals: { ar_collection: records, column_name: column }
406
406
  end
407
407
  filtered_result
408
408
  end
@@ -20,6 +20,30 @@ module CmAdmin
20
20
  end
21
21
  end
22
22
 
23
+ def cm_recognize_path(path_helper)
24
+ http_methods = [:get, :post, :patch, :delete, :put, :options]
25
+ cm_admin_path = cm_admin.send(path_helper)
26
+ recognized_path = nil
27
+ http_methods.each do |method|
28
+ begin
29
+ recognized_path = Rails.application.routes.recognize_path(cm_admin_path, method: method)
30
+ return recognized_path if recognized_path.present?
31
+ rescue ActionController::RoutingError
32
+ next
33
+ end
34
+ end
35
+ end
36
+
37
+ def validate_cm_path_policy(path_helper)
38
+ recognized_path= cm_recognize_path(path_helper)
39
+
40
+ model_name = recognized_path[:controller].split('/').last.singularize.classify
41
+ action_name = action(recognized_path[:action])
42
+ @policy_model = CmAdmin::Model.find_by(name: model_name)
43
+ policy([:cm_admin, @policy_model&.name&.constantize]).send("#{action_name}?")
44
+ end
45
+
46
+
23
47
  def action(action_name)
24
48
  case action_name.to_sym
25
49
  when :update
@@ -68,7 +68,9 @@ module Exportable
68
68
  column = CmAdmin::Models::Column.find_by(model, :index, { name: column_name.to_sym })
69
69
  record_hash[column.field_name] = if column.field_type == :custom
70
70
  send(column.helper_method, record, column.field_name).to_s
71
- else
71
+ elsif column.field_type == :enum
72
+ record.send(column.field_name).to_s.titleize
73
+ else
72
74
  record.send(column.field_name).to_s
73
75
  end
74
76
  end
@@ -22,6 +22,5 @@
22
22
  - elsif params[:view_type] == 'table' || @current_action.view_type == :table
23
23
  == render 'cm_admin/main/table'
24
24
 
25
- = column_pop_up(@model)
26
25
  = manage_column_pop_up(@model)
27
26
 
@@ -1,6 +1,6 @@
1
1
  module CmAdmin
2
2
  class Configuration
3
- attr_accessor :layout, :included_models, :cm_admin_models, :enable_tracking, :project_name
3
+ attr_accessor :layout, :included_models, :cm_admin_models, :enable_tracking, :project_name, :sidebar
4
4
 
5
5
  def initialize
6
6
  @layout = 'admin'
@@ -8,6 +8,7 @@ module CmAdmin
8
8
  @cm_admin_models = []
9
9
  @enable_tracking = false
10
10
  @project_name = ''
11
+ @sidebar = []
11
12
  end
12
13
  end
13
14
  end
@@ -1,3 +1,3 @@
1
1
  module CmAdmin
2
- VERSION = '4.4.0'
2
+ VERSION = '4.4.6'
3
3
  end
@@ -162,13 +162,13 @@ module CmAdmin
162
162
  def show_attachment_value(ar_object, field)
163
163
  if ar_object.send(field.field_name).attached?
164
164
  if has_one_image_attached?(ar_object, field)
165
- content_tag :a, href: ar_object.send(field.field_name).url do
165
+ content_tag :a, href: ar_object.send(field.field_name).url, target: '_blank' do
166
166
  ar_object.send(field.field_name).filename.to_s
167
167
  end
168
168
  elsif has_many_image_attached?(ar_object, field)
169
169
  ar_object.send(field.field_name).map do |asset|
170
170
  content_tag(:div) do
171
- content_tag :a, href: asset.url do
171
+ content_tag :a, href: asset.url, target: '_blank' do
172
172
  asset.filename.to_s
173
173
  end
174
174
  end
@@ -1,13 +1,26 @@
1
1
  require 'pagy'
2
+
2
3
  module CmAdmin
3
4
  module ViewHelpers
4
- module NavigationHelper
5
+ module NavigationHelper # rubocop:disable Metrics/ModuleLength
5
6
  include Pagy::Frontend
7
+
6
8
  def navigation_links(navigation_type)
7
- CmAdmin.config.cm_admin_models.map do |model|
9
+ if CmAdmin.config.sidebar.present?
10
+ custom_navigation_links(navigation_type, CmAdmin.config.sidebar)
11
+ else
12
+ default_navigation_links(navigation_type)
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def default_navigation_links(navigation_type)
19
+ CmAdmin.config.cm_admin_models.map do |model| # rubocop:disable Metrics/BlockLength
8
20
  next unless model.is_visible_on_sidebar
9
21
 
10
- path = CmAdmin::Engine.mount_path + '/' + model.name.underscore.pluralize
22
+ path = "#{CmAdmin::Engine.mount_path}/#{model.name.underscore.pluralize}"
23
+
11
24
  if policy([:cm_admin, model.name.classify.constantize]).index?
12
25
  if navigation_type == 'sidebar'
13
26
  content_tag(:a, href: path) do
@@ -15,7 +28,7 @@ module CmAdmin
15
28
  content_tag(:span, class: 'menu-icon') do
16
29
  concat tag.i class: model.icon_name.to_s
17
30
  end +
18
- model.model_name.titleize.pluralize
31
+ model.model_name.titleize.pluralize
19
32
  end
20
33
  end
21
34
  elsif navigation_type == 'quick_links'
@@ -35,6 +48,98 @@ module CmAdmin
35
48
  end
36
49
  end.join.html_safe
37
50
  end
51
+
52
+ # Custom Navbar Code
53
+ def custom_navigation_links(navigation_type, sidebar = []) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
54
+ sidebar.filter_map do |main_item|
55
+ @policy_model = nil
56
+ next unless should_display_item?(main_item)
57
+
58
+ path = main_item[:children].present? ? collapse_path(main_item) : { href: get_route(main_item[:path]) }
59
+ recognized_path = main_item[:path].present? && main_item[:path].start_with?('cm_') ? cm_recognize_path(main_item[:path]) : {}
60
+ current_path = get_route(main_item[:path]).present? && request.params.dig(:tab_id) == (recognized_path[:controller].to_s + '#' + recognized_path[:action].to_s).gsub("/", "_").gsub("#", "_") ? 'selected-item' : ''
61
+
62
+ if navigation_type == 'sidebar'
63
+ content_tag(:a, path) do
64
+ content_tag(:div, class: "menu-item #{current_path}") do
65
+ content_tag(:span, class: 'menu-icon') { tag.i(class: main_item[:icon_name] || @policy_model&.icon_name || 'fa fa-th-large') } +
66
+ content_tag(:span, main_item[:display_name] || @policy_model&.formatted_name.pluralize) + content_tag(:span) +
67
+ (main_item[:children].present? ? tag.i(class: 'sidebar-dropdown-svg fa fa-chevron-down') : ''.html_safe)
68
+ end +
69
+ generate_sub_menu(main_item)
70
+ end
71
+ elsif navigation_type == 'quick_links'
72
+ (main_item[:children] || [main_item]).filter_map do |item|
73
+ next unless should_display_item?(item)
74
+
75
+ content_tag(:a, href: get_route(item[:path]), class: 'visible') do
76
+ content_tag(:div, class: 'result-item') do
77
+ content_tag(:span) { tag.i(class: item[:icon_name] || @policy_model&.icon_name || 'fa fa-th-large') } +
78
+ content_tag(:span, item[:display_name] || @policy_model&.formatted_name.pluralize)
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end.join.html_safe
84
+ end
85
+
86
+ # Helper Methods
87
+ def should_display_item?(sidebar_item)
88
+ return true if sidebar_item[:children]&.any? { |sub_item| should_display_item?(sub_item) }
89
+ return validate_cm_path_policy(sidebar_item[:path]) if sidebar_item[:path]&.start_with?('cm_') && (sidebar_item[:display_if].nil? || sidebar_item[:display_if]&.call(current_user))
90
+ return true if sidebar_item[:display_if]&.call(current_user) || sidebar_item[:display_if].nil? && sidebar_item[:children].nil?
91
+
92
+ false
93
+ end
94
+
95
+ def collapse_path(main_item)
96
+ {
97
+ 'data-bs-toggle' => 'collapse',
98
+ 'href' => "##{(main_item[:display_name] || @policy_model&.display_name).parameterize}Collapse",
99
+ 'role' => 'button',
100
+ 'aria-expanded' => 'true',
101
+ 'aria-controls' => "#{(main_item[:display_name] || @policy_model&.display_name).parameterize}Collapse",
102
+ 'data-cm-nav-id' => "##{(main_item[:display_name] || @policy_model&.display_name).parameterize}Collapse"
103
+ }
104
+ end
105
+
106
+ def generate_sub_menu(sidebar_item)
107
+ return ''.html_safe unless sidebar_item[:children].present?
108
+
109
+ sub_menu = sidebar_item[:children].filter_map { |sub_item| sub_menu_link(sub_item) }.join.html_safe
110
+ sub_menu_state_class = sidebar_item[:children].any? { |sub_item|
111
+ recognized_path = sub_item[:path].present? && sub_item[:path].start_with?('cm_') ? cm_recognize_path(sub_item[:path]) : {}
112
+ get_route(sub_item[:path]).present? && request.params.dig(:tab_id) == ((recognized_path[:controller].to_s + '#' + recognized_path[:action].to_s).gsub("/", "_").gsub("#", "_")) } ? 'show' : 'collapse'
113
+ content_tag(:div, id: "#{(sidebar_item[:display_name] || @policy_model&.formatted_name.pluralize).parameterize}Collapse", "data-cm-nav-id": "#{(sidebar_item[:display_name] || @policy_model&.formatted_name.pluralize).parameterize}Collapse", class: sub_menu_state_class) do
114
+ sub_menu
115
+ end
116
+ end
117
+
118
+ def sub_menu_link(sub_item)
119
+ return unless should_display_item?(sub_item)
120
+
121
+ recognized_path = sub_item[:path].present? && sub_item[:path].start_with?('cm_') ? cm_recognize_path(sub_item[:path]) : {}
122
+ current_path = get_route(sub_item[:path]).present? && request.params.dig(:tab_id) == ((recognized_path[:controller].to_s + '#' + recognized_path[:action].to_s).gsub("/", "_").gsub("#", "_")) ? 'selected-item' : ''
123
+
124
+ content_tag(:a, href: get_route(sub_item[:path])) do
125
+ content_tag(:div, class: "menu-item submenu-item #{current_path}") do
126
+ content_tag(:span, class: 'menu-icon') { tag.i(class: sub_item[:icon_name] || @policy_model&.icon_name || 'fa fa-th-large') } +
127
+ content_tag(:span, sub_item[:display_name] || @policy_model&.formatted_name.pluralize)
128
+ end
129
+ end
130
+ end
131
+
132
+ def get_route(path)
133
+ return '' unless path.present?
134
+
135
+ recognized_path = path.start_with?('cm_') ? cm_recognize_path(path) : {}
136
+
137
+
138
+ return cm_admin.send(path.to_sym) + "?tab_id=#{(recognized_path[:controller].to_s + '#' + recognized_path[:action].to_s).gsub("/", "_").gsub("#", "_")}" if path.start_with?('cm_')
139
+ return send(path.to_sym) if Rails.application.routes.url_helpers.method_defined?(path.to_sym)
140
+
141
+ path
142
+ end
38
143
  end
39
144
  end
40
145
  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: 4.4.0
4
+ version: 4.4.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael
@@ -11,10 +11,9 @@ authors:
11
11
  - Pranav
12
12
  - Mahaveer
13
13
  - Austin
14
- autorequire:
15
14
  bindir: exe
16
15
  cert_chain: []
17
- date: 2024-12-24 00:00:00.000000000 Z
16
+ date: 2025-01-14 00:00:00.000000000 Z
18
17
  dependencies:
19
18
  - !ruby/object:Gem::Dependency
20
19
  name: caxlsx_rails
@@ -508,7 +507,6 @@ metadata:
508
507
  homepage_uri: https://github.com/commutatus/cm-admin
509
508
  source_code_uri: https://github.com/commutatus/cm-admin
510
509
  github_repo: ssh://github.com/commutatus/cm-admin
511
- post_install_message:
512
510
  rdoc_options: []
513
511
  require_paths:
514
512
  - lib
@@ -523,8 +521,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
523
521
  - !ruby/object:Gem::Version
524
522
  version: '0'
525
523
  requirements: []
526
- rubygems_version: 3.5.22
527
- signing_key:
524
+ rubygems_version: 3.6.2
528
525
  specification_version: 4
529
526
  summary: CmAdmin is a robust gem designed to assist in creating admin panels for Rails
530
527
  applications