cm-admin 0.6.6 → 0.6.7

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: 0644c45e1ae1e807b94e66341d607778f8ca9fbe456a1d741d34db0cf5489550
4
- data.tar.gz: 3cb2975b1c28a7cf6e150c16bb4e235750e02fb2ce39df110a4b2bb0b17f6a7c
3
+ metadata.gz: 23f6fccd6392ef215ea1e9c8927722e5c8cfe249d04515e49c9aab6daebf9b26
4
+ data.tar.gz: 6a39df0f21e575502cbe688c69a8a53ba458d81a98fc4dd455fabc6d293d5772
5
5
  SHA512:
6
- metadata.gz: 412c8867112a3241b3e71b9049473f437bcc99950cf9c286495d5bd85b25459446a3465d150703cf4056c49daadfa1dd556eb0172e873cab2d665090c9d9c66c
7
- data.tar.gz: ec362ed640f95dd335b653d6040c904d40b53fb941eeb7f0eeefe94bf3d38910fdbdf5a00fb68b5b303ab15b578b680d0ed79cd764748813ef70b3556d138666
6
+ metadata.gz: 8f944d24b0601cf979f84589fc957d9951c75cfaa1eec722819d581436dd2f496fa2fc73a8c42d98f23c1e73e46d5e40188fb93174fb8bb01a63898e3c0a5e4a
7
+ data.tar.gz: 6cb1770919c12717fa95119b12d6be1727589e4bc67f54de96af164718fd4b9d9f60feb091e46db6b5b879669cd964c9c0d87acf65f06b09ea38496f6b647a90
@@ -81,6 +81,16 @@
81
81
  }
82
82
  }
83
83
 
84
+ .select2 {
85
+ &.error {
86
+ border: 1px solid $error-clr;
87
+ border-radius: 5px;
88
+ &:focus {
89
+ outline: 3px auto rgba(248, 54, 54, 0.3);
90
+ }
91
+ }
92
+ }
93
+
84
94
  .file-upload-wrapper {
85
95
  display: inline-flex;
86
96
  align-items: center;
@@ -8,7 +8,7 @@ module CmAdmin
8
8
  class ExportsController < ApplicationController
9
9
 
10
10
  def export
11
- file_path = CmAdmin::Models::Export.generate_excel(params[:class_name], params[:columns], helpers)
11
+ file_path = CmAdmin::Models::Export.generate_excel(params[:class_name], params, helpers)
12
12
  send_file file_path, disposition: 'attachment'
13
13
  end
14
14
 
@@ -8,8 +8,10 @@ require("bootstrap")
8
8
  require('flatpickr')
9
9
  require("jgrowl")
10
10
  require('./scaffolds.js')
11
+ require('./form_validation.js')
11
12
  require('./quick_search.js')
12
13
  require('./filters.js')
14
+ require('./exports.js')
13
15
 
14
16
  import jQuery from 'jquery'
15
17
  window.$ = jQuery
@@ -0,0 +1,6 @@
1
+ $(document).on('click', '.export-to-file-btn', function(e) {
2
+ e.preventDefault();
3
+ query_param = window.location.href.split("?")[1]
4
+ $('#export-to-file-form').get(0).setAttribute('action', '/cm_admin/export_to_file.js?' + query_param);
5
+ $("#export-to-file-form").submit();
6
+ });
@@ -0,0 +1,37 @@
1
+ $(document).on('turbolinks:load', function () {
2
+ $(document).on('click', '.form_submit', function(e) {
3
+ e.preventDefault();
4
+ var submit = [];
5
+ var form_class = $(this).data('form-class');
6
+ $("." + form_class + " input.required, ." + form_class + " textarea.required").each(function() {
7
+ $(this).removeClass('error');
8
+ if ($(this).val().trim().length === 0) {
9
+ $(this).addClass('error');
10
+ window.scrollTo(top);
11
+ submit.push(true);
12
+ }
13
+ });
14
+ $("." + form_class + " select.required").each(function() {
15
+ $(this).removeClass('error');
16
+ if ($(this).val().trim().length === 0) {
17
+ $(this).parent().find('.select2').addClass('error');
18
+ window.scrollTo(top);
19
+ submit.push(true);
20
+ }
21
+ });
22
+ $('.nested_input_validation').each(function() {
23
+ var class_name;
24
+ class_name = $(this).data('class-name');
25
+ $(this).parents(':nth(1)').find('.' + class_name).addClass('hidden');
26
+ if ($(this).val().trim().length === 0) {
27
+ $(this).parents(':nth(1)').find('.' + class_name).removeClass('hidden');
28
+ window.scrollTo(top);
29
+ submit.push(true);
30
+ }
31
+ });
32
+ if (submit.length === 0) {
33
+ $('.' + form_class).submit();
34
+ return $('.form_submit').button('loading');
35
+ }
36
+ });
37
+ });
@@ -26,8 +26,8 @@
26
26
  / span
27
27
  / input.cm-checkbox type="checkbox"
28
28
  - @model.available_fields[@action.name.to_sym].each do |column|
29
- td
30
- span class="#{column.cm_css_class} text-ellipsis" = show_field_value(ar_object, column)
29
+ td class="text-ellipsis"
30
+ span class="#{column.cm_css_class}" = show_field_value(ar_object, column)
31
31
  - associated_model_actions = @associated_model && @associated_model.available_actions.select{|act| act if act.route_type == 'member'}
32
32
  - if associated_model_actions.present?
33
33
  td.row-action-cell
@@ -1,7 +1,10 @@
1
1
  .nested-field-wrapper
2
2
  label.field-label = table_name.to_s.titleize
3
+ - initialized_record_count = 1
3
4
  = f.fields_for table_name do |record|
4
- = render partial: '/cm_admin/main/nested_fields', locals: { f: record, assoc_name: table_name }
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?
5
8
  - if @reflections.select {|x| x if x.name == table_name}.first.macro == :has_many
6
9
  .links
7
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 }}
@@ -26,10 +26,6 @@ module CmAdmin
26
26
  :current_action, :params, :filters, :available_tabs, :icon_name
