cm-admin 0.9.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +82 -0
  3. data/.github/ISSUE_TEMPLATE/config.yml +5 -0
  4. data/.github/ISSUE_TEMPLATE/feature_request.md +21 -0
  5. data/Gemfile.lock +96 -9
  6. data/app/assets/config/cm_admin_manifest.js +1 -0
  7. data/app/assets/javascripts/cm_admin/application.js +5 -0
  8. data/app/{javascript/packs → assets/javascripts}/cm_admin/exports.js +0 -0
  9. data/app/{javascript/packs → assets/javascripts}/cm_admin/filters.js +20 -31
  10. data/app/{javascript/packs → assets/javascripts}/cm_admin/form_validation.js +0 -0
  11. data/app/{javascript/packs → assets/javascripts}/cm_admin/quick_search.js +16 -3
  12. data/app/assets/javascripts/cm_admin/scaffolds.js +44 -0
  13. data/app/assets/stylesheets/cm_admin/base/form.scss +115 -40
  14. data/app/assets/stylesheets/cm_admin/base/scaffold.scss +2 -0
  15. data/app/assets/stylesheets/cm_admin/components/_input.scss +12 -0
  16. data/app/controllers/cm_admin/resource_controller.rb +10 -7
  17. data/app/helpers/cm_admin/application_helper.rb +0 -3
  18. data/app/javascript/packs/cm_admin/application.js +4 -4
  19. data/app/javascript/packs/cm_admin/scaffolds.js +81 -0
  20. data/app/views/cm_admin/main/_nested_fields.html.slim +26 -9
  21. data/app/views/cm_admin/main/_nested_table_form.html.slim +9 -10
  22. data/app/views/cm_admin/main/_tabs.html.slim +1 -1
  23. data/app/views/layouts/cm_admin.html.slim +9 -4
  24. data/app/views/layouts/static.html.slim +3 -2
  25. data/bin/importmap +15 -0
  26. data/bin/webpack +8 -8
  27. data/bin/webpack-dev-server +9 -9
  28. data/cm_admin.gemspec +3 -0
  29. data/config/importmap.rb +12 -0
  30. data/config/webpack/development.js +1 -1
  31. data/config/webpack/environment.js +1 -1
  32. data/config/webpack/production.js +1 -1
  33. data/config/webpacker.yml +2 -2
  34. data/lib/cm_admin/configuration.rb +5 -2
  35. data/lib/cm_admin/engine.rb +36 -15
  36. data/lib/cm_admin/models/filter.rb +1 -1
  37. data/lib/cm_admin/models/form_field.rb +8 -2
  38. data/lib/cm_admin/version.rb +1 -1
  39. data/lib/cm_admin/version_manager.rb +21 -0
  40. data/lib/cm_admin/view_helpers/form_field_helper.rb +183 -35
  41. data/lib/cm_admin/view_helpers/page_info_helper.rb +4 -0
  42. data/lib/cm_admin.rb +7 -2
  43. data/lib/generators/cm_admin/templates/actiontext.scss +0 -1
  44. data/lib/tasks/webpack_install.rake +15 -13
  45. data/package-lock.json +42 -55
  46. data/tmp/cache/webpacker/last-compilation-digest-development +1 -1
  47. data/yarn.lock +6708 -6916
  48. metadata +43 -6
@@ -106,12 +106,14 @@ module CmAdmin
106
106
  data = @action.parent == "index" ? @ar_object.data : @ar_object
107
107
  format.html { render @action.partial }
108
108
  else
109
- ar_object = @action.code_block.call(@ar_object)
110
- if ar_object.errors.empty?
111
- redirect_url = @model.current_action.redirection_url || @action.redirection_url || request.referrer || "/cm_admin/#{@model.ar_model.table_name}/#{@ar_object.id}"
109
+ response_object = @action.code_block.call(@response_object)
110
+ if response_object.class == Hash
111
+ format.json { render json: response_object }
112
+ elsif response_object.errors.empty?
113
+ redirect_url = @model.current_action.redirection_url || @action.redirection_url || request.referrer || "/cm_admin/#{@model.ar_model.table_name}/#{@response_object.id}"
112
114
  format.html { redirect_to redirect_url, notice: "#{@action.name.titleize} is successful" }
