kono_utils 0.15.5

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 (112) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +442 -0
  4. data/Rakefile +23 -0
  5. data/app/assets/javascripts/kono_utils/utilities.coffee +456 -0
  6. data/app/assets/stylesheets/kono_utils/utils.css.scss +43 -0
  7. data/app/controllers/kono_utils/change_log_controller.rb +6 -0
  8. data/app/input/bs_aceeditor_input.rb +53 -0
  9. data/app/input/bs_autocomplete_input.rb +60 -0
  10. data/app/input/bs_datepicker_input.rb +16 -0
  11. data/app/input/bs_datetimepicker_input.rb +80 -0
  12. data/app/input/bs_file_download_input.rb +35 -0
  13. data/app/input/bs_image_input.rb +35 -0
  14. data/app/input/bs_label_with_container_input.rb +22 -0
  15. data/app/input/bs_location_picker_input.rb +95 -0
  16. data/app/input/bs_readonly_input.rb +52 -0
  17. data/app/input/bs_timepicker_input.rb +14 -0
  18. data/app/policies/kono_utils/base_editing_policy_concern.rb +27 -0
  19. data/app/views/kono_utils/base_editing/_edit.html.erb +3 -0
  20. data/app/views/kono_utils/base_editing/_edit_page_side_title_header.html.erb +3 -0
  21. data/app/views/kono_utils/base_editing/_edit_page_title_header.html.erb +3 -0
  22. data/app/views/kono_utils/base_editing/_form.html.erb +15 -0
  23. data/app/views/kono_utils/base_editing/_index_buttons.html.erb +2 -0
  24. data/app/views/kono_utils/base_editing/_index_page_side_title_header.html.erb +3 -0
  25. data/app/views/kono_utils/base_editing/_index_page_title_header.html.erb +3 -0
  26. data/app/views/kono_utils/base_editing/_index_tfoot.html.erb +0 -0
  27. data/app/views/kono_utils/base_editing/_new.html.erb +3 -0
  28. data/app/views/kono_utils/base_editing/_new_page_side_title_header.html.erb +3 -0
  29. data/app/views/kono_utils/base_editing/_new_page_title_header.html.erb +3 -0
  30. data/app/views/kono_utils/base_editing/_search_form.html.erb +1 -0
  31. data/app/views/kono_utils/base_editing/application/_edit_page_side_title_header.html.erb +1 -0
  32. data/app/views/kono_utils/base_editing/application/_edit_page_title_header.html.erb +1 -0
  33. data/app/views/kono_utils/base_editing/application/_index_page_side_title_header.html.erb +1 -0
  34. data/app/views/kono_utils/base_editing/application/_index_page_title_header.html.erb +1 -0
  35. data/app/views/kono_utils/base_editing/application/_new_page_side_title_header.html.erb +1 -0
  36. data/app/views/kono_utils/base_editing/application/_new_page_title_header.html.erb +1 -0
  37. data/app/views/kono_utils/base_editing/application/edit.html.erb +1 -0
  38. data/app/views/kono_utils/base_editing/application/new.html.erb +1 -0
  39. data/app/views/kono_utils/base_editing/edit.html.erb +1 -0
  40. data/app/views/kono_utils/base_editing/index.html.erb +36 -0
  41. data/app/views/kono_utils/base_editing/new.html.erb +1 -0
  42. data/app/views/kono_utils/change_log/index.html.erb +3 -0
  43. data/config/initializers/mysql.rb +12 -0
  44. data/config/initializers/time.rb +12 -0
  45. data/config/locales/it.yml +18 -0
  46. data/lib/generators/kono_utils/install/install_generator.rb +24 -0
  47. data/lib/generators/templates/initializer.rb +3 -0
  48. data/lib/kono_utils.rb +41 -0
  49. data/lib/kono_utils/application_helper.rb +625 -0
  50. data/lib/kono_utils/base_editing_helper.rb +194 -0
  51. data/lib/kono_utils/base_search.rb +173 -0
  52. data/lib/kono_utils/concerns.rb +10 -0
  53. data/lib/kono_utils/concerns/active_record_translation.rb +47 -0
  54. data/lib/kono_utils/concerns/base_editing.rb +195 -0
  55. data/lib/kono_utils/concerns/base_modals.rb +97 -0
  56. data/lib/kono_utils/concerns/success_message.rb +25 -0
  57. data/lib/kono_utils/encoder.rb +55 -0
  58. data/lib/kono_utils/engine.rb +13 -0
  59. data/lib/kono_utils/fiscal_code.rb +47 -0
  60. data/lib/kono_utils/params_hash_array.rb +37 -0
  61. data/lib/kono_utils/percentage.rb +60 -0
  62. data/lib/kono_utils/search_attribute.rb +57 -0
  63. data/lib/kono_utils/tmp_file.rb +81 -0
  64. data/lib/kono_utils/version.rb +3 -0
  65. data/lib/kono_utils/virtual_model.rb +22 -0
  66. data/lib/tasks/kono_utils_tasks.rake +4 -0
  67. data/spec/dummy/README.rdoc +28 -0
  68. data/spec/dummy/Rakefile +6 -0
  69. data/spec/dummy/app/assets/images/.keep +0 -0
  70. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  71. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  72. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  73. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  74. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  75. data/spec/dummy/app/mailers/.keep +0 -0
  76. data/spec/dummy/app/models/.keep +0 -0
  77. data/spec/dummy/app/models/concerns/.keep +0 -0
  78. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  79. data/spec/dummy/bin/bundle +3 -0
  80. data/spec/dummy/bin/rails +4 -0
  81. data/spec/dummy/bin/rake +4 -0
  82. data/spec/dummy/bin/setup +29 -0
  83. data/spec/dummy/config.ru +4 -0
  84. data/spec/dummy/config/application.rb +32 -0
  85. data/spec/dummy/config/boot.rb +5 -0
  86. data/spec/dummy/config/database.yml +25 -0
  87. data/spec/dummy/config/environment.rb +5 -0
  88. data/spec/dummy/config/environments/development.rb +41 -0
  89. data/spec/dummy/config/environments/production.rb +79 -0
  90. data/spec/dummy/config/environments/test.rb +42 -0
  91. data/spec/dummy/config/initializers/assets.rb +11 -0
  92. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  93. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  94. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  95. data/spec/dummy/config/initializers/inflections.rb +16 -0
  96. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  97. data/spec/dummy/config/initializers/session_store.rb +3 -0
  98. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  99. data/spec/dummy/config/locales/en.yml +23 -0
  100. data/spec/dummy/config/routes.rb +56 -0
  101. data/spec/dummy/config/secrets.yml +22 -0
  102. data/spec/dummy/lib/assets/.keep +0 -0
  103. data/spec/dummy/log/.keep +0 -0
  104. data/spec/dummy/public/404.html +67 -0
  105. data/spec/dummy/public/422.html +67 -0
  106. data/spec/dummy/public/500.html +66 -0
  107. data/spec/dummy/public/favicon.ico +0 -0
  108. data/spec/lib/kono_utils/fiscal_code_spec.rb +56 -0
  109. data/spec/rails_helper.rb +53 -0
  110. data/spec/spec_helper.rb +92 -0
  111. data/vendor/assets/javascripts/EventEmitter.js +473 -0
  112. metadata +425 -0
