carnival 0.2.7 → 0.2.8

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