113
115
  else
114
- error_messages = ar_object.errors.full_messages.map{|error_message| "<li>#{error_message}</li>"}.join
116
+ error_messages = response_object.errors.full_messages.map{|error_message| "<li>#{error_message}</li>"}.join
115
117
  format.html { redirect_to request.referrer, alert: "<b>#{@action.name.titleize} is unsuccessful</b><br /><ul>#{error_messages}</ul>" }
116
118
  end
117
119
  end
@@ -193,9 +195,11 @@ module CmAdmin
193
195
  end
194
196
 
195
197
  def resource_params(params)
196
- columns = @model.ar_model.column_names
198
+ columns = @model.ar_model.columns_hash.map {|key, ar_adapter|
199
+ ar_adapter.sql_type_metadata.sql_type.ends_with?('[]') ? Hash[ar_adapter.name, []] : ar_adapter.name.to_sym
200
+ }
197
201
  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)
202
+ permittable_fields = @model.additional_permitted_fields + columns.reject { |i| CmAdmin::REJECTABLE_FIELDS.include?(i) }
199
203
  permittable_fields += @model.ar_model.name.constantize.reflect_on_all_associations.map {|x|
200
204
  next if x.options[:polymorphic]
201
205
  if x.class.name.include?('HasOne')
@@ -214,7 +218,6 @@ module CmAdmin
214
218
  }
215
219
  permittable_fields += nested_fields
216
220
  @model.ar_model.columns.map { |col| permittable_fields << col.name.split('_cents') if col.name.include?('_cents') }
217
-
218
221
  params.require(@model.name.underscore.to_sym).permit(*permittable_fields)
219
222
  end
220
223
 
@@ -1,8 +1,5 @@
1
- require "webpacker/helper"
2
-
3
1
  module CmAdmin
4
2
  module ApplicationHelper
5
- include ::Webpacker::Helper
6
3
 
7
4
  def current_webpacker_instance
8
5
  CmAdmin.webpacker
@@ -9,10 +9,10 @@ require('flatpickr')
9
9
  require("jgrowl")
10
10
  require("trix")
11
11
  require('./scaffolds.js')
12
- require('./form_validation.js')
13
- require('./quick_search.js')
14
- require('./filters.js')
15
- require('./exports.js')
12
+ require('/app/assets/javascripts/cm_admin/form_validation.js')
13
+ require('/app/assets/javascripts/cm_admin/quick_search.js')
14
+ require('/app/assets/javascripts/cm_admin/filters.js')
15
+ require('/app/assets/javascripts/cm_admin/exports.js')
16
16
 
17
17
  import jQuery from 'jquery'
18
18
  import LocalTime from "local-time"
@@ -74,3 +74,84 @@ $(document).on('click', '.drawer-close', function(e) {
74
74
  $('.cm-drawer').addClass('hidden');
75
75
  }, 300);
76
76
  });