@@ -0,0 +1,52 @@
1
+ class BsReadonlyInput < Formtastic::Inputs::StringInput
2
+ include FormtasticBootstrap::Inputs::Base
3
+ include FormtasticBootstrap::Inputs::Base::Collections
4
+ include ActionView::Helpers::TagHelper
5
+ include ActionView::Context
6
+ include FontAwesome::Rails::IconHelper
7
+ include ActionView::Helpers::JavaScriptHelper
8
+
9
+
10
+ ##
11
+ # Nel caso di collection si può definire con
12
+ # :show_hidden => [true] per stampare il campo hidden o meno con il vero valore
13
+ # :display_field come options quale campo usare per stampare
14
+ # :value_renderer => Proc da aggiungere, a cui passiamo
15
+ # campo, valore , se passato nulla viene
16
+ # renderizzato standard un p contenente il valore
17
+ #
18
+ def to_html
19
+
20
+ field_name = method
21
+ show_value = object.send(method)
22
+ if show_value.is_a?(ActiveRecord::Base) and !options[:display_field].blank?
23
+ #vuol dire che siamo in una collection
24
+ show_value = show_value.send(options[:display_field])
25
+ field_name = input_name
26
+ end
27
+
28
+ if !options[:value_renderer].is_a?(Proc)
29
+ options[:value_renderer]=Proc.new { |field, value|
30
+ buff = ActiveSupport::SafeBuffer.new
31
+ buff<<content_tag(:p, value, class: 'form-control-static', id: "#{field.form_control_input_html_options[:id]}_container")
32
+ buff
33
+ }
34
+ end
35
+
36
+
37
+ bootstrap_wrapping do
38
+ content_tag(:div, class: 'input-group date') do
39
+
40
+ buff = ActiveSupport::SafeBuffer.new
41
+
42
+ buff<< options[:value_renderer].call(self, show_value)
43
+
44
+ buff<< builder.hidden_field(field_name, form_control_input_html_options)
45
+
46
+ buff
47
+
48
+ end
49
+ end
50
+ end
51
+
52
+ end
@@ -0,0 +1,14 @@
1
+ class BsTimepickerInput < BsDatetimepickerInput
2
+
3
+ def icon
4
+ fa_icon("clock-o".to_sym)
5
+ end
6
+
7
+ def default_javascript_options
8
+ {
9
+ server_format: 'YYYY-MM-DD HH:mm:ss UTC',
10
+ server_match: '/^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2} UTC$/',
11
+ format: 'HH:mm'
12
+ }
13
+ end
14
+ end
@@ -0,0 +1,27 @@
1
+ require 'active_support/concern'
2
+ module KonoUtils
3
+
4
+ module BaseEditingPolicyConcern
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ def permitted_attributes
9
+ # [:descrizione]
10
+ record.class.column_names.collect { |s| s.to_sym } - [:id, :created_at, :updated_at]
11
+ end
12
+ end
13
+
14
+ if defined? ::Application::Scope
15
+ class Scope < ::Application::Scope
16
+ def resolve
17
+ scope
18
+ end
19
+ end
20
+ end
21
+
22
+ # module ClassMethods
23
+
24
+ # end
25
+ end
26
+ end
27
+
@@ -0,0 +1,3 @@
1
+ <%= render 'edit_page_title_header' %>
2
+ <%= render 'edit_page_side_title_header' %>
3
+ <%= render 'form' %>
@@ -0,0 +1,3 @@
1
+ <% content_for :side_title do %>
2
+ <%= list_button index_custom_polymorphic_path(base_class) if policy(base_class).index? %>
3
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <% content_for :page_title do %>
2
+ <%= title_mod_g(base_class) %>
3
+ <% end %>
@@ -0,0 +1,15 @@
1
+ <%= semantic_form_for(*semantic_form_attributes(@object)) do |f| %>
2
+
3
+ <div class="row">
4
+ <% form_attributes(@object).each do |field| %>
5
+
6
+ <div class="<%= cell_column_class(field) %>">
7
+ <%= editing_form_print_field(f, field) %>
8
+ </div>
9
+
10
+ <% end %>
11
+ </div>
12
+
13
+ <%= form_submit f %>
14
+
15
+ <% end %>
@@ -0,0 +1,2 @@
1
+ <%= edit_button edit_custom_polymorphic_path(record) if policy(record).edit? %>
2
+ <%= delete_button index_custom_polymorphic_path(record) if policy(record).destroy? %>
@@ -0,0 +1,3 @@
1
+ <% content_for :side_title do %>
2
+ <%= new_button new_custom_polymorphic_path(base_class) if policy(base_class.new).create? %>
3
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <% content_for :page_title do %>
2
+ <%= base_class.mnp %>
3
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <%= render 'new_page_title_header' %>
2
+ <%= render 'new_page_side_title_header' %>
3
+ <%= render 'form' %>
@@ -0,0 +1,3 @@
1
+ <% content_for :side_title do %>
2
+ <%= list_button index_custom_polymorphic_path(base_class) %>
3
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <% content_for :page_title do %>
2
+ <%= title_new_g(base_class) %>
3
+ <% end %>
@@ -0,0 +1 @@
1
+ <%= search_form @search, {:reset_path => polymorphic_path(base_class)} %>
@@ -0,0 +1 @@
1
+ <%= render 'base_editing/edit_page_side_title_header' %>
@@ -0,0 +1 @@
1
+ <%= render 'base_editing/edit_page_title_header' %>
@@ -0,0 +1 @@
1
+ <%= render 'base_editing/index_page_side_title_header' %>
@@ -0,0 +1 @@
1
+ <%= render 'base_editing/index_page_title_header' %>
@@ -0,0 +1 @@
1
+ <%= render 'base_editing/new_page_title_header' %>
@@ -0,0 +1 @@
1
+ <%= render 'base_editing/new_page_title_header' %>
@@ -0,0 +1 @@
1
+ <%= render 'base_editing/edit' %>
@@ -0,0 +1 @@
1
+ <%= render 'base_editing/new' %>
@@ -0,0 +1 @@
1
+ <%= render 'base_editing/edit' %>
@@ -0,0 +1,36 @@
1
+ <%= render 'index_page_title_header' %>
2
+ <%= render 'index_page_side_title_header' %>
3
+
4
+ <%= render 'search_form' unless @search.nil? %>
5
+
6
+ <table class="table table-bordered table-hover">
7
+ <thead>
8
+ <tr>
9
+ <% table_columns.each do |t| %>
10
+ <%= index_column_builder(t, :th) do %>
11
+ <%= index_print_column_head(t) %>
12
+ <% end %>
13
+ <% end %>
14
+ <th class="index-col-btn"></th>
15
+ </tr>
16
+ </thead>
17
+
18
+ <tbody>
19
+ <% @objects.each do |r| %>
20
+ <tr>
21
+ <% table_columns.each do |t| %>
22
+ <%= index_column_builder(t, :td, record: r) do %>
23
+ <%= index_print_column(r, t) %>
24
+ <% end %>
25
+ <% end %>
26
+ <th class="index-col-btn">
27
+ <%= render 'index_buttons', record: r %>
28
+ </th>
29
+ </tr>
30
+ <% end %>
31
+ </tbody>
32
+ <%= render 'index_tfoot' %>
33
+ </table>
34
+
35
+ <%= will_paginate_bst(@objects) %>
36
+
@@ -0,0 +1 @@
1
+ <%= render 'base_editing/new' %>
@@ -0,0 +1,3 @@
1
+ <% content_for :title, t('.title', :default => 'Changelog') %>
2
+
3
+ <%=raw RDiscount.new(File.open(Rails.root.join('CHANGELOG.md')).read).to_html %>
@@ -0,0 +1,12 @@
1
+ # Creates DATETIME(6) column types by default which support microseconds.
2
+ #
3
+ # Without it, only regular (second precise) DATETIME columns are created.
4
+ module ActiveRecord::ConnectionAdapters
5
+ if ActiveRecord::Base.connection.instance_of? Mysql2Adapter
6
+ version = Gem::Version.new(Mysql2::Client.info.fetch(:version))
7
+ min_vresion = Gem::Version.new('5.6.4')
8
+ if version>=min_vresion
9
+ AbstractMysqlAdapter::NATIVE_DATABASE_TYPES[:datetime][:limit] = 6
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # NOTE: Apparently, this initializer is not necessary with Rails 4.2.5 and up.
2
+ # It just works with the correct database type DATETIME(6).
3
+
4
+ # Where 6N is the number of places after the decimal (.)
5
+ # For less precision (eg. miliseconds), change 6N to 3N
6
+ if ActiveRecord::Base.connection.instance_of? ActiveRecord::ConnectionAdapters::Mysql2Adapter
7
+ version = Gem::Version.new(Mysql2::Client.info.fetch(:version))
8
+ min_vresion = Gem::Version.new('5.6.4')
9
+ if version>=min_vresion
10
+ Time::DATE_FORMATS[:db] = '%Y-%m-%d %H:%M:%S.%6N'
11
+ end
12
+ end
@@ -0,0 +1,18 @@
1
+ it:
2
+ back: Indietro
3
+ new: Nuovo
4
+ newa: Nuova
5
+ edit: Modifica
6
+ del: Cancella
7
+ wait: "Wait..."
8
+ are_you_sure: "Confermi la cancellazione?"
9
+ formtastic:
10
+ inputs:
11
+ bs_file_download:
12
+ download: Download
13
+ activerecord:
14
+ successful:
15
+ messages:
16
+ created: "%{model} creato correttamente."
17
+ updated: "%{model} aggiornato correttamente."
18
+ destroyed: "%{model} è stato correttamente cancellato."
@@ -0,0 +1,24 @@
1
+ require 'rails/generators'
2
+ module KonoUtils
3
+ class InstallGenerator < Rails::Generators::Base
4
+ desc "Installa l'inizializzatore"
5
+
6
+ # Commandline options can be defined here using Thor-like options:
7
+ # class_option :my_opt, :type => :boolean, :default => false, :desc => "My Option"
8
+
9
+ # I can later access that option using:
10
+ # options[:my_opt]
11
+
12
+
13
+ def self.source_root
14
+ @source_root ||= File.expand_path('../../../templates', __FILE__)
15
+ end
16
+
17
+ # Generator Code. Remember this is just suped-up Thor so methods are executed in order
18
+ def copy_files
19
+ copy_file 'initializer.rb', 'config/initializers/kono_utils.rb'
20
+ end
21
+
22
+
23
+ end
24
+ end
@@ -0,0 +1,3 @@
1
+ KonoUtils.configure do |config|
2
+ #config.google_api_key = '' #chiave API
3
+ end
data/lib/kono_utils.rb ADDED
@@ -0,0 +1,41 @@
1
+ require 'kono_utils/engine' if defined?(::Rails)
2
+
3
+ module KonoUtils
4
+ extend ActiveSupport::Autoload
5
+
6
+ autoload :VirtualModel
7
+ autoload :Encoder
8
+ autoload :ParamsHashArray
9
+ autoload :Percentage
10
+ autoload :FiscalCode
11
+ autoload :TmpFile
12
+ autoload :ApplicationHelper
13
+ autoload :BaseEditingHelper
14
+ autoload :BaseSearch
15
+ autoload :Concerns
16
+
17
+ class Configuration
18
+ attr_accessor :google_api_key
19
+ end
20
+
21
+ class << self
22
+ attr_writer :configuration
23
+ end
24
+
25
+ def self.configuration
26
+ @configuration ||= Configuration.new
27
+ end
28
+
29
+ def self.configure
30
+ yield configuration
31
+ end
32
+
33
+
34
+ end
35
+
36
+
37
+ if defined?(::Rails)
38
+ if Rails.gem_version > Gem::Version.new('4.2.0')
39
+ require 'kono_utils/concerns/active_record_translation'
40
+ end
41
+ end
@@ -0,0 +1,625 @@
1
+ module KonoUtils
2
+ module ApplicationHelper
3
+
4
+
5
+ def will_paginate_bst(collection)
6
+ will_paginate collection, renderer: BootstrapPagination::Rails
7
+ end
8
+
9
+
10
+ def namespace_content(&block)
11
+ content_tag :div, class: "#{(controller.class.name.split("::") + [action_name]).join(" ")}" do
12
+ yield
13
+ end
14
+
15
+ end
16
+
17
+ def true_false_label(val)
18
+
19
+ if val
20
+ icon =fa_icon(:check)
21
+ classe='success'
22
+ else
23
+ classe='danger'
24
+ icon =fa_icon(:times)
25
+ end
26
+
27
+ content_tag(:span, icon, class: "label label-#{classe}")
28
+
29
+ end
30
+
31
+
32
+ ##
33
+ # Genera una modal da riutilizzare per far aspettare determinate operazioni al client
34
+ def bootstrap_please_wait
35
+ content_tag(:div,
36
+ class: 'modal fade',
37
+ id: 'processing_wait',
38
+ tabindex: "-1",
39
+ role: "dialog",
40
+ "aria-hidden".to_sym => "true") do
41
+ content_tag :div, class: 'modal-dialog modal-sm' do
42
+ content_tag :div, class: 'modal-content' do
43
+
44
+ buff = ActiveSupport::SafeBuffer.new
45
+
46
+ buff << content_tag(:div, class: 'modal-header') do
47
+ content_tag(:h4, "Processing...", class: "modal-title")
48
+ end
49
+
50
+ buff << content_tag(:div, class: 'modal-body') do
51
+ content_tag :div, class: "progress" do
52
+ content_tag :div, ' ', class: "progress-bar progress-bar-striped active", role: "progressbar", style: "width: 100%"
53
+ end
54
+ end
55
+
56
+ buff
57
+ end
58
+ end
59
+ end
60
+ end
61
+
62
+
63
+ ##
64
+ # Genera la form di ricerca
65
+ # * *Args* :
66
+ # - search_model -> KonoUtils::BaseSearch
67
+ # - args -> Hash with configurations:
68
+ # - attributes -> array of symbols for the search, if empty used from search_model
69
+ # - reset_path -> path per cui resettare la ricerca, nil
70
+ # - form_opts -> opzioni da aggiungere per la form
71
+ # - buttons_editor -> Proc chiamata, con il passaggio dell'oggetto della form e
72
+ # del ActiveSupport::SafeBuffer con all'interno dei bottoni
73
+ # come parametro, deve ritornare
74
+ # un ActiveSupport::SafeBuffer a sua volta
75
+ # * *Returns* :
76
+ # -
77
+ #
78
+ def search_form(search_model, args={})
79
+
80
+ args = {
81
+ :attributes => [],
82
+ :reset_path => nil,
83
+ :form_opts => {},
84
+ :field_option => {:wrapper_html => {:class => "col-xs-12 col-sm-6 col-md-4 col-lg-3"}},
85
+ :buttons_editor => Proc.new { |form_obj, sb| sb }
86
+ }.merge(args)
87
+
88
+ reset_path = args[:reset_path]
89
+
90
+ field_option = args[:field_option]
91
+
92
+ base_search_form_wrapper(search_model, {:attributes => args[:attributes], :form_opts => args[:form_opts]}) do |f|
93
+ content_tag :div, class: "panel panel-default search_panel" do
94
+
95
+ buffer = ActiveSupport::SafeBuffer.new
96
+
97
+ buffer<< content_tag(:div, class: 'panel-heading') do
98
+ content_tag :h3, class: "panel-title collapse_search" do
99
+ header = ActiveSupport::SafeBuffer.new
100
+
101
+ header<< content_tag(:span, t(:search))
102
+
103
+ header<<content_tag(:div, fa_icon("search") + content_tag(:span, nil, class: 'caret'), class: 'pull-right icon-search')
104
+
105
+ header
106
+ end
107
+ end
108
+
109
+ buffer<< content_tag(:div, class: "collapsible_panel #{(search_model.data_loaded? ? 'uncollapsed' : '')}") do
110
+ fb_collapse = ActiveSupport::SafeBuffer.new
111
+
112
+ fb_collapse << content_tag(:div, class: "panel-body") do
113
+ f.fields_builder(:field_options => field_option)
114
+ end
115
+
116
+
117
+ fb_collapse << content_tag(:div, class: 'panel-footer text-right') do
118
+ form_buffer = ActiveSupport::SafeBuffer.new
119
+
120
+ form_buffer<< button_tag(t(:search), type: "submit", class: "btn btn-primary")
121
+
122
+ if search_model.data_loaded? and !reset_path.nil?
123
+ form_buffer<< link_to(content_tag(:span, nil, class: 'glyphicon glyphicon-remove'), reset_path, class: 'btn btn-info')
124
+ end
125
+
126
+ args[:buttons_editor].call(f, form_buffer)
127
+ end
128
+
129
+ fb_collapse
130
+ end
131
+
132
+ buffer
133
+ end
134
+ end
135
+
136
+
137
+ end
138
+
139
+ class BaseSearchFormWrapper < Struct.new(:formtastic_form, :attributes, :current_user)
140
+
141
+ def fields_builder(cfgs={field_options: {}})
142
+ form_buffer = ActiveSupport::SafeBuffer.new
143
+
144
+ self.attributes.each do |field|
145
+
146
+ form_options = field.form_options
147
+ if form_options.is_a?(Proc)
148
+ form_options = form_options.call(current_user, self.formtastic_form)
149
+ end
150
+
151
+ form_buffer << self.formtastic_form.input(field.field, cfgs[:field_options].merge(form_options))
152
+ end
153
+
154
+ form_buffer
155
+ end
156
+ end
157
+
158
+ ##
159
+ # Utility interna che si occupa della logica minima per generare la il form di ricerca
160
+ def base_search_form_wrapper(search_model, args={:attributes => [], :form_opts => {}})
161
+ attributes = args[:attributes] || {}
162
+ form_opts = args[:form_opts] || {}
163
+ if attributes.length==0
164
+ attributes = search_model.search_attributes
165
+ end
166
+
167
+ form_opts = {method: :get, :html => {autocomplete: 'off'}}.merge(form_opts)
168
+
169
+ semantic_form_for search_model, form_opts do |f|
170
+ yield BaseSearchFormWrapper.new(f, attributes, @current_user)
171
+ end
172
+ end
173
+
174
+
175
+ def title_mod(model)
176
+ "#{t(:edit)} #{model.mn}"
177
+ end
178
+
179
+ def title_new(model)
180
+ "#{t(:new)} #{model.mn}"
181
+ end
182
+
183
+ def title_newa(model)
184
+ "#{t(:newa)} #{model.mn}"
185
+ end
186
+
187
+ def title_del(model)
188
+ "#{t(:del)} #{model.mn}"
189
+ end
190
+
191
+
192
+ ##
193
+ # Genera l'hash da passare come collection alle selectbox, esegue anche la traduzione con locale
194
+ #
195
+ # <%= f.input :usage, :as => :select,
196
+ # :collection => enum_collection(Logo, :usage), :input_html => {:include_blank => true} %>
197
+ #
198
+ # * *Args* :
199
+ # - model -> ActiveRecord model contenente l'enum
200
+ # - attribute -> Symbol che identifica l'attributo dell'enum
201
+ # - variant -> se c'è la variante questa viene inserite _#{variant} dopo il nome del valore
202
+ # * *Returns* :
203
+ # - Hash
204
+ #
205
+ def enum_collection(model, attribute, variant=nil)
206
+
207
+ model.send(attribute.to_s.pluralize(2).to_sym).collect { |key, val|
208
+ [enum_translation(model, attribute, key, variant), key]
209
+ }.to_h
210
+ end
211
+
212
+
213
+ ##
214
+ # Si occupa di tradurre un determinato valore di un enum
215
+ # - model -> ActiveRecord model contenente l'enum
216
+ # - attribute -> Symbol che identifica l'attributo dell'enum
217
+ # - variant -> se c'è la variante questa viene inserite _#{variant} dopo il nome del valore
218
+ #
219
+ # * *Returns* :
220
+ # - String
221
+ #
222
+ def enum_translation(model, attribute, value, variant=nil)
223
+ ApplicationHelper.enum_translation(model, attribute, value, variant)
224
+ end
225
+
226
+
227
+ ##
228
+ # Le traduzioni dentro al locale devono essere fatte in questo modo:
229
+ # it:
230
+ # activerecord:
231
+ # attributes:
232
+ # estimate_before/value:
233
+ # na: NA
234
+ # very_insufficient: 1
235
+ # insufficient: 2
236
+ # sufficient: 3
237
+ # excellent: 4
238
+ #
239
+ # dove in questo caso estimate_before è il modello e value è il nome del campo enum
240
+ #
241
+ def self.enum_translation(model, attribute, value, variant=nil)
242
+ return '' if value.nil?
243
+ variant = "_#{variant}" unless variant.nil?
244
+ model.human_attribute_name("#{attribute}.#{value}#{variant}")
245
+ end
246
+
247
+
248
+ ##
249
+ # Helper per generare una modal con all'interno un form
250
+ # Utilizzare passando un block il quale riceve come parametro la form di formtastic
251
+ # possibile passare anche una proc in buttons_proc per scrivere in modo differente i bottoni nella modal,
252
+ # alla proc viene passato il solito form di formtastic e il bottone standard di chiusura
253
+ #
254
+ def modal_form_generator(args = {})
255
+
256
+ args = {
257
+ id: 'modal',
258
+ class: '',
259
+ title: 'Titolo',
260
+ form_cfgs: [],
261
+ buttons_proc: Proc.new do |f, default_close_btn|
262
+ default_close_btn +
263
+ f.action(:submit, button_html: {class: 'btn btn-primary'}, :label => :save_and_close)
264
+ end
265
+ }.merge(args)
266
+
267
+ raise 'Passare le configurazioni per la form' if args[:form_cfgs]==[]
268
+
269
+ default_close_btn = content_tag(:button, 'Chiudi', type: 'button', class: 'btn btn-default', data: {dismiss: "modal"})
270
+
271
+ content_tag(:div,
272
+ class: "modal fade kono_modal_form",
273
+ id: args[:id],
274
+ tabindex: "-1",
275
+ role: "dialog",
276
+ "aria-hidden".to_sym => "true") do
277
+ content_tag :div, class: 'modal-dialog' do
278
+ semantic_form_for(*args[:form_cfgs]) do |f|
279
+ content_tag :div, class: 'modal-content' do
280
+
281
+ buff = ActiveSupport::SafeBuffer.new
282
+
283
+ buff << content_tag(:div, class: 'modal-header') do
284
+ content_tag(:button, raw("&times;"), type: "button", class: "close", data: {dismiss: 'modal'}, "aria-hidden".to_sym => "true") +
285
+ content_tag(:h4, args[:title], class: "modal-title")
286
+ end
287
+
288
+ buff << content_tag(:div, class: 'modal-body') do
289
+ yield f
290
+ end
291
+
292
+ buff << content_tag(:div, class: 'modal-footer') do
293
+ args[:buttons_proc].call(f, default_close_btn)
294
+ end
295
+
296
+ buff
297
+ end
298
+ end
299
+ end
300
+ end
301
+
302
+ end
303
+
304
+
305
+ ##
306
+ # Genera il bottone per editazione con una modal del contenuto,
307
+ # gli viene passato un block contenente la modal da lanciare per l'editazione,
308
+ # solitamente generata con modal_form_generator.
309
+ # come parametri viene passato l'id del target che si aspetta di richiamare
310
+ #
311
+ # ES:
312
+ # modal_edit_button do |id|
313
+ # render 'tikal_core/people/person_contacts/modal_form', :contact => contact, :id => id %>
314
+ # end
315
+ #
316
+ # Attributes:
317
+ # align: left|rigth
318
+ # updatable_content: elemento da rimpiazzare con il partial restituito
319
+ # class: classi aggiuntive per selezionare meglio il bottone
320
+ # btn_class: classi aggiuntive del bottone
321
+ # bnt_icon: Symbol che identifica che icona utilizzare per il bottone
322
+ #
323
+ #
324
+ def modal_edit_button(*args, &block)
325
+
326
+ options = {
327
+ align: 'left',
328
+ updatable_content: '',
329
+ class: '',
330
+ btn_class: '',
331
+ bnt_icon: :edit
332
+ }.merge(args.extract_options!)
333
+
334
+ id = "#{SecureRandom.hex}"
335
+
336
+
337
+ content_tag :div, class: "kono_edit_button align-#{options[:align]} #{options[:class]}", :data => {updatable_content: options[:updatable_content]} do
338
+ buffer = ActiveSupport::SafeBuffer.new
339
+
340
+ buffer << button_tag(data: {toggle: 'modal', target: "##{id}"}, class: "btn btn-default btn-xs #{options[:btn_class]}") { fa_icon(options[:bnt_icon]) }
341
+
342
+ buffer << capture do
343
+ block.call(id)
344
+ end
345
+
346
+ buffer
347
+ end
348
+ end
349
+
350
+
351
+ ##
352
+ # Genera il bottone per la cancellazione di un elemento
353
+ #
354
+ # modal_delete_button(path, [options])
355
+ # path -> resource to delete
356
+ # options:
357
+ # * confirm : Text to display in modal
358
+ # * align : left|right
359
+ # * callback_remove : id dell'elemento da rimuove una volta avuto successo il javascript di cancellazione
360
+ # * bnt_icon : Symbol che identifica che icona utilizzare per il bottone
361
+ def modal_delete_button(*args)
362
+ options = {
363
+ confirm: 'Sicuri di voler eliminare il record? L\'azione non è annullabile.',
364
+ align: 'left',
365
+ callback_remove: nil,
366
+ bnt_icon: :times
367
+ }.merge(args.extract_options!)
368
+ path = args[0]
369
+
370
+ id = "#{SecureRandom.hex}"
371
+
372
+ content_tag :div, class: "tk_delete_button align-#{options[:align]}" do
373
+
374
+ buffer = ActiveSupport::SafeBuffer.new
375
+
376
+ buffer<<button_tag(data: {toggle: 'modal', target: "##{id}"}, class: 'btn btn-danger btn-xs') { fa_icon(options[:bnt_icon]) }
377
+
378
+ buffer<< content_tag(:div,
379
+ class: 'modal fade',
380
+ id: id,
381
+ tabindex: "-1",
382
+ role: "dialog",
383
+ "aria-hidden".to_sym => "true") do
384
+ form_tag(path, method: :delete, data: {callback_remove: options[:callback_remove]}) do
385
+ content_tag :div, class: 'modal-dialog' do
386
+ content_tag :div, class: 'modal-content' do
387
+
388
+ buff = ActiveSupport::SafeBuffer.new
389
+
390
+ buff << content_tag(:div, class: 'modal-header') do
391
+ tmp_buff = ActiveSupport::SafeBuffer.new
392
+ tmp_buff<<button_tag(fa_icon(:times), type: "button", class: "close", data: {dismiss: "modal"}, "aria-hidden".to_sym => true)
393
+ tmp_buff<<content_tag(:h4, "Attenzione", class: "modal-title")
394
+ tmp_buff
395
+ end
396
+
397
+ buff << content_tag(:div, options[:confirm], class: 'modal-body text-danger')
398
+
399
+ buff << content_tag(:div, class: 'modal-footer') do
400
+ button_tag('Annulla', type: "button", class: "btn btn-default", data: {dismiss: "modal"})+
401
+ button_tag('Conferma', type: 'submit', class: "btn btn-danger")
402
+ end
403
+
404
+ buff
405
+ end
406
+
407
+ end
408
+ end
409
+ end
410
+
411
+ buffer << content_tag(:script, raw("$('##{id} form').kono_delete_button();"), :type => 'text/javascript')
412
+
413
+ buffer
414
+ end
415
+ end
416
+
417
+ ##
418
+ # Colleziona i mesi per la select box
419
+ def month_collection
420
+ (1..12).collect { |m| [t('date.month_names')[m].capitalize, m] }
421
+ end
422
+
423
+
424
+ ##
425
+ # Genera una collection degli anni per la select box
426
+ # parte da -8 a +1
427
+ #
428
+ def year_collection(start=-8, last=1)
429
+ ((Time.now.year+start)..(Time.now.year+last)).to_a.reverse
430
+ end
431
+
432
+ module_function :year_collection
433
+
434
+
435
+ ##
436
+ # Si occupa di generare la visualizzazione dell'exception passata, con informazioni
437
+ # aggiuntive se utente è super admin
438
+ # * *Args* :
439
+ # - exception -> Exception
440
+ def bs_rescue_printer(exception)
441
+ bff = ActiveSupport::SafeBuffer.new
442
+
443
+ bff<< content_tag(:div, class: "alert alert-warning") do
444
+ button_tag(raw("&times;"), data: {dismiss: "alert", hidden: "true"}, class: 'close') +
445
+ content_tag(:strong, 'Errore') +
446
+ " Attenzione, il codice eseguito non è valido, contattare l'amministratore."
447
+ end
448
+
449
+ if @current_user.is_super_admin?
450
+
451
+ bff<<content_tag(:div, class: "panel panel-info") do
452
+ tmp = ActiveSupport::SafeBuffer.new
453
+ tmp<<content_tag(:div, class: "panel-heading") do
454
+ content_tag :h3, "Messagio di Errore: #{exception.message} "
455
+ end
456
+ tmp<<content_tag(:div, class: "panel-body") do
457
+ content_tag :pre, exception.backtrace.join("\n")
458
+ end
459
+
460
+ tmp
461
+ end
462
+ end
463
+
464
+ bff
465
+ end
466
+
467
+ ##
468
+ #
469
+ # * *Args* :
470
+ # - int -> Valore intero per definire
471
+ # - class -> optional classi aggiuntive
472
+ # * *Returns* :
473
+ # - content
474
+ #
475
+ def bs_spacer(space, classe='')
476
+ content_tag :div, nil, class: "v-spacer space-x#{space} #{classe}"
477
+ end
478
+
479
+
480
+ ##
481
+ # Costruisce una tabella con i campi utili alla creazione di elementi multipli
482
+ #
483
+ # Attributes:
484
+ # form -> la form proveniente da formtastic
485
+ # field -> il campo referente dell'associazione
486
+ # fields -> elenco di campi su cui costruire le varie colonne
487
+ # options -> Hash di opzioni:
488
+ # :disable_duplication => [false] : server per disabilitare il bottone della duplicazione
489
+ #
490
+ # se gli si passa un blocco allora possiamo elaborare la costruzione dei differenti campi in modo personale
491
+ # al blocco viene passato la classe di formtastic della form, il campo, e un blocco contenente la proc per
492
+ # elaborare i campi in modo standard
493
+ #
494
+ # multiple_elements_table(form, :campo_has_many, [:label, :string_value, :number_value]) do |field, form|
495
+ # case field
496
+ # when :string_value, :number_value
497
+ # form.input field, label: false, input_html: {:autocomplete => 'off', class: 'toggle_value'}
498
+ # else
499
+ # form.input field, label: false, input_html: {:autocomplete => 'off'}
500
+ # end
501
+ # end
502
+ #
503
+ # Traduzioni delle colonne:
504
+ #
505
+ # modello_iniziale/campo_has_many:
506
+ # campo_del_has_many
507
+ #
508
+ #
509
+ def multiple_elements_table(*params)
510
+ options = params.extract_options!
511
+
512
+ options = {:disable_duplication => false}.merge(options)
513
+
514
+ form = params[0]
515
+ field = params[1]
516
+ fields = params[2]
517
+
518
+ semantic_form_nested=[field]
519
+
520
+ #inserimento logiche per scope su elenco elementi multipli
521
+ unless options[:scope].nil?
522
+ semantic_form_nested<<options[:scope]
523
+ end
524
+
525
+ content_tag :table, class: "table table-bordered" do
526
+
527
+ b = ActiveSupport::SafeBuffer.new
528
+
529
+ b<< content_tag(:thead) do
530
+ content_tag :tr do
531
+ c = ActiveSupport::SafeBuffer.new
532
+
533
+ fields.each do |f|
534
+ ::Rails.logger.debug { form.object.class.inspect }
535
+ ::Rails.logger.debug { field }
536
+ ::Rails.logger.debug { f.inspect }
537
+ c<<content_tag(:th, form.object.class.human_attribute_name("#{field}.#{f}"),class:"multi_tab_#{f}")
538
+ end
539
+ unless options[:disable_duplication]
540
+ c<<content_tag(:td, nil)
541
+ end
542
+
543
+ c
544
+ end
545
+ end
546
+
547
+ b<<content_tag(:tbody) do
548
+ form.semantic_fields_for(*semantic_form_nested) do |measure|
549
+
550
+ default_execution = Proc.new { |field| measure.input field, :label => false }
551
+
552
+ content_tag :tr, class: "form-inline list riga_misura" do
553
+
554
+ d = ActiveSupport::SafeBuffer.new
555
+
556
+ fields.each do |f|
557
+ d<<content_tag(:td,class:"multi_tab_#{f}") do
558
+
559
+ if block_given?
560
+ yield(f, measure, default_execution)
561
+ else
562
+ default_execution.call(f)
563
+ end
564
+
565
+ end
566
+ end
567
+
568
+ unless options[:disable_duplication]
569
+ d << content_tag(:td) do
570
+
571
+ link_to "#", class: 'btn btn-xs btn-default add_one_more' do
572
+
573
+ h = ActiveSupport::SafeBuffer.new
574
+ h<< fa_icon(:plus)
575
+ h<< measure.input(:_destroy, as: :hidden)
576
+
577
+ h
578
+ end
579
+
580
+ end
581
+ end
582
+
583
+ d
584
+ end
585
+ end
586
+ end
587
+
588
+ b
589
+ end
590
+ end
591
+
592
+
593
+ ##
594
+ # Genera un'albero con bootstrap-tree
595
+ # deve ricevere un array di dati da trasformare in json.
596
+ # per come scrivere il parametro data vedi
597
+ # https://github.com/jonmiles/bootstrap-treeview
598
+ #
599
+ def bs_tree(data)
600
+
601
+ id_div = SecureRandom.hex(10)
602
+
603
+ tmp = ActiveSupport::SafeBuffer.new
604
+
605
+ tmp<< content_tag(:div, nil, id: id_div, class: 'bs_tree_list')
606
+
607
+ tmp<< javascript_tag do
608
+ raw "$('##{id_div}').treeview({data: #{data.to_json}});"
609
+ end
610
+
611
+ end
612
+
613
+ ##
614
+ # Stampa una data con il default delle date se questa non è nil
615
+ #
616
+ def print_rescue_date(date)
617
+ unless date.nil?
618
+ return l date.to_date
619
+ end
620
+ ''
621
+ end
622
+
623
+
624
+ end
625
+ end