27
27
  attr_reader :name, :ar_model, :is_visible_on_sidebar
28
28
 
29
- # Class variable for storing all actions
30
- # CmAdmin::Model.all_actions
31
- singleton_class.send(:attr_accessor, :all_actions)
32
-
33
29
  def initialize(entity, &block)
34
30
  @name = entity.name
35
31
  @ar_model = entity
@@ -44,14 +40,10 @@ module CmAdmin
44
40
  instance_eval(&block) if block_given?
45
41
  actions unless @actions_set
46
42
  $available_actions = @available_actions.dup
47
- self.class.all_actions.push(@available_actions)
48
43
  define_controller
49
44
  end
50
45
 
51
46
  class << self
52
- def all_actions
53
- @all_actions || []
54
- end
55
47
 
56
48
  def find_by(search_hash)
57
49
  CmAdmin.config.cm_admin_models.find { |x| x.name == search_hash[:name] }
@@ -97,6 +89,15 @@ module CmAdmin
97
89
  @icon_name = name
98
90
  end
99
91
 
92
+ def filter_params(params)
93
+ # OPTIMIZE: Need to check if we can permit the filter_params in a better way
94
+ date_columns = @filters.select{|x| x.filter_type.eql?(:date)}.map(&:db_column_name)
95
+ range_columns = @filters.select{|x| x.filter_type.eql?(:range)}.map(&:db_column_name)
96
+ single_select_columns = @filters.select{|x| x.filter_type.eql?(:single_select)}.map(&:db_column_name)
97
+ multi_select_columns = @filters.select{|x| x.filter_type.eql?(:multi_select)}.map{|x| Hash["#{x.db_column_name}", []]}
98
+
99
+ params.require(:filters).permit(:search, date: date_columns, range: range_columns, single_select: single_select_columns, multi_select: multi_select_columns) if params[:filters]
100
+ end
100
101
 
101
102
  private
102
103
 
@@ -185,14 +186,6 @@ module CmAdmin
185
186
  CmAdmin.const_set "#{@name}Controller", klass
186
187
  end
187
188
 
188
- def filter_params(params)
189
- # OPTIMIZE: Need to check if we can permit the filter_params in a better way
190
- date_columns = @filters.select{|x| x.filter_type.eql?(:date)}.map(&:db_column_name)
191
- range_columns = @filters.select{|x| x.filter_type.eql?(:range)}.map(&:db_column_name)
192
- single_select_columns = @filters.select{|x| x.filter_type.eql?(:single_select)}.map(&:db_column_name)
193
- multi_select_columns = @filters.select{|x| x.filter_type.eql?(:multi_select)}.map{|x| Hash["#{x.db_column_name}", []]}
194
-
195
- params.require(:filters).permit(:search, date: date_columns, range: range_columns, single_select: single_select_columns, multi_select: multi_select_columns) if params[:filters]
196
- end
189
+
197
190
  end