77
+
78
+ $(document).on('change', '[data-field-type="linked-field"]', function(e) {
79
+ e.stopPropagation();
80
+ params = {}
81
+ params[$(this).data('field-name')] = $(this).val()
82
+ request_url = $(this).data('target-url') + '?' + $.param(params);
83
+ console.log(request_url)
84
+ $.ajax(request_url, {
85
+ type: 'GET',
86
+ success: function(data) {
87
+ apply_response_to_field(data)
88
+ },
89
+ error: function(jqxhr, textStatus, errorThrown) {
90
+ alert('Something went wrong. Please try again later.\n' + errorThrown);
91
+ }
92
+ });
93
+ });
94
+
95
+ function apply_response_to_field(response) {
96
+ $.each(response['fields'], function(key, value) {
97
+ switch(value['target_type']) {
98
+ case 'select':
99
+ update_options_in_select(value['target_value'])
100
+ break;
101
+ case 'input':
102
+ update_options_input_value(value['target_value'])
103
+ break;
104
+ case 'toggle_visibility':
105
+ toggle_field_visibility(value['target_value'])
106
+ }
107
+ })
108
+ }
109
+
110
+ function update_options_input_value(field_obj) {
111
+ input_tag = $('#' + field_obj['table'] + '_' + field_obj['field_name'])
112
+ input_tag.val(field_obj['field_value'])
113
+ }
114
+
115
+ function update_options_in_select(field_obj) {
116
+ select_tag = $('#' + field_obj['table'] + '_' + field_obj['field_name'])
117
+ select_tag.empty();
118
+ $.each(field_obj['field_value'], function(key, value) {
119
+ select_tag.append($("<option></option>")
120
+ .attr("value", value[1]).text(value[0]));
121
+ });
122
+ }
123
+
124
+ function toggle_field_visibility(field_obj) {
125
+ element = $('#' + field_obj['table'] + '_' + field_obj['field_name'])
126
+ element.closest('.input-wrapper').toggleClass('hidden')
127
+ }
128
+
129
+ $(document).on('cocoon:after-insert', '.nested-field-wrapper', function(e) {
130
+ e.stopPropagation();
131
+ replaceAccordionTitle($(this))
132
+ });
133
+
134
+ $(document).on('cocoon:after-remove', '.nested-field-wrapper', function(e) {
135
+ e.stopPropagation();
136
+ replaceAccordionTitle($(this))
137
+ });
138
+
139
+ $(document).ready( function () {
140
+ $('.nested-field-wrapper').each(function() {
141
+ replaceAccordionTitle($(this))
142
+ })
143
+ });
144
+
145
+ var replaceAccordionTitle = function(element) {
146
+ var i = 0;
147
+ var table_name = $(element).data('table-name')
148
+ var model_name = $(element).data('model-name')
149
+ $(element).find('.accordion-item:visible').each(function() {
150
+ i++;
151
+ var accordion_title = model_name + ' ' + i
152
+ var accordion_id = table_name + '-' + i
153
+ $(this).find('.accordion-button').text(accordion_title);
154
+ $(this).find('.accordion-button').attr('data-bs-target', '#' + accordion_id);
155
+ $(this).find('.accordion-collapse').attr('id', accordion_id);
156
+ });
157
+ }
@@ -1,9 +1,26 @@
1
- .nested-fields class=assoc_name
2
- - @model.available_fields[ action(action_name) ][assoc_name].each do |field|
3
- .row
4
- .col-sm-10
5
- = input_field_for_column(f, field)
6
- .col-sm-2
7
- - unless field.input_type == :hidden
8
- - if @reflections.select {|x| x if x.name == assoc_name}.first.macro == :has_many
9
- = link_to_remove_association "x", f
1
+ - fields = @model.available_fields[ action(action_name) ][assoc_name]
2
+ - if fields.count == 1
3
+ .nested-single-field.nested-fields
4
+ - fields.each do |field|
5
+ .field-input
6
+ = input_field_for_column(f, field)
7
+ .field-remove-action
8
+ - unless field.input_type == :hidden
9
+ - if @reflections.select {|x| x if x.name == assoc_name}.first.macro == :has_many
10
+ = link_to_remove_association "", f, class: 'fa fa-times'
11
+ - else
12
+ .accordion-item.nested-fields
13
+ h2#headingOne.accordion-header
14
+ button.accordion-button[type="button" data-bs-toggle="collapse" data-bs-target="##{assoc_name}-#{f.object.id}" aria-expanded="true" aria-controls="collapseOne"]
15
+ | Chapter 1
16
+ .field-remove-action
17
+ - if @reflections.select {|x| x if x.name == assoc_name}.first.macro == :has_many
18
+ = link_to_remove_association "", f, class: 'fa fa-trash ghost-btn accordion-delete-btn'
19
+ div.accordion-collapse.collapse.show[aria-labelledby="headingOne" id="#{assoc_name}-#{f.object.id}"]
20
+ .accordion-body
21
+ - fields.each do |field|
22
+ .form-field
23
+ .field-label-wrapper
24
+ label.field-label = field.field_name.to_s.titleize
25
+ .field-input-wrapper
26
+ = input_field_for_column(f, field)
@@ -1,10 +1,9 @@
1
- .nested-field-wrapper
2
- label.field-label = table_name.to_s.titleize
3
- - initialized_record_count = 1
4
- = f.fields_for table_name do |record|
5
- - if record.object.persisted? || initialized_record_count == 1
6
- = render partial: '/cm_admin/main/nested_fields', locals: { f: record, assoc_name: table_name }
7
- - initialized_record_count += 1 if record.object.new_record?
8
- - if @reflections.select {|x| x if x.name == table_name}.first.macro == :has_many
9
- .links
10
- = link_to_add_association "+ Add #{table_name.to_s.titleize}", f, table_name, partial: '/cm_admin/main/nested_fields', render_options: {locals: { assoc_name: table_name }}
1
+ .nested-field-wrapper data-table-name=table_name data-model-name=table_name.to_s.classify
2
+ label.nested-field-label = table_name.to_s.titleize
3
+ .accordion.nested-form-accordion
4
+ = f.fields_for table_name do |record|
5
+ - if record.object.persisted?
6
+ = render partial: '/cm_admin/main/nested_fields', locals: { f: record, assoc_name: table_name }
7
+ - if @reflections.select {|x| x if x.name == table_name}.first.macro == :has_many
8
+ .links
9
+ = link_to_add_association "+ Add #{table_name.to_s.titleize}", f, table_name, partial: '/cm_admin/main/nested_fields', render_options: {locals: { assoc_name: table_name }}, class: 'd-inline-block secondary-btn mt-2'
@@ -4,4 +4,4 @@ ul.nav.nav-pills
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}?"))
5
5
  li.nav-item
