symphonia 2.1.7

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 (188) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +674 -0
  3. data/README.md +16 -0
  4. data/Rakefile +44 -0
  5. data/app/assets/images/bg-checker.png +0 -0
  6. data/app/assets/images/bullet.gif +0 -0
  7. data/app/assets/images/close.png +0 -0
  8. data/app/assets/images/loading.gif +0 -0
  9. data/app/assets/images/next.png +0 -0
  10. data/app/assets/images/prev.png +0 -0
  11. data/app/assets/javascripts/ckeditor/plugins/autogrow/plugin.js +232 -0
  12. data/app/assets/javascripts/ckeditor/plugins/autogrow/samples/autogrow.html +102 -0
  13. data/app/assets/javascripts/ckeditor/plugins/image_chooser/icons/addimage.png +0 -0
  14. data/app/assets/javascripts/ckeditor/plugins/image_chooser/plugin.js +15 -0
  15. data/app/assets/javascripts/symphonia/Sortable.js +1249 -0
  16. data/app/assets/javascripts/symphonia/_core.js +45 -0
  17. data/app/assets/javascripts/symphonia/application.js.erb +147 -0
  18. data/app/assets/javascripts/symphonia/filters.js +44 -0
  19. data/app/assets/javascripts/symphonia/symphonia_bootstrap_dialog.js +136 -0
  20. data/app/assets/javascripts/symphonia/symphonia_ckeditor.js +55 -0
  21. data/app/assets/stylesheets/symphonia/application.css +4 -0
  22. data/app/assets/stylesheets/symphonia/basic.scss +218 -0
  23. data/app/assets/stylesheets/symphonia/filters.scss +19 -0
  24. data/app/assets/stylesheets/symphonia/symphonia_bootstrap.scss +56 -0
  25. data/app/channels/application_cable/channel.rb +5 -0
  26. data/app/controllers/symphonia/accounts_controller.rb +169 -0
  27. data/app/controllers/symphonia/admin_controller.rb +22 -0
  28. data/app/controllers/symphonia/api_controller.rb +64 -0
  29. data/app/controllers/symphonia/application_controller.rb +8 -0
  30. data/app/controllers/symphonia/attachments_controller.rb +37 -0
  31. data/app/controllers/symphonia/filters_controller.rb +23 -0
  32. data/app/controllers/symphonia/images_controller.rb +16 -0
  33. data/app/controllers/symphonia/login_controller.rb +80 -0
  34. data/app/controllers/symphonia/roles_controller.rb +100 -0
  35. data/app/controllers/symphonia/user_sessions_controller.rb +16 -0
  36. data/app/controllers/symphonia/users_controller.rb +168 -0
  37. data/app/helpers/symphonia/application_helper.rb +422 -0
  38. data/app/helpers/symphonia/bootstrap_modal_helper.rb +59 -0
  39. data/app/helpers/symphonia/form_helper.rb +50 -0
  40. data/app/helpers/symphonia/renderer_helper.rb +85 -0
  41. data/app/mailers/symphonia/application_mailer.rb +6 -0
  42. data/app/mailers/symphonia/notifier.rb +42 -0
  43. data/app/models/symphonia/admin_module.rb +18 -0
  44. data/app/models/symphonia/application_record.rb +14 -0
  45. data/app/models/symphonia/attachment.rb +16 -0
  46. data/app/models/symphonia/common_file.rb +9 -0
  47. data/app/models/symphonia/email_preference.rb +5 -0
  48. data/app/models/symphonia/image.rb +46 -0
  49. data/app/models/symphonia/preference.rb +12 -0
  50. data/app/models/symphonia/role.rb +55 -0
  51. data/app/models/symphonia/swagger/error_model.rb +19 -0
  52. data/app/models/symphonia/swagger/responses.rb +27 -0
  53. data/app/models/symphonia/user.rb +141 -0
  54. data/app/models/symphonia/user_session.rb +19 -0
  55. data/app/views/common/403.html.erb +5 -0
  56. data/app/views/common/404.html.erb +2 -0
  57. data/app/views/layouts/symphonia/_modal.html.erb +19 -0
  58. data/app/views/layouts/symphonia/_query.html.erb +51 -0
  59. data/app/views/layouts/symphonia/application.html.erb +45 -0
  60. data/app/views/layouts/symphonia/application.pdf.erb +15 -0
  61. data/app/views/layouts/symphonia/mailer.html.erb +13 -0
  62. data/app/views/symphonia/accounts/_detail.html.erb +65 -0
  63. data/app/views/symphonia/accounts/_form.html.erb +14 -0
  64. data/app/views/symphonia/accounts/edit.html.erb +9 -0
  65. data/app/views/symphonia/accounts/edit.js.erb +5 -0
  66. data/app/views/symphonia/accounts/lost_password.html.erb +6 -0
  67. data/app/views/symphonia/accounts/lost_password.js.erb +3 -0
  68. data/app/views/symphonia/accounts/new_activation.html.erb +11 -0
  69. data/app/views/symphonia/accounts/new_activation.js.erb +6 -0
  70. data/app/views/symphonia/accounts/register.html.erb +20 -0
  71. data/app/views/symphonia/accounts/reset_password.html.erb +18 -0
  72. data/app/views/symphonia/accounts/update.js.erb +1 -0
  73. data/app/views/symphonia/admin/index.html.erb +15 -0
  74. data/app/views/symphonia/attachments/destroy.js.erb +1 -0
  75. data/app/views/symphonia/common/_editable_images_grid.html.erb +12 -0
  76. data/app/views/symphonia/common/_filters.html.erb +23 -0
  77. data/app/views/symphonia/common/_locale_chooser.html.erb +16 -0
  78. data/app/views/symphonia/common/_share_links.html.erb +5 -0
  79. data/app/views/symphonia/filters/options.html.erb +36 -0
  80. data/app/views/symphonia/filters/options.js.erb +9 -0
  81. data/app/views/symphonia/filters/table.html.erb +21 -0
  82. data/app/views/symphonia/login/_form.html.erb +19 -0
  83. data/app/views/symphonia/login/new.html.erb +11 -0
  84. data/app/views/symphonia/login_sessions/new.html.erb +1 -0
  85. data/app/views/symphonia/notifier/activation_user.html.erb +7 -0
  86. data/app/views/symphonia/notifier/activation_user.text.erb +3 -0
  87. data/app/views/symphonia/notifier/reset_password_user.html.erb +7 -0
  88. data/app/views/symphonia/notifier/reset_password_user.text.erb +3 -0
  89. data/app/views/symphonia/notifier/test_mail.html.erb +2 -0
  90. data/app/views/symphonia/notifier/test_mail.text.erb +3 -0
  91. data/app/views/symphonia/notifier/user_change_to_active.html.erb +3 -0
  92. data/app/views/symphonia/notifier/user_change_to_active.text.erb +1 -0
  93. data/app/views/symphonia/notifier/user_registered.html.erb +13 -0
  94. data/app/views/symphonia/notifier/user_registered.text.erb +8 -0
  95. data/app/views/symphonia/roles/_form.html.erb +30 -0
  96. data/app/views/symphonia/roles/edit.html.erb +5 -0
  97. data/app/views/symphonia/roles/index.html.erb +6 -0
  98. data/app/views/symphonia/roles/new.html.erb +4 -0
  99. data/app/views/symphonia/roles/show.html.erb +5 -0
  100. data/app/views/symphonia/users/_form.html.erb +13 -0
  101. data/app/views/symphonia/users/edit.html.erb +26 -0
  102. data/app/views/symphonia/users/edit.js.erb +3 -0
  103. data/app/views/symphonia/users/edit_current.html.erb +7 -0
  104. data/app/views/symphonia/users/index.html.erb +5 -0
  105. data/app/views/symphonia/users/new.html.erb +8 -0
  106. data/app/views/symphonia/users/show.html.erb +63 -0
  107. data/config/locales/cs.yml +233 -0
  108. data/config/locales/en.yml +47 -0
  109. data/config/routes.rb +52 -0
  110. data/db/migrate/20130714140500_create_users.rb +49 -0
  111. data/db/migrate/20130714140501_create_roles.rb +16 -0
  112. data/db/migrate/20130714140502_create_preferences.rb +26 -0
  113. data/db/migrate/20130828175114_create_attachments.rb +20 -0
  114. data/db/migrate/20141213204351_create_admin_modules.rb +20 -0
  115. data/db/seeds.rb +12 -0
  116. data/lib/generators/symphonia/entity_controller/entity_controller_generator.rb +48 -0
  117. data/lib/generators/symphonia/entity_controller/templates/controller.rb +100 -0
  118. data/lib/generators/symphonia/query/query_generator.rb +37 -0
  119. data/lib/generators/symphonia/setup/setup_generator.rb +52 -0
  120. data/lib/generators/symphonia/setup/templates/404.html +26 -0
  121. data/lib/generators/symphonia/setup/templates/500.html +37 -0
  122. data/lib/generators/symphonia/setup/templates/Gemfile +18 -0
  123. data/lib/generators/symphonia/setup/templates/base_layout.html.erb +46 -0
  124. data/lib/generators/symphonia/setup/templates/design.scss +4 -0
  125. data/lib/generators/symphonia/setup/templates/settings.rb +65 -0
  126. data/lib/generators/symphonia/setup/templates/spec_helper.rb +18 -0
  127. data/lib/symphonia/action_cable/connection.rb +31 -0
  128. data/lib/symphonia/admin_constraint.rb +9 -0
  129. data/lib/symphonia/attachable.rb +35 -0
  130. data/lib/symphonia/base_controller.rb +96 -0
  131. data/lib/symphonia/bootstrap_link_render.rb +69 -0
  132. data/lib/symphonia/controller_extensions.rb +200 -0
  133. data/lib/symphonia/engine.rb +137 -0
  134. data/lib/symphonia/form_builder.rb +137 -0
  135. data/lib/symphonia/menu_manager.rb +23 -0
  136. data/lib/symphonia/model_attributes/attribute.rb +137 -0
  137. data/lib/symphonia/model_attributes.rb +102 -0
  138. data/lib/symphonia/model_filters/base.rb +82 -0
  139. data/lib/symphonia/model_filters/boolean_filter.rb +26 -0
  140. data/lib/symphonia/model_filters/date_filter.rb +81 -0
  141. data/lib/symphonia/model_filters/integer_filter.rb +18 -0
  142. data/lib/symphonia/model_filters/select_filter.rb +48 -0
  143. data/lib/symphonia/model_filters/string_filter.rb +18 -0
  144. data/lib/symphonia/model_filters.rb +10 -0
  145. data/lib/symphonia/object.rb +31 -0
  146. data/lib/symphonia/permissions.rb +93 -0
  147. data/lib/symphonia/query.rb +275 -0
  148. data/lib/symphonia/query_columns/attribute_column.rb +43 -0
  149. data/lib/symphonia/query_columns/generic_column.rb +165 -0
  150. data/lib/symphonia/query_columns.rb +8 -0
  151. data/lib/symphonia/spec_helper.rb +4 -0
  152. data/lib/symphonia/user_management.rb +58 -0
  153. data/lib/symphonia/version.rb +4 -0
  154. data/lib/symphonia.rb +20 -0
  155. data/spec/controllers/account_controller_spec.rb +90 -0
  156. data/spec/controllers/admin_controller_spec.rb +35 -0
  157. data/spec/controllers/api_controller_spec.rb +9 -0
  158. data/spec/controllers/filters_controller_spec.rb +35 -0
  159. data/spec/controllers/images_controller_spec.rb +5 -0
  160. data/spec/controllers/login_controller_spec.rb +20 -0
  161. data/spec/controllers/roles_controller_spec.rb +12 -0
  162. data/spec/controllers/users_controller_spec.rb +47 -0
  163. data/spec/factories/factories.rb +52 -0
  164. data/spec/helpers/symphonia/application_helper_spec.rb +62 -0
  165. data/spec/mailers/previews/symphonia/notifier_preview.rb +27 -0
  166. data/spec/mailers/symphonia/notifier_spec.rb +76 -0
  167. data/spec/models/attachment_spec.rb +22 -0
  168. data/spec/models/query/attribute_spec.rb +8 -0
  169. data/spec/models/query/symphonia_query_spec.rb +70 -0
  170. data/spec/models/role_spec.rb +13 -0
  171. data/spec/models/user_spec.rb +10 -0
  172. data/spec/rails_helper.rb +13 -0
  173. data/spec/requests/accounts_spec.rb +118 -0
  174. data/spec/requests/attachments_controller_spec.rb +23 -0
  175. data/spec/requests/login_spec.rb +26 -0
  176. data/spec/requests/roles_spec.rb +10 -0
  177. data/spec/requests/users_spec.rb +50 -0
  178. data/spec/spec_helper.rb +101 -0
  179. data/spec/support/common_file.txt +2 -0
  180. data/spec/support/query.rb +36 -0
  181. data/spec/support/shared.rb +62 -0
  182. data/spec/support/shared_controllers.rb +31 -0
  183. data/spec/support/stub_users.rb +32 -0
  184. data/spec/support/symphonia.jpg +0 -0
  185. data/spec/support/wait_for_ajax.rb +15 -0
  186. data/spec/version_spec.rb +5 -0
  187. data/spec/views/filters/options.html.erb_spec.rb +14 -0
  188. metadata +697 -0