198
191
  end
@@ -27,30 +27,6 @@ module CmAdmin
27
27
  self.tag_class = {}
28
28
  end
29
29
 
30
- #formatting value for different data types
31
- def self.format_data_type(column, value)
32
- case column.column_type
33
- when :string
34
- if column.format.present?
35
- column.format = [column.format] if column.format.is_a? String
36
- column.format.each do |formatter|
37
- value = value.send(formatter)
38
- end
39
- end
40
- when :datetime
41
- format_value = column.format.present? ? column.format.to_s : '%d/%m/%Y'
42
- value = value.strftime(format_value)
43
- when :enum
44
- value = value.titleize
45
- when :decimal
46
- round_to = column.round.present? ? column.round.to_i : 2
47
- value = value.round(round_to)
48
- when :custom
49
-
50
- end
51
- return value
52
- end
53
-
54
30
  class << self
55
31
  def find_by(model, search_hash)
56
32
  model.available_fields.find { |i| i.name == search_hash[:name] }
@@ -3,18 +3,10 @@ module CmAdmin
3
3
  module DslMethod
4
4
  extend ActiveSupport::Concern
5
5
 
6
- def cm_page(name: nil, partial: nil, path: nil, route_type: nil, page_title: nil, display_type: :button, &block)
7
- action = CmAdmin::Models::CustomAction.new(name: name, verb: :get, partial: partial, path: path, route_type: route_type, display_type: display_type, &block)
8
- @available_actions << action
9
- # @available_actions << CmAdmin::Models::CustomAction.new(name: name, verb: 'get', layout: 'cm_admin', partial: partial, path: path, parent: self.current_action.name, route_type: route_type, page_title: page_title, display_type: display_type, &block)
10
- # @current_action = CmAdmin::Models::CustomAction.find_by(self, name: name)
11
- end
12
-
13
6
  def cm_index(page_title: nil, page_description: nil, partial: nil, &block)
14
7
  @current_action = CmAdmin::Models::Action.find_by(self, name: 'index')
15
8
  @current_action.set_values(page_title, page_description, partial)
16
9
  yield
17
- # action.instance_eval(&block)
18
10
  end
19
11
 
20
12
  def cm_show(page_title: nil, page_description: nil, partial: nil, &block)
@@ -2,24 +2,29 @@ module CmAdmin
2
2
  module Models
3
3
  class Export
4
4
  class << self
5
- def generate_excel(klass_name, columns = [], helpers)
5
+ def generate_excel(klass_name, params, helpers)
6
6
  klass = klass_name.constantize
7
+ columns = params[:columns] || []
8
+ # filter_params = params[:filters]
7
9
  model = CmAdmin::Model.find_by({name: klass_name})
8
- records = get_records(klass, model, columns, helpers)
10
+ # records = get_records(klass, model, columns, helpers)
11
+ records = "CmAdmin::#{klass_name}Policy::Scope".constantize.new(Current.user, klass).resolve
12
+ filtered_data = CmAdmin::Models::Filter.filtered_data(model.filter_params(params), records, model.filters)
13
+ formatted_data = format_records(filtered_data, model, columns, helpers)
9
14
  file_path = "#{Rails.root}/tmp/#{klass}_data_#{DateTime.now.strftime("%Y-%m-%d_%H-%M-%S")}.xlsx"
10
- create_workbook(records, columns, file_path)
15
+ create_workbook(formatted_data, columns, file_path)
11
16
  return file_path
12
17
  end
13
18
 
14
- def get_records(klass, model, columns, helpers)
15
- records = klass
19
+
20
+ def format_records(records, model, columns, helpers)
16
21
  custom_fields = model.available_fields[:index].map{|field| field if field.field_type == :custom}.compact
17
22
  normal_fields = model.available_fields[:index].map{|field| field unless field.field_type == :custom}.compact
18
23
  deserialized_columns = CmAdmin::Utils.deserialize_csv_columns(columns, :as_json_params)
19
24
  # This includes isn't recursve, a full solution should be recursive
20
25
  records_arr = []
21
26
  records.includes(deserialized_columns[:include].keys).find_each do |record|
22
- record_hash = record.as_json({only: normal_fields.map(&:field_name)})
27
+ record_hash = record.as_json({only: columns.map(&:to_sym)})
23
28
  custom_fields.each do |field|
24
29
  record_hash[field.field_name.to_sym] = helpers.send(field.helper_method, record, field.field_name)
25
30
  end
@@ -1,3 +1,3 @@
1
1
  module CmAdmin