6
6
  - nav_item_action_name = nav_item.custom_action.present? ? nav_item.custom_action : 'show'
7
- = link_to nav_item.nav_item_name.to_s.titleize, cm_admin.send("#{@ar_object.model_name.singular}_#{nav_item_action_name}_path", @ar_object.id), class: "nav-link #{ nav_item_action_name == action_name ? 'active' : ''}"
7
+ = link_to tab_display_name(nav_item.nav_item_name), cm_admin.send("#{@ar_object.model_name.singular}_#{nav_item_action_name}_path", @ar_object.id), class: "nav-link #{ nav_item_action_name == action_name ? 'active' : ''}"
@@ -7,12 +7,17 @@ html
7
7
  = csrf_meta_tags
8
8
  = csp_meta_tag
9
9
  = stylesheet_link_tag 'cm_admin/cm_admin', media: 'all', 'data-turbolinks-track': 'reload'
10
- = stylesheet_pack_tag 'cm_admin/application', 'data-turbolinks-track': 'reload'
11
- link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" /
12
- = javascript_pack_tag 'cm_admin/application', 'data-turbolinks-track': 'reload'
10
+ - if CmAdmin::VersionManager.use_webpacker?
11
+ = stylesheet_pack_tag 'cm_admin/application', 'data-turbolinks-track': 'reload'
12
+ = javascript_pack_tag 'cm_admin/application', 'data-turbolinks-track': 'reload'
13
+ script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"
14
+ - elsif CmAdmin::VersionManager.use_importmap?
15
+ = javascript_importmap_tags
16
+ = javascript_import_module_tag "cm_admin/application"
13
17
  = javascript_include_tag 'cm_admin/custom', 'data-turbolinks-track': 'reload'
14
18
  = stylesheet_link_tag 'cm_admin/custom', media: 'all', 'data-turbolinks-track': 'reload'
15
- script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"
19
+ link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" /
20
+
16
21
  script src="https://raw.githack.com/SortableJS/Sortable/master/Sortable.js"
17
22
  body
18
23
  .cm-admin
@@ -7,8 +7,9 @@ html
7
7
  = csrf_meta_tags
8
8
  = csp_meta_tag
9
9
  = stylesheet_link_tag 'cm_admin/cm_admin', media: 'all', 'data-turbolinks-track': 'reload'
