carnival 0.2.7 → 0.2.8

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.
Files changed (75) hide show
  1. data/app/assets/{images/carnival/fonts → fonts/carnival}/opensans-regular-webfont.eot +0 -0
  2. data/app/assets/{images/carnival/fonts → fonts/carnival}/opensans-regular-webfont.svg +0 -0
  3. data/app/assets/{images/carnival/fonts → fonts/carnival}/opensans-regular-webfont.ttf +0 -0
  4. data/app/assets/{images/carnival/fonts → fonts/carnival}/opensans-regular-webfont.woff +0 -0
  5. data/app/assets/{images/carnival/fonts → fonts/carnival}/opensans-semibold-webfont.eot +0 -0
  6. data/app/assets/{images/carnival/fonts → fonts/carnival}/opensans-semibold-webfont.svg +0 -0
  7. data/app/assets/{images/carnival/fonts → fonts/carnival}/opensans-semibold-webfont.ttf +0 -0
  8. data/app/assets/{images/carnival/fonts → fonts/carnival}/opensans-semibold-webfont.woff +0 -0
  9. data/app/assets/{images/carnival/fonts → fonts/carnival}/up-not.png +0 -0
  10. data/app/assets/javascripts/carnival/{vizir_admin.js → vizir_admin.js.erb} +44 -18
  11. data/app/assets/stylesheets/carnival/actions.css.scss +3 -7
  12. data/app/assets/stylesheets/carnival/carnival-table.css.scss +12 -3
  13. data/app/assets/stylesheets/carnival/forms.css.scss +1 -0
  14. data/app/assets/stylesheets/carnival/menu.css.scss +3 -3
  15. data/app/assets/stylesheets/carnival/period.css.scss +1 -1
  16. data/app/assets/stylesheets/carnival/search.css.scss +9 -6
  17. data/app/assets/stylesheets/carnival/structure.css.scss +10 -10
  18. data/app/controllers/carnival/base_admin_controller.rb +37 -57
  19. data/app/helpers/carnival/base_admin_helper.rb +52 -70
  20. data/app/inputs/admin_date_input.rb +2 -1
  21. data/app/models/carnival/batch_action.rb +1 -2
  22. data/app/models/carnival/field.rb +3 -2
  23. data/app/presenters/carnival/base_admin_presenter.rb +47 -192
  24. data/app/presenters/carnival/dsl.rb +55 -0
  25. data/app/services/carnival/klass_service.rb +5 -1
  26. data/app/services/carnival/presenters/advanced_search_parser.rb +4 -5
  27. data/app/services/carnival/query_service.rb +15 -24
  28. data/app/view_objects/carnival/paginator.rb +10 -12
  29. data/app/view_objects/carnival/thead_renderer.rb +11 -18
  30. data/app/views/carnival/base_admin/_index_as_table.html.haml +6 -4
  31. data/app/views/carnival/base_admin/index.html.haml +8 -4
  32. data/app/views/carnival/shared/_advanced_search.html.haml +6 -5
  33. data/app/views/carnival/shared/form/_form.html.haml +3 -2
  34. data/config/locales/carnival.en.yml +13 -5
  35. data/config/locales/carnival.pt-br.yml +1 -1
  36. data/lib/carnival.rb +10 -12
  37. data/lib/carnival/engine.rb +3 -2
  38. data/lib/carnival/routes.rb +4 -4
  39. data/lib/carnival/version.rb +1 -1
  40. data/spec/dummy/app/controllers/admin/todo_lists_controller.rb +7 -0
  41. data/spec/dummy/app/controllers/admin/todos_controller.rb +7 -0
  42. data/spec/dummy/app/models/todo.rb +7 -0
  43. data/spec/dummy/app/models/todo_list.rb +4 -0
  44. data/spec/dummy/app/presenters/admin/todo_list_presenter.rb +13 -0
  45. data/spec/dummy/app/presenters/admin/todo_presenter.rb +32 -0
  46. data/spec/dummy/config/application.rb +3 -0
  47. data/spec/dummy/config/database.yml +1 -1
  48. data/spec/dummy/config/environments/development.rb +2 -0
  49. data/spec/dummy/config/initializers/carnival_initializer.rb +25 -0
  50. data/spec/dummy/config/locales/carnival.en.yml +28 -0
  51. data/spec/dummy/config/locales/carnival.pt-br.yml +259 -0
  52. data/spec/dummy/config/routes.rb +7 -52
  53. data/spec/dummy/db/migrate/20150316021645_create_todos.rb +10 -0
  54. data/spec/dummy/db/migrate/20150408165317_create_todo_lists.rb +8 -0
  55. data/spec/dummy/db/migrate/20150408165333_add_todo_list_relation_to_todos.rb +5 -0
  56. data/spec/dummy/db/schema.rb +32 -0
  57. data/spec/factories/todo_lists_factory.rb +5 -0
  58. data/spec/factories/todos_factory.rb +18 -0
  59. data/spec/features/create_spec.rb +28 -0
  60. data/spec/features/destroy_spec.rb +11 -0
  61. data/spec/features/index/basic_index_spec.rb +14 -0
  62. data/spec/features/index/pagination_spec.rb +19 -0
  63. data/spec/features/index/scope_spec.rb +29 -0
  64. data/spec/features/index/search_spec.rb +28 -0
  65. data/spec/features/show_spec.rb +15 -0
  66. data/spec/features/update_spec.rb +26 -0
  67. data/spec/rails_helper.rb +25 -5
  68. data/spec/support/features/index_helpers.rb +15 -0
  69. metadata +386 -284
  70. checksums.yaml +0 -7
  71. data/app/views/carnival/base_admin/index.pdf.haml +0 -13
  72. data/app/views/carnival/shared/_header.pdf.haml +0 -13
  73. data/app/views/carnival/shared/_list_cel.pdf.haml +0 -9
  74. data/app/views/carnival/shared/_report.pdf.haml +0 -21
  75. data/config/initializers/wicked_pdf.rb +0 -5