@@ -0,0 +1,102 @@
1
+ require 'active_support/concern'
2
+ <<EXAMPLE
3
+ # user.rb
4
+ class User
5
+ include Symphonia::ModelAttributes
6
+
7
+ register_query do
8
+ add_attribute :login, :link
9
+ add_attribute :name, sort: %i[first_name last_name]
10
+ add_attribute :first_name
11
+ add_attribute :last_name
12
+ add_attribute :mail, :mail
13
+ add_attribute :status, :enum
14
+ add_attribute :role, :reference
15
+ add_attribute :admin, :boolean
16
+ add_attribute :login_count
17
+ add_attribute :last_login_ip
18
+ add_attribute :last_login_at
19
+
20
+ add_attribute :author, :reference, sort: "users.last_name"
21
+
22
+ # @param [ActiveSupport::View] view
23
+ # @param [Symphonia::ModelAttributes::Attribute] attribute
24
+ # @param [ApplicationRecord] entity
25
+ add_attribute :custom do |view, attribute, entity|
26
+ view.link_to(attribute.value(entity), entity.custom)
27
+ end
28
+ end
29
+ end
30
+ # users/show.html.erb
31
+ @user.format_value :login, self
32
+ @user.format_value :name, self
33
+ @user.format_value :role, self
34
+
35
+ EXAMPLE
36
+ require_dependency 'symphonia/model_attributes/attribute'
37
+ module Symphonia
38
+ module ModelAttributes
39
+
40
+ extend ActiveSupport::Concern
41
+
42
+ included do
43
+
44
+ mattr_accessor :registered_attributes do
45
+ {}
46
+ end
47
+ mattr_accessor :query
48
+
49
+ def format_value(name, view = nil)
50
+ value = send(name)
51
+ return value if view.nil?
52
+
53
+ f = get_attribute(name)
54
+ if f.nil?
55
+ Rails.logger.debug "Attribute '#{name}' not found in #{self.class.name}"
56
+ value
57
+ else
58
+ f.format(view, self)
59
+ end
60
+
61
+ end
62
+
63
+ def get_attribute(name)
64
+ self.class.registered_attributes[name]
65
+ end
66
+ end
67
+
68
+ class_methods do
69
+
70
+ def register_query(klass = nil, &block)
71
+ # klass ||= "Symphonia::Queries::#{self.name.demodulize}".constantize
72
+ return true unless query.nil?
73
+
74
+ klass ||= Class.new(Symphonia::Query)
75
+ klass.model = self
76
+ self.query = klass
77
+
78
+ yield klass
79
+
80
+ self.query = klass
81
+ end
82
+
83
+ def add_attribute(name, *args, &block)
84
+ options = args.extract_options!
85
+ formatter = args.shift
86
+ c = if formatter
87
+ [formatter, 'attribute'].join('_').classify
88
+ else
89
+ (columns_hash[name.to_s].try(:type).to_s + 'Attribute').classify
90
+ end
91
+ _c = ('Symphonia::ModelAttributes::' + c).safe_constantize || Symphonia::ModelAttributes::Attribute
92
+ attr = _c.new(name, self, options, block_given? ? block : formatter)
93
+ if options.has_key?(:sort)
94
+ attr.sort = options.delete(:sort)
95
+ end
96
+ attr.filter = options[:filter] || columns_hash[name.to_s].try(:type)
97
+ registered_attributes[name.to_sym] = attr
98
+ end
99
+ end
100
+ end
101
+
102
+ end
@@ -0,0 +1,82 @@
1
+ module Symphonia
2
+ module ModelFilters
3
+ class Base
4
+ attr_reader :name, :type, :caption, :options, :query, :value, :operator
5
+
6
+ # @param [Symphonia::ModelAttributes::Attribute] attribute
7
+ # @param [Symphonia::Query] query
8
+ # @param [Hash] options
9
+ def initialize(attribute, query, options = {})
10
+ if attribute.is_a? String
11
+ ActiveSupport::Deprecation.warn("name as argument is no longer supported - use Attribute")
12
+ @name = attribute
13
+ else
14
+ @name = attribute.name
15
+ @attribute = attribute
16
+ end
17
+ @options = options
18
+ @query = query
19
+ @operator = 'eq'
20
+ end
21
+
22
+ def caption
23
+ @caption = @options[:caption]
24
+ @caption ||= query.model.human_attribute_name(name)
25
+ end
26
+
27
+ def form_field(_c)
28
+ raise NotImplementError
29
+ end
30
+
31
+ def inspect
32
+ "#<#{self.class.name} name='#{name}' caption='#{caption}' options=#{@options.inspect}>"
33
+ end
34
+
35
+ def active?
36
+ !!query.active_filters[name]
37
+ end
38
+
39
+ def value=(q)
40
+ if (m = q.downcase.match(/^([!~><]+)(.*)/))
41
+ @value = m[2]
42
+ self.operator = m[1]
43
+ else
44
+ @operator ||= 'eq'
45
+ @value = q
46
+ end
47
+
48
+ @value
49
+ end
50
+
51
+ def operator=(o)
52
+ @operator = case o
53
+ when '!'
54
+ 'not_eq'
55
+ when '~'
56
+ @value = "%#{@value}%"
57
+ 'matches'
58
+ when '!~'
59
+ @value = "%#{@value}%"
60
+ 'not_matches'
61
+ when '>'
62
+ 'lt'
63
+ when '<'
64
+ 'gt'
65
+ else
66
+ 'eq'
67
+ end
68
+ end
69
+
70
+ def apply(_scope)
71
+ Rails.logger.debug("Apply filter #{name} '#{operator}' #{value}")
72
+ end
73
+
74
+ private
75
+
76
+ def form_field_name
77
+ name
78
+ end
79
+
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,26 @@
1
+ module Symphonia
2
+ module ModelFilters
3
+ class BooleanFilter < Base
4
+
5
+ def operator=(o)
6
+ if o == '!'
7
+ @operator = 'not_eq'
8
+ else
9
+ @operator = 'eq'
10
+ end
11
+ end
12
+
13
+ def apply(scope)
14
+ super
15
+ t = scope.arel_table
16
+ scope.where(t[name].send(operator, true))
17
+ end
18
+
19
+ def form_field(_c)
20
+ _c.text_field_tag(form_field_name, @query.active_filters[name], class: 'form-control')
21
+ end
22
+ end
23
+
24
+ end
25
+
26
+ end
@@ -0,0 +1,81 @@
1
+ module Symphonia
2
+ module ModelFilters
3
+ class DateFilter < Base
4
+ attr_accessor :available_values
5
+
6
+ def initialize(name, query, options={})
7
+ super
8
+ @operator = 'in'
9
+ end
10
+
11
+ def value=(q)
12
+ v = available_values.values.reduce(:merge)[q.to_sym]
13
+ @operator = 'between' unless q == 'today'
14
+ @value = if q == 'custom'
15
+ data = self.query.controller.params.require(:date_from_custom).permit(:from, :to)
16
+ v.call(data)
17
+ else
18
+ v.call
19
+ end
20
+ end
21
+
22
+ # def operator=(o)
23
+ # if o == '!'
24
+ # @operator = 'not_in'
25
+ # end
26
+ # end
27
+
28
+ def apply(scope)
29
+ super
30
+ t = scope.arel_table
31
+ scope.where(t[name].send(operator, value))
32
+ end
33
+
34
+ def available_values
35
+ {
36
+ past: {
37
+ last_month: -> {d = Date.today.last_month.beginning_of_month; d..d.end_of_month},
38
+ last_year: -> {d = Date.today.last_year.beginning_of_year; d..d.end_of_year}
39
+ },
40
+ present: {
41
+ today: -> {Date.today},
42
+ this_month: -> {Date.today.beginning_of_month..Date.today.end_of_month},
43
+ this_year: -> {Date.today.beginning_of_year..Date.today.end_of_year},
44
+ custom: ->(data) {data[:from].to_date..data[:to].to_date}
45
+ },
46
+ future: {
47
+ next_month: -> {d = Date.today.next_month.beginning_of_month; d..d.end_of_month},
48
+ next_year: -> {d = Date.today.next_year.beginning_of_year; d..d.end_of_year}
49
+ }
50
+ }
51
+ end
52
+
53
+ def form_field(_c)
54
+ groups = available_values.inject({}) do |mem, (time, values)|
55
+ mem[_c.t("time.#{time}")] = values.collect do |(k, _val)|
56
+ [_c.t("query_options.filter_date.values.#{k}"), k]
57
+ end
58
+ mem
59
+ end
60
+ selected = Array(@query.active_filters[name])
61
+ _c.content_tag(:div, class: 'row') do
62
+ _c.select_tag("#{form_field_name}", _c.grouped_options_for_select(groups, selected), {
63
+ class: 'form-control',
64
+ include_blank: true,
65
+ onchange: 'symphoniaFiltersForm.dateFilterCallback(this)'
66
+ }) + _c.content_tag(:div, class: 'filter-custom-date clearfix input-daterange input-group inline', style: 'display: none') do
67
+ _c.date_field_tag("#{form_field_name}_custom[to]", '', {
68
+ placeholder: _c.t('query_options.filter_date.to'),
69
+ class: 'form-control datepicker pull-right'
70
+ }) +
71
+ # _c.content_tag(:span, _c.t('query_options.filter_date.to'), class: 'input-group-addon')+
72
+ _c.date_field_tag("#{form_field_name}_custom[from]", '', {
73
+ placeholder: _c.t('query_options.filter_date.from'),
74
+ class: 'form-control datepicker'
75
+ })
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,18 @@
1
+ module Symphonia
2
+ module ModelFilters
3
+ class IntegerFilter < Base
4
+
5
+ def apply(scope)
6
+ super
7
+ t = scope.arel_table
8
+ scope.where(t[name].send(operator, value.to_f))
9
+ end
10
+
11
+ def form_field(_c)
12
+ _c.number_field_tag(form_field_name, @query.active_filters[name], class: 'form-control')
13
+ end
14
+ end
15
+
16
+ end
17
+
18
+ end
@@ -0,0 +1,48 @@
1
+ module Symphonia
2
+ module ModelFilters
3
+ class SelectFilter < StringFilter
4
+ attr_accessor :available_values
5
+
6
+ def initialize(name, query, options = {})
7
+ super
8
+ @operator = 'in'
9
+ end
10
+
11
+ def available_values
12
+ return @available_values.call(_c, self) if @available_values.is_a? Proc
13
+
14
+ @available_values || case @attribute
15
+ when Symphonia::ModelAttributes::EnumAttribute
16
+ @query.model.send(@attribute.name.to_s.pluralize).keys
17
+ end
18
+ end
19
+
20
+ def value=(q)
21
+ @value = Array(q)
22
+ end
23
+
24
+ def operator=(o)
25
+ if o == '!'
26
+ @operator = 'not_in'
27
+ end
28
+ end
29
+
30
+ def apply(scope)
31
+ super
32
+ t = scope.arel_table
33
+ scope.where(t[name].send(operator, value))
34
+ end
35
+
36
+ def form_field(_c)
37
+ selected = Array(@query.active_filters[name])
38
+ _c.content_tag(:div, class: 'input-group') do
39
+ _c.content_tag(:div, class: 'input-group-prepend') do
40
+ _c.content_tag(:span, _c.check_box_tag("o[#{form_field_name}]", '!', operator == 'not_in', title: 'Not In'), class: "input-group-text")
41
+ end +
42
+ _c.select_tag("#{form_field_name}[]", _c.options_for_select(available_values, selected), class: 'form-control', include_blank: true, multiple: selected.size > 1) +
43
+ _c.content_tag(:div, _c.link_to(_c.fa_icon('plus-square-o'), 'javascript:void(0)', onclick: "toggleMultiSelect($(this).closest('.input-group').find('select'))", title: I18n.t(:title_toggle_multiselect), class: "input-group-text"), class: 'input-group-append')
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,18 @@
1
+ module Symphonia
2
+ module ModelFilters
3
+ class StringFilter < Base
4
+
5
+ def apply(scope)
6
+ super
7
+ t = scope.arel_table
8
+ scope.where(t[name].lower.send(operator, Array(value).map(&:downcase)))
9
+ end
10
+
11
+ def form_field(_c)
12
+ _c.text_field_tag(form_field_name, @query.active_filters[name], class: 'form-control')
13
+ end
14
+ end
15
+
16
+ end
17
+
18
+ end
@@ -0,0 +1,10 @@
1
+ require_dependency 'symphonia/model_filters/base'
2
+ require_dependency 'symphonia/model_filters/string_filter'
3
+ require_dependency 'symphonia/model_filters/date_filter'
4
+ require_dependency 'symphonia/model_filters/boolean_filter'
5
+ require_dependency 'symphonia/model_filters/integer_filter'
6
+ require_dependency 'symphonia/model_filters/select_filter'
7
+ module Symphonia
8
+ module ModelFilters
9
+ end
10
+ end
@@ -0,0 +1,31 @@
1
+ class Object
2
+ # def to_boolean
3
+ # return true if self.is_a?(TrueClass)
4
+
5
+ # respond_to?(:downcase) && ['true', 1, '1', 'yes', 't', 'y'].include?(self.downcase)
6
+ # end
7
+ end
8
+
9
+ class String
10
+ def to_boolean
11
+ ['true', 1, '1', 'yes', 't', 'y'].include?(self.downcase)
12
+ end
13
+ end
14
+
15
+ class NilClass
16
+ def to_boolean
17
+ false
18
+ end
19
+ end
20
+
21
+ class FalseClass
22
+ def to_boolean
23
+ false
24
+ end
25
+ end
26
+
27
+ class TrueClass
28
+ def to_boolean
29
+ true
30
+ end
31
+ end
@@ -0,0 +1,93 @@
1
+ require 'rails'
2
+ module Symphonia
3
+ module Permissions
4
+ @@mapper = []
5
+ @@used_names = []
6
+ mattr_accessor :mapper, :used_names
7
+ class PermissionMissingError < RuntimeError; end
8
+ class << self
9
+
10
+ def map(&block)
11
+ if block_given?
12
+ yield self
13
+ end
14
+ end
15
+
16
+ def register(name, options={})
17
+ return if @@used_names.include?(name)
18
+
19
+ p = Permission.new(name, options)
20
+ @@used_names << p.name.to_s
21
+ mapper << p
22
+
23
+ p
24
+ end
25
+
26
+ def update(name)
27
+ self.get(name) || raise(PermissionMissingError)
28
+ end
29
+
30
+ # Returns the permission of given name or nil if it wasn't found
31
+ # Argument should be a symbol
32
+ def get(name)
33
+ mapper.detect{|i| i.name == name}
34
+ end
35
+
36
+ def all
37
+ mapper
38
+ end
39
+
40
+ def find_all(permission_names=[])
41
+ ps = used_names & Array(permission_names).compact
42
+ ps.collect{|m| get(m.to_sym)}
43
+ end
44
+
45
+ end
46
+
47
+ class Permission
48
+ attr_reader :name
49
+ # actions => [:controller_name => [:action, :action, :action]]
50
+ def initialize(name, options={})
51
+ @name = name
52
+ @perms = Hash.new { |hash, key| hash[key] = Array.new }
53
+ end
54
+ alias_method :id, :name
55
+
56
+ def to_s
57
+ @name.to_s
58
+ end
59
+
60
+ def allowed?(controller, action)
61
+ Array(@perms[controller.to_sym]).include?(action.to_sym)
62
+ end
63
+
64
+ def add(controller, actions=[])
65
+ @perms[controller] += actions
66
+ end
67
+
68
+ def remove_actions(controller, actions=[])
69
+ @perms[controller] -= actions
70
+ end
71
+
72
+ def remove_controller(controller)
73
+ @perms.delete(controller)
74
+ end
75
+
76
+ def controllers
77
+ @controllers ||= @perms.keys
78
+ end
79
+
80
+ def allow_action?(controller, action)
81
+ controller = controller.to_sym
82
+ action = action.to_sym
83
+
84
+ if self.controllers.include?(controller)
85
+ return @perms[controller].include?(action)
86
+ else
87
+ return false
88
+ end
89
+ end
90
+ end
91
+ end
92
+
93
+ end