10
- = stylesheet_pack_tag 'cm_admin/application', 'data-turbolinks-track': 'reload'
11
- = javascript_pack_tag 'cm_admin/application', 'data-turbolinks-track': 'reload'
10
+ - if CmAdmin::VersionManager.rails6?
11
+ = stylesheet_pack_tag 'cm_admin/application', 'data-turbolinks-track': 'reload'
12
+ = javascript_pack_tag 'cm_admin/application', 'data-turbolinks-track': 'reload'
12
13
  body
13
14
  - flash.each do |type, msg|
14
15
  .alert class="alert-#{type}"
data/bin/importmap ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # NOTE: make sure we are loading the correct versions of things
4
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
5
+ require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
6
+
7
+ # NOTE: importmap requires some rails goodness that we don't have in the engine,
8
+ # because we don't have config/application.rb that loads the environment.
9
+ require 'rails'
10
+
11
+ # importmap-rails is not loaded automatically
12
+ require 'importmap-rails'
13
+
14
+ # the actual command runner
15
+ require 'importmap/commands'
data/bin/webpack CHANGED
@@ -1,18 +1,18 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development"
4
- ENV["NODE_ENV"] ||= "development"
3
+ ENV['RAILS_ENV'] ||= ENV['RACK_ENV'] || 'development'
4
+ ENV['NODE_ENV'] ||= 'development'
5
5
 
6
- require "pathname"
7
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
6
+ require 'pathname'
7
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
8
8
  Pathname.new(__FILE__).realpath)
9
9
 
10
- require "bundler/setup"
10
+ require 'bundler/setup'
11
11
 
12
- require "webpacker"
13
- require "webpacker/webpack_runner"
12
+ require 'webpacker'
13
+ require 'webpacker/webpack_runner'
14
14
 
15
- APP_ROOT = File.expand_path("..", __dir__)
15
+ APP_ROOT = File.expand_path('..', __dir__)
16
16
  Dir.chdir(APP_ROOT) do
17
17
  Webpacker::WebpackRunner.run(ARGV)
18
18
  end
@@ -1,18 +1,18 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development"
4
- ENV["NODE_ENV"] ||= "development"
3
+ ENV['RAILS_ENV'] ||= ENV['RACK_ENV'] || 'development'
4
+ ENV['NODE_ENV'] ||= 'development'
5
5
 
6
- require "pathname"
7
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
6
+ require 'pathname'
7
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
8
8
  Pathname.new(__FILE__).realpath)
9
9
 
10
- require "bundler/setup"
10
+ require 'bundler/setup'
11
11
 
12
- require "webpacker"
13
- require "webpacker/dev_server_runner"
12
+ require 'webpacker'
13
+ require 'webpacker/dev_server_runner'
14
14
 
15
- APP_ROOT = File.expand_path("..", __dir__)
15
+ APP_ROOT = File.expand_path('..', __dir__)
16
16
  Dir.chdir(APP_ROOT) do
17
17
  Webpacker::DevServerRunner.run(ARGV)
18
- end
18
+ end
data/cm_admin.gemspec CHANGED
@@ -26,6 +26,7 @@ Gem::Specification.new do |spec|
26
26
  spec.bindir = "exe"
27
27
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
28
  spec.require_paths = ["lib"]
29
+ spec.add_runtime_dependency('rails', '>= 6.0')
29
30
  spec.add_runtime_dependency 'caxlsx_rails'
30
31
  spec.add_runtime_dependency 'cocoon', '~> 1.2.15'
31
32
  spec.add_runtime_dependency 'local_time', '~> 2.1.0'
@@ -34,4 +35,6 @@ Gem::Specification.new do |spec|
34
35
  spec.add_runtime_dependency 'slim', '~> 4.1.0'
35
36
  spec.add_runtime_dependency 'webpacker', '~> 5.4.3'
36
37
  spec.add_runtime_dependency 'csv-importer', '~> 0.8.2'
38
+ spec.add_dependency 'importmap-rails'
39
+
37
40
  end