@@ -0,0 +1,55 @@
1
+ module Carnival
2
+ module Dsl
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ [:index_as, :actions, :batch_actions, :items_per_page,
7
+ :model_names, :fields, :scopes, :forms]
8
+ .each do |variable_name|
9
+ class_variable_set("@@#{variable_name}", {})
10
+ end
11
+ end
12
+
13
+ module ClassMethods
14
+ def index_as(type)
15
+ class_variable_get('@@index_as')[presenter_class_name] = type
16
+ end
17
+
18
+ def action(name, params = {})
19
+ class_variable_get('@@actions')[presenter_class_name] ||= {}
20
+ class_variable_get('@@actions')[presenter_class_name][name] = Carnival::Action.new(name, params)
21
+ end
22
+
23
+ def batch_action(name, params = {})
24
+ class_variable_get('@@batch_actions')[presenter_class_name] ||= {}
25
+ class_variable_get('@@batch_actions')[presenter_class_name][name] = Carnival::BatchAction.new(self.new({}), name, params)
26
+ end
27
+
28
+ def items_per_page(per_page)
29
+ class_variable_get('@@items_per_page')[presenter_class_name] ||= {}
30
+ class_variable_get('@@items_per_page')[presenter_class_name][:items_per_page] = per_page
31
+ end
32
+
33
+ def scope(name, params = {})
34
+ instantiate_element(class_variable_get('@@scopes'), Carnival::Scope, name.to_sym, params)
35
+ end
36
+
37
+ def field(name, params = {})
38
+ instantiate_element(class_variable_get('@@fields'), Carnival::Field, name.to_sym, params)
39
+ end
40
+
41
+ def form(action, params = {})
42
+ instantiate_element(class_variable_get('@@forms'), Carnival::Form, name.to_sym, params)
43
+ end
44
+
45
+ def model_name(name)
46
+ class_variable_get('@@model_names')[presenter_class_name] = name
47
+ end
48
+
49
+ def instantiate_element(container, klass, name, params)
50
+ container[presenter_class_name] ||= {}
51
+ container[presenter_class_name][name] = klass.new(name, params)
52
+ end
53
+ end
54
+ end
55
+ end
@@ -1,6 +1,6 @@
1
1
  module Carnival
2
2
  class KlassService
3
-
3
+ ONE_TO_ONE_RELATION_TYPES = [:has_one, :belongs_to]
4
4
  def initialize(klass)
5
5
  @klass = klass
