kono_utils 0.15.5

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