@@ -0,0 +1,12 @@
1
+ pin 'cm_admin/application'
2
+ pin 'jquery', to: 'https://ga.jspm.io/npm:jquery@3.6.0/dist/jquery.js', preload: true
3
+ pin 'bootstrap', to: 'https://ga.jspm.io/npm:bootstrap@5.1.3/dist/js/bootstrap.esm.js', preload: true
4
+ pin '@popperjs/core', to: 'https://ga.jspm.io/npm:@popperjs/core@2.11.5/lib/index.js', preload: true
5
+ pin 'flatpickr', to: 'https://ga.jspm.io/npm:flatpickr@4.6.13/dist/esm/index.js'
6
+ pin 'jgrowl', to: 'https://ga.jspm.io/npm:jgrowl@1.4.8/jquery.jgrowl.js'
7
+ pin 'moment', to: 'https://ga.jspm.io/npm:moment@2.29.4/moment.js'
8
+ pin 'trix', to: 'https://ga.jspm.io/npm:trix@2.0.0-beta.0/dist/trix.js'
9
+ pin '@fortawesome/fontawesome-free', to: 'https://ga.jspm.io/npm:@fortawesome/fontawesome-free@6.1.1/js/all.js'
10
+ pin 'daterangepicker', to: 'https://ga.jspm.io/npm:daterangepicker@3.1.0/daterangepicker.js'
11
+ pin '@nathanvda/cocoon', to: 'https://ga.jspm.io/npm:@nathanvda/cocoon@1.2.14/cocoon.js'
12
+ pin 'select2', to: 'https://ga.jspm.io/npm:select2@4.1.0-rc.0/dist/js/select2.js'
@@ -2,4 +2,4 @@ process.env.NODE_ENV = process.env.NODE_ENV || 'development'
2
2
 
3
3
  const environment = require('./environment')
4
4
 
5
- module.exports = environment.toWebpackConfig()
5
+ module.exports = environment.toWebpackConfig()
@@ -10,4 +10,4 @@ environment.plugins.prepend('Provide',
10
10
  })
11
11
  )
12
12
 
13
- module.exports = environment
13
+ module.exports = environment
@@ -2,4 +2,4 @@ process.env.NODE_ENV = process.env.NODE_ENV || 'production'
2
2
 
3
3
  const environment = require('./environment')
4
4
 
5
- module.exports = environment.toWebpackConfig()
5
+ module.exports = environment.toWebpackConfig()
data/config/webpacker.yml CHANGED
@@ -10,7 +10,7 @@ default: &default
10
10
 
11
11
  # Additional paths webpack should lookup modules
12
12
  # ['app/assets', 'engine/foo/app/assets']
13
- additional_paths: []
13
+ additional_paths: ['app/assets']
14
14
 
15
15
  # Reload manifest.json on all requests so we reload latest compiled packs
16
16
  cache_manifest: false
@@ -89,4 +89,4 @@ production:
89
89
  extract_css: true
90
90
 
91
91
  # Cache manifest.json for performance
92
- cache_manifest: true
92
+ cache_manifest: true
@@ -1,10 +1,13 @@
1
1
  module CmAdmin
2
2
  class Configuration
3
- attr_accessor :layout, :included_models, :cm_admin_models
4
-
3
+ attr_accessor :layout, :included_models, :cm_admin_models, :authorized_roles
4
+
5
5
  def initialize
6
+ @layout = 'admin'
6
7
  @included_models = []
7
8
  @cm_admin_models = []
9
+ @authorized_roles = []
8
10
  end
11
+
9
12
  end
10
13
  end
@@ -1,4 +1,7 @@
1
1
  require 'rails'
2
+ require 'importmap-rails'
3
+ require 'cm_admin/version_manager'
4
+
2
5
  module CmAdmin
3
6
  class Engine < Rails::Engine
4
7
  isolate_namespace CmAdmin
@@ -17,24 +20,42 @@ module CmAdmin
17
20
  )
18
21
  end
19
22
 
20
- initializer "webpacker.proxy" do |app|
21
- insert_middleware = begin
22
- CmAdmin.webpacker.config.dev_server.present?
23
- rescue
24
- nil
25
- end
26
- next unless insert_middleware
27
-
28
- app.middleware.insert_before(
29
- 0, Webpacker::DevServerProxy, # "Webpacker::DevServerProxy" if Rails version < 5
30
- ssl_verify_none: true,
31
- webpacker: CmAdmin.webpacker
32
- )
33
- end
34
-
35
23
  def mount_path