2
- VERSION = "0.6.6"
2
+ VERSION = "0.6.7"
3
3
  end
@@ -3,27 +3,29 @@ module CmAdmin
3
3
  module FormFieldHelper
4
4
  def input_field_for_column(f, field)
5
5
  value = field.custom_value || f.object.send(field.field_name)
6
+ is_required = f.object._validators[field.field_name].map(&:kind).include?(:presence)
7
+ required_class = is_required ? 'required' : ''
6
8
  case field.input_type
7
9
  when :integer
8
- return f.text_field field.field_name, class: 'normal-input', disabled: field.disabled, value: value, placeholder: "Enter #{field.field_name.to_s.humanize.downcase}", data: { behaviour: 'integer-only' }
10
+ return f.text_field field.field_name, class: "normal-input #{required_class}", disabled: field.disabled, value: value, placeholder: "Enter #{field.field_name.to_s.humanize.downcase}", data: { behaviour: 'integer-only' }
9
11
  when :decimal
10
- return f.number_field field.field_name, class: 'normal-input', disabled: field.disabled, value: value, placeholder: "Enter #{field.field_name.to_s.downcase.gsub('_', ' ')}", data: { behaviour: 'decimal-only' }
12
+ return f.number_field field.field_name, class: "normal-input #{required_class}", disabled: field.disabled, value: value, placeholder: "Enter #{field.field_name.to_s.downcase.gsub('_', ' ')}", data: { behaviour: 'decimal-only' }
11
13
  when :string
12
- return f.text_field field.field_name, class: 'normal-input', disabled: field.disabled, value: value, placeholder: "Enter #{field.field_name.to_s.downcase.gsub('_', ' ')}"
14
+ return f.text_field field.field_name, class: "normal-input #{required_class}", disabled: field.disabled, value: value, placeholder: "Enter #{field.field_name.to_s.downcase.gsub('_', ' ')}"
13
15
  when :single_select
14
- return f.select field.field_name, options_for_select((field.collection || []), value), {include_blank: "Select #{field.field_name.to_s.downcase.gsub('_', ' ')}"}, class: 'normal-input select-2', disabled: field.disabled
16
+ return f.select field.field_name, options_for_select((field.collection || []), value), {include_blank: "Select #{field.field_name.to_s.downcase.gsub('_', ' ')}"}, class: "normal-input #{required_class} select-2", disabled: field.disabled
15
17
  when :multi_select
16
- return f.select field.field_name, options_for_select((field.collection || []), value), {include_blank: "Select #{field.field_name.to_s.downcase.gsub('_', ' ')}"}, class: 'normal-input select-2', disabled: field.disabled, multiple: true
18
+ return f.select field.field_name, options_for_select((field.collection || []), value), {include_blank: "Select #{field.field_name.to_s.downcase.gsub('_', ' ')}"}, class: "normal-input #{required_class} select-2", disabled: field.disabled, multiple: true
17
19
  when :date
18
- return f.text_field field.field_name, class: 'normal-input', disabled: field.disabled, value: value, placeholder: "Enter #{field.field_name.to_s.downcase.gsub('_', ' ')}", data: { behaviour: 'date-only' }
20
+ return f.text_field field.field_name, class: "normal-input #{required_class}", disabled: field.disabled, value: value, placeholder: "Enter #{field.field_name.to_s.downcase.gsub('_', ' ')}", data: { behaviour: 'date-only' }
19
21
  when :date_time
20
- return f.text_field field.field_name, class: 'normal-input', disabled: field.disabled, value: value, placeholder: "Enter #{field.field_name.to_s.downcase.gsub('_', ' ')}", data: { behaviour: 'date-time' }
22
+ return f.text_field field.field_name, class: "normal-input #{required_class}", disabled: field.disabled, value: value, placeholder: "Enter #{field.field_name.to_s.downcase.gsub('_', ' ')}", data: { behaviour: 'date-time' }
21
23
  when :text
22
- return f.text_area field.field_name, class: 'normal-input', placeholder: "Enter #{field.field_name.to_s.downcase.gsub('_', ' ')}"
24
+ return f.text_area field.field_name, class: "normal-input #{required_class}", placeholder: "Enter #{field.field_name.to_s.downcase.gsub('_', ' ')}"
23
25
  when :single_file_upload
24
- return f.file_field field.field_name, class: 'normal-input'
26
+ return f.file_field field.field_name, class: "normal-input #{required_class}"
25
27
  when :multi_file_upload
26
- return f.file_field field.field_name, multiple: true, class: 'normal-input'
28
+ return f.file_field field.field_name, multiple: true, class: "normal-input #{required_class}"
27
29
  when :hidden
28
30
  return f.hidden_field field.field_name, value: field.custom_value
29
31
  end
@@ -37,7 +37,7 @@ module CmAdmin
37
37
  end
38
38
 
39
39
  def set_form_for_fields(resource, available_fields_hash, url, method)
40
- form_for(resource, url: url, method: method) do |f|
40
+ form_for(resource, url: url, method: method, html: { class: "cm_#{resource.class.name.downcase}_form" } ) do |f|
41
41
  available_fields_hash.each do |key, fields_array|
42
42
  if key == :fields
43
43
  fields_array.each do |field|
@@ -59,7 +59,7 @@ module CmAdmin
59
59
  end
60
60
  end
61
61
  concat tag.br
62
- concat f.submit 'Save', class: 'cta-btn mt-3'
62
+ concat f.submit 'Save', class: 'cta-btn mt-3 form_submit', data: {form_class: "cm_#{f.object.class.name.downcase}_form"}
63
63
  end
64
64
  end
65
65
  end
@@ -5,7 +5,6 @@ module CmAdmin
5
5
  include PageInfoHelper
6
6
  include NavigationHelper
7
7
  include FormHelper
8
- include ColumnFieldHelper
9
8
  include FieldDisplayHelper
10
9
  include FilterHelper
11
10
  include ManageColumnPopupHelper
data/yarn.lock CHANGED
@@ -1331,9 +1331,9 @@ async-limiter@~1.0.0:
1331
1331
  integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==
1332
1332
 
1333
1333
  async@^2.6.2:
1334
- version "2.6.3"
1335
- resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff"
1336
- integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==
1334
+ version "2.6.4"
1335
+ resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221"
1336
+ integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==
1337
1337
  dependencies:
1338
1338
  lodash "^4.17.14"
1339
1339
 
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: 0.6.6
4
+ version: 0.6.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - sajinmp
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2022-05-03 00:00:00.000000000 Z
13
+ date: 2022-05-11 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: pagy
@@ -148,7 +148,9 @@ files:
148
148
  - app/helpers/cm_admin/application_helper.rb
149
149
  - app/helpers/cm_admin/custom_helper.rb
150
150
  - app/javascript/packs/cm_admin/application.js
151
+ - app/javascript/packs/cm_admin/exports.js
151
152
  - app/javascript/packs/cm_admin/filters.js
153
+ - app/javascript/packs/cm_admin/form_validation.js
152
154
  - app/javascript/packs/cm_admin/quick_search.js
153
155
  - app/javascript/packs/cm_admin/scaffolds.js
154
156
  - app/javascript/stylesheets/cm_admin/application.scss
@@ -212,7 +214,6 @@ files:
212
214
  - lib/cm_admin/utils.rb
213
215
  - lib/cm_admin/version.rb
214
216
  - lib/cm_admin/view_helpers.rb
215
- - lib/cm_admin/view_helpers/column_field_helper.rb
216
217
  - lib/cm_admin/view_helpers/field_display_helper.rb
217
218
  - lib/cm_admin/view_helpers/filter_helper.rb
218
219
  - lib/cm_admin/view_helpers/form_field_helper.rb
@@ -1,29 +0,0 @@
1
- module CmAdmin
2
- module ViewHelpers
3
- module ColumnFieldHelper
4
-
5
- #adds prefix and suffix to a value
6
- def add_prefix_and_suffix_helper(value, prefix, suffix)
7
- "#{prefix} #{value} #{suffix}"
8
- end
9
-
10
- #formats the column value a field
11
- def column_for_field_helper(ar_object, column)
12
- value = ar_object.send(column.db_column_name)
13
- formatted_value = CmAdmin::Models::Column.format_data_type(column, value)
14
- formatted_value = add_prefix_and_suffix_helper(formatted_value, column.prefix, column.suffix)
15
- formatted_value = link_url_value_helper(column, value, formatted_value)
16
- return formatted_value
17
- end
18
-
19
- #column's value is either linked with 'url' attribute's value or its own value
20
- def link_url_value_helper(column, value, formatted_value)
21
- return formatted_value unless column.column_type.to_s == 'link'
22
- link_url_value = column.url.present? ? column.url : value
23
- final_value = "<a href=#{link_url_value}>#{formatted_value}</a>".html_safe
24
- return final_value
25
- end
26
-
27
- end
28
- end
29
- end