cm-admin 0.6.6 → 0.6.7

Sign up to get free protection for your applications and to get access to all the features.
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