36
24
  CmAdmin::Engine.routes.find_script_name({})
37
25
  end
38
26
 
27
+ if VersionManager.rails6?
28
+ initializer "webpacker.proxy" do |app|
29
+ insert_middleware = begin
30
+ CmAdmin.webpacker.config.dev_server.present?
31
+ rescue
32
+ nil
33
+ end
34
+ next unless insert_middleware
35
+
36
+ app.middleware.insert_before(
37
+ 0, Webpacker::DevServerProxy, # "Webpacker::DevServerProxy" if Rails version < 5
38
+ ssl_verify_none: true,
39
+ webpacker: CmAdmin.webpacker
40
+ )
41
+ end
42
+ elsif VersionManager.rails7?
43
+ initializer "cm_admin.importmap", before: "importmap" do |app|
44
+ # NOTE: this will add pins from this engine to the main app
45
+ # https://github.com/rails/importmap-rails#composing-import-maps
46
+ app.config.importmap.paths << root.join("config/importmap.rb")
47
+
48
+ # NOTE: something about cache; I did not look into it.
49
+ # https://github.com/rails/importmap-rails#sweeping-the-cache-in-development-and-test
50
+ app.config.importmap.cache_sweepers << root.join("app/assets/javascripts")
51
+ end
52
+
53
+ # NOTE: add engine manifest to precompile assets in production
54
+ initializer "cm_admin.assets" do |app|
55
+ app.config.assets.precompile += %w[cm_admin_manifest]
56
+ end
57
+ end
58
+
59
+
39
60
  end
40
61
  end
@@ -70,7 +70,7 @@ module CmAdmin
70
70
 
71
71
  if filter.db_column_name.map{|x| x.is_a?(Hash)}.include?(true)
72
72
  associations_hash = filter.db_column_name.select{|x| x if x.is_a?(Hash)}.last
73
- records = records.joins(associations_hash.keys)
73
+ records = records.left_joins(associations_hash.keys).distinct
74
74
  end
75
75
 
76
76
  records = records.where(
@@ -1,8 +1,13 @@
1
1
  module CmAdmin
2
2
  module Models
3
3
  class FormField
4
- attr_accessor :field_name, :label, :header, :input_type, :collection, :disabled, :helper_method, :placeholder, :display_if, :html_attr
5
- VALID_INPUT_TYPES = [:integer, :decimal, :string, :single_select, :multi_select, :date, :date_time, :text, :single_file_upload, :multi_file_upload, :hidden, :rich_text].freeze
4
+ attr_accessor :field_name, :label, :header, :input_type, :collection, :disabled, :helper_method,
5
+ :placeholder, :display_if, :html_attr, :target
6
+
7
+ VALID_INPUT_TYPES = %i[
8
+ integer decimal string single_select multi_select date date_time text
9
+ single_file_upload multi_file_upload hidden rich_text check_box radio_button
10
+ ].freeze
6
11
 
7
12
  def initialize(field_name, input_type, attributes = {})
8
13
  @field_name = field_name
@@ -20,6 +25,7 @@ module CmAdmin
20
25
  self.input_type = :string
21
26
  self.placeholder = "Enter #{self.field_name.to_s.downcase.gsub('_', ' ')}"
22
27
  self.html_attr = {}
28
+ self.target = {}
23
29
  end
24
30
  end
25
31
  end
@@ -1,3 +1,3 @@
1
1
  module CmAdmin
2
- VERSION = '0.9.0'
2
+ VERSION = '1.0.0'
3
3
  end
@@ -0,0 +1,21 @@
1
+ module CmAdmin
2
+ class VersionManager
3
+ class << self
4
+ def rails6?
5
+ Rails::VERSION::MAJOR == 6
6
+ end
7
+
8
+ def rails7?
9
+ Rails::VERSION::MAJOR == 7
10
+ end
11
+
12
+ def use_importmap?
13
+ rails7? && File.exist?('config/importmap.rb')
14
+ end
15
+
16
+ def use_webpacker?
17
+ rails6? && defined?(Webpacker) == 'constant'
18
+ end
19
+ end
20
+ end
21
+ end