6
6
  end
@@ -9,6 +9,10 @@ module Carnival
9
9
  !get_association(sym).nil?
10
10
  end
11
11
 
12
+ def is_a_one_to_one_relation?(sym)
13
+ relation_type(sym).try(:in?, ONE_TO_ONE_RELATION_TYPES)
14
+ end
15
+
12
16
  def relation_type sym
13
17
  return nil if !relation?(sym)
14
18
  association = get_association(sym)
@@ -41,13 +41,12 @@ module Carnival
41
41
  end
42
42
 
43
43
  if @klass_service.relation? search_field.to_sym
44
- related_model = @klass_service.get_related_class(search_field.to_sym).name.underscore
45
- foreign_key = @klass_service.get_foreign_key(search_field.to_sym)
46
- if @klass_service.is_a_belongs_to_relation?(search_field.to_sym)
47
- records = records.joins(related_model.split("/").last.to_sym)
44
+ if @klass_service.is_a_one_to_one_relation?(search_field.to_sym)
45
+ records = records.joins(search_field.split("/").last.to_sym)
48
46
  else
49
- records = records.joins(related_model.split("/").last.pluralize.to_sym)
47
+ records = records.joins(search_field.split("/").last.pluralize.to_sym)
50
48
  end
49
+ related_model = @klass_service.get_related_class(search_field.to_sym).name.underscore
51
50
  table = related_model.split("/").last.classify.constantize.table_name
52
51
  column = "id" if column.nil?
53
52
  else
@@ -1,7 +1,7 @@
1
1
  module Carnival
2
2
  class QueryService
3
-
4
3
  attr_accessor :total_records
4
+
5
5
  def initialize(model, presenter, query_form)
6
6
  @model = model
7
7
  @presenter = presenter
@@ -18,12 +18,15 @@ module Carnival
18
18
  def records_without_pagination_and_scope
19
19
  records = @model
20
20
  records = date_period_query(records)
21
- records = search_query(records)
22
21
  records = advanced_search_query(records)
23
22
  records = order_query(records)
24
23
  includes_relations(records)
25
24
  end
26
25
 
26
+ def page_count
27
+ (total_records / @presenter.items_per_page.to_f).ceil
28
+ end
29
+
27
30
  def records_without_pagination
28
31
  scope_query records_without_pagination_and_scope
29
32
  end
@@ -34,16 +37,15 @@ module Carnival
34
37
 
35
38
  def scopes_number
36
39
  records = records_without_pagination_and_scope
37
- scopes = {}
38
- @presenter.scopes.each do |key, index|
39
- scopes[key] = scope_query(records, key).size
40
- end
41
- scopes
40
+
41
+ Hash[@presenter.scopes.keys.map do |key|
42
+ [key, scope_query(records, key).size]
43
+ end]
42
44
  end
43
45
 
44
46
  def scope_query(records, scope = @query_form.scope)
45
- if(scope.present? && scope.to_sym != :all)
46
- records = records.send(scope)
47
+ if scope.present? && scope.to_sym != :all
48
+ records.send(scope)
47
49
  else
48
50
  records
49
51
  end
@@ -51,20 +53,10 @@ module Carnival
51
53
 
52
54
  def date_period_query(records)
53
55
  date_filter_field = @presenter.date_filter_field
54
- if(date_filter_field.present? && @query_form.date_period_from.present? && @query_form.date_period_from != "" && @query_form.date_period_to.present? && @query_form.date_period_to != "")
55
- records.where("#{@presenter.table_name}.#{date_filter_field.name} between ? and ?", "#{@query_form.date_period_from} 00:00:00", "#{@query_form.date_period_to} 23:59:59")
56
- else
57
- records
58
- end
59
- end
60
-
61
- def search_query(records)
62
- if @query_form.search_term.present? and @presenter.searchable_fields.size > 0
63
- filters = @presenter.searchable_fields.map do |key, field|
64
- " #{key.to_s} like :search"
65
- end
66
- records = includes_relations(records) if @should_include_relation
67
- records.where(filters.join(" or "), search: "%#{@query_form.search_term}%")
56
+ if date_filter_field.present? && @query_form.date_period_from.present? && @query_form.date_period_from != "" && @query_form.date_period_to.present? && @query_form.date_period_to != ""
57
+ from = DateTime.parse(@query_form.date_period_from).beginning_of_day
58
+ to = DateTime.parse(@query_form.date_period_to).end_of_day
59
+ records.where(@presenter.date_filter_field.name.to_sym => [from..to])
68
60
  else
69
61
  records
70
62
  end
@@ -103,6 +95,5 @@ module Carnival
103
95
  def sort_direction
104
96
  @query_form.sort_direction
105
97
  end
106
-
107
98
  end
108
99
  end
@@ -1,6 +1,5 @@
1
1
  module Carnival
2
2
  class Paginator
3
-
4
3
  def initialize(current_page, last_page, max_fast_pages = 5)
5
4
  @current_page = current_page
6
5
  @last_page = last_page >= 1 ? last_page : 1
@@ -9,27 +8,27 @@ module Carnival
9
8
 
10
9
  def fast_pages_links_indexes
11
10
  fast_page_links = []
12
- first_index = -(@max_fast_pages/2)
13
- while fast_page_links.size < @max_fast_pages do
11
+ first_index = -(@max_fast_pages / 2)
12
+ while fast_page_links.size < @max_fast_pages
14
13
  fast_page = @current_page + first_index
15
14
  break if fast_page > @last_page
16
15
  fast_page_links << fast_page if fast_page > 0
17
- first_index = first_index + 1
16
+ first_index += 1
18
17
  end
19
18
  fast_page_links
20
19
  end
21
20
 
22
21
  def fast_pages_links_html
23
22
  fast_pages_links_indexes.map do |page|
24
- {:label => page, :css_class => get_css_class(page), :js_function => get_js_function(page)}
23
+ { label: page, css_class: get_css_class(page), js_function: get_js_function(page) }
25
24
  end
26
25
  end
27
26
 
28
- def get_js_function page
27
+ def get_js_function(page)
29
28
  "javascript:Carnival.goToPage(#{page})"
30
29
  end
31
30
 
32
- def get_css_class page
31
+ def get_css_class(page)
33
32
  if page == @current_page
34
33
  'carnival-selected-page-button'
35
34
  else
@@ -55,12 +54,11 @@ module Carnival
55
54
 
56
55
  def pages
57
56
  htmls = []
58
- htmls << {:label => ('paginate_first'), :js_function => get_js_function(1)}
59
- htmls << {:label => ('paginate_previous'), :js_function => get_js_function(previous_page)}
57
+ htmls << { label: ('paginate_first'), js_function: get_js_function(1) }
58
+ htmls << { :label => ('paginate_previous'), js_function: get_js_function(previous_page) }
60
59
  htmls = htmls + fast_pages_links_html
61
- htmls << {:label => ('paginate_next'), :js_function => get_js_function(next_page)}
62
- htmls << {:label => ('paginate_last'), :js_function => get_js_function(@last_page)}
60
+ htmls << { label: ('paginate_next'), js_function: get_js_function(next_page) }
61
+ htmls << { label: ('paginate_last'), js_function: get_js_function(@last_page) }
63
62
  end
64
-
65
63
  end
66
64
  end
@@ -1,52 +1,45 @@
1
1
  module Carnival
2
2
  class TheadRenderer
3
-
4
- def initialize fields, sort_column, sort_direction
3
+ def initialize(fields, sort_column, sort_direction)
5
4
  @fields = fields
6
5
  @sort_column = sort_column.to_sym
7
6
  @sort_direction = sort_direction
8
7
  end
9
8
 
10
-
11
9
  def columns
12
- columns = []
13
- @fields.each do |key, field|
14
- column = {
10
+ @fields.values.map do |field|
11
+ {
15
12
  field: field,
16
13
  name: field.name,
17
14
  sort_dir: sort_dir(field),
18
15
  sort_function: sort_function(field),
19
16
  class: css_class(field)
20
17
  }
21
- columns << column
22
18
  end
23
- columns
24
19
  end
25
20
 
26
- def css_class field
27
- return 'sorting_disabled' if !field.sortable?
21
+ def css_class(field)
22
+ return 'sorting_disabled' unless field.sortable?
28
23
 
29
24
  if field.sort_name.to_sym == @sort_column
30
- return "sorting_#{@sort_direction.to_s}"
25
+ "sorting_#{@sort_direction}"
31
26
  else
32
- return 'sorting'
27
+ 'sorting'
33
28
  end
34
29
  end
35
30
 
36
- def sort_function field
37
- return '' if !field.sortable?
31
+ def sort_function(field)
32
+ return '' unless field.sortable?
38
33
  sort_direction = sort_dir field
39
34
  "Carnival.sortColumn('#{field.sort_name}', '#{sort_direction}')"
40
35
  end
41
36
 
42
- def sort_dir field
37
+ def sort_dir(field)
43
38
  sort_direction = 'asc'
44
39
  if field.sort_name.to_sym == @sort_column
45
- sort_direction = 'desc' if @sort_direction == 'asc'
40
+ sort_direction = 'desc' if @sort_direction == 'asc'
46
41
  end
47
42
  sort_direction
48
43
  end
49
-
50
-
51
44
  end
52
45
  end
@@ -2,12 +2,13 @@
2
2
  %thead
3
3
  %tr
4
4
  -if presenter.has_batch_actions?
5
- %th
5
+ %th.batching
6
6
  %input{id: 'toggle-all-batch-actions-items',type: 'checkbox'}
7
7
  - @thead_renderer.columns.each do |column|
8
8
  - if ( @presenter.render_field?(column[:field], :index))
9
9
  %th{"onclick" => "javascript:#{column[:sort_function]}", "class" => "#{column[:class]}"}= translate_field(presenter, column[:field])
10
- %th.buttons
10
+ - if @presenter.actions_for_record.any?
11
+ %th.buttons
11
12
  %tbody
12
13
  - @records.each do |record|
13
14
  %tr
@@ -17,5 +18,6 @@
17
18
  - @presenter.fields_for_action(:index).each do |key, field|
18
19
  - if ( @presenter.render_field?(field, :index))
19
20
  = list_cel(@presenter, key,record, false).html_safe
20
- %td
21
- = list_buttons(@presenter, record).html_safe
21
+ - if @presenter.actions_for_record.any?
22
+ %td
23
+ = list_buttons(@presenter, record).html_safe
@@ -1,3 +1,6 @@
1
+ .gray_border.with_margin_bottom.header
2
+ %h1= @presenter.model_class.model_name.human(default: t('carnival.index'))
3
+
1
4
  - special_scope = params[:special_scope]
2
5
  - presenter = @presenter
3
6
  - params = {:class => "carnival-#{presenter.index_as}"}
@@ -10,7 +13,10 @@
10
13
  .batch-operations
11
14
  - batch_operation_actions = []
12
15
  - presenter.batch_actions.each do |key, item|
13
- = button_to item.to_label, item.path(presenter), {:method => :post, :class => "batch_action_button"}
16
+ - if item.params[:type].try(:to_sym) == :ajax
17
+ %span= link_to item.to_label, item.path(presenter), :class => "batch_action_button", remote: true, data: {'carnival-show-overlay' => true}
18
+ - else
19
+ = button_to item.to_label, item.path(presenter), {:method => :post, :class => "batch_action_button"}
14
20
  :javascript
15
21
  $(document).ready(function(){
16
22
  Carnival.batchActionInitialize("#{t('select_one_item')}");
@@ -60,8 +66,7 @@
60
66
 
61
67
  .table-download-links
62
68
  - params = @query_form.to_hash
63
- = link_to t('download_as_csv'), presenter.model_path(:index, {:format => 'csv'}.merge(params)), :class => "carnival-action-button pdf" if presenter.has_action?(:csv)
64
- = link_to t('download_as_pdf'), presenter.model_path(:index, {:format => 'pdf'}.merge(params)), :class => "carnival-action-button csv" if presenter.has_action?(:pdf)
69
+ = link_to t('download_as_csv'), presenter.model_path(:index, { format: 'csv' }.merge(params)), class: 'carnival-action-button csv' if presenter.has_action?(:csv)
65
70
 
66
71
  - else
67
72
  .empty-result
@@ -69,6 +74,5 @@
69
74
  = t('no_results')
70
75
  %h4
71
76
  %span
72
- Adicionar novo registro
73
77
  - presenter.actions_for_page.each do |key, action|
74
78
  = render '/carnival/shared/action_default', :label=>t("#{presenter.model_name}.#{action.name}", default: t("carnival.#{action.name}")), :path=> action.path(presenter)
@@ -8,11 +8,11 @@
8
8
  .search_field
9
9
  .label
10
10
  - label_field = presenter.get_field(field)
11
- - default_label = t("activerecord.attributes.#{presenter.full_model_name}.#{key}")
11
+ - translation_prefix = "activerecord.attributes.#{presenter.full_model_name}"
12
12
  - if presenter.relation_field?(label_field)
13
- = label_tag key, t("activerecord.attributes.#{label_field.name}", default: default_label)
13
+ = label_tag key, t("#{translation_prefix}.#{key.to_s.gsub('.', '_')}")
14
14
  - else
15
- = label_tag key, default_label
15
+ = label_tag key, t("#{translation_prefix}.#{key}")
16
16
  .field
17
17
  = render '/carnival/shared/advanced_search_field', :field => field, :presenter => presenter, :value => value
18
18
  %li.search_item
@@ -26,6 +26,7 @@
26
26
  - if params[key.to_s].present? && params[key.to_s] != "undefined"
27
27
  - value = params[key.to_s]
28
28
  %li.advanced-search-tag
29
- = t("activerecord.attributes.#{presenter.full_model_name}.#{key}")
30
- = ": #{value}"
29
+ %span
30
+ = t("activerecord.attributes.#{presenter.full_model_name}.#{key.to_s.gsub('.', '_')}")
31
+ = ": #{value}"
31
32
  %a{:href => "javascript:Carnival.removeAdvancedSearch('"+key.to_s+"')"}
@@ -9,9 +9,10 @@
9
9
  $(document).ready(function(){
10
10
  nestedForm = $(".nested-form-list .form-new-association").each(function(index, element){
11
11
  nestedForms[getFormName(element)] = element;
12
- element.remove();
13
12
  });
14
13
 
14
+ $(".nested-form-list .form-new-association:last-child").remove();
15
+
15
16
  $(".existing-options").hide();
16
17
  $(".nested-form-subtitle").hide();
17
18
  });
@@ -50,7 +51,7 @@
50
51
  var parentIndex = container.parents('li').index();
51
52
 
52
53
  newForm = replaceInputIndexes(newForm, parentForm, parent, parentIndex);
53
- }
54
+ }
54
55
 
55
56
  return newForm;
56
57
  }
@@ -8,6 +8,11 @@ en:
8
8
  errors:
9
9
  invalid_field: "The actions '%{actions}' are invalid for field '%{field}' for presenter '%{presenter}'"
10
10
 
11
+ messages:
12
+ created: Successfully created!
13
+ updated: Successfully updated!
14
+ select: Select
15
+
11
16
  nested_form:
12
17
  open: Open
13
18
  close: Close
@@ -17,12 +22,15 @@ en:
17
22
  existing_option: Existing Options
18
23
  existing_option_title: Options
19
24
  choose_an_option: Choose an option
25
+
26
+ create: Create
20
27
  minimize: Minimize
21
28
  paginate_first: First
22
- paginate_previous: « Previous
23
- paginate_next: Next »
24
29
  paginate_last: Last
30
+ paginate_next: Next »
31
+ paginate_previous: « Previous
25
32
  paginate_total: Total
26
- sort_by: Sort by
27
- asc: Crescent
28
- desc: Decrescent
33
+ please_wait: Wait...
34
+ update: Update
35
+ from: From
36
+ to: To
@@ -5,6 +5,7 @@ pt-BR:
5
5
  new: Novo
6
6
  edit: Editar
7
7
  destroy: Apagar
8
+ index: Listagem
8
9
  errors:
9
10
  invalid_field: "As actions '%{actions}' não são válidas para o campo '%{field}' do presenter '%{presenter}'"
10
11
 
@@ -30,7 +31,6 @@ pt-BR:
30
31
  asc: Crescente
31
32
  desc: Decrescente
32
33
  download_as_csv: Baixar como CSV
33
- download_as_pdf: Baixar como PDF
34
34
  no_results: Não foram encontrados resultados
35
35
  advanced_search: Busca
36
36
  select_an_option: Selecione uma opção