voluntary 0.1.0 → 0.2.0

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 (136) hide show
  1. data/app/assets/javascripts/voluntary/application.js +1 -1
  2. data/app/assets/javascripts/voluntary/base.js.coffee +30 -1
  3. data/app/assets/stylesheets/voluntary/application.css +1 -0
  4. data/app/assets/stylesheets/voluntary/base.css.sass +1 -1
  5. data/app/controllers/areas_controller.rb +6 -5
  6. data/app/controllers/candidatures_controller.rb +15 -10
  7. data/app/controllers/concerns/voluntary/v1/base_controller.rb +95 -0
  8. data/app/controllers/devise_extensions/registrations_controller.rb +2 -2
  9. data/app/controllers/organizations_controller.rb +7 -6
  10. data/app/controllers/professions_controller.rb +6 -5
  11. data/app/controllers/projects_controller.rb +11 -6
  12. data/app/controllers/users_controller.rb +2 -2
  13. data/app/controllers/vacancies_controller.rb +14 -5
  14. data/app/controllers/voluntary/api/v1/api_controller.rb +9 -0
  15. data/app/controllers/voluntary/application_controller.rb +2 -66
  16. data/app/controllers/workflow/candidatures_controller.rb +1 -1
  17. data/app/controllers/workflow/products_controller.rb +7 -7
  18. data/app/controllers/workflow/stories_controller.rb +1 -1
  19. data/app/controllers/workflow/tasks_controller.rb +2 -2
  20. data/app/controllers/workflow/user/product/areas_controller.rb +2 -2
  21. data/app/controllers/workflow/user/projects_controller.rb +10 -2
  22. data/app/helpers/voluntary/application_helper.rb +79 -0
  23. data/app/helpers/voluntary/collection_helper.rb +45 -0
  24. data/app/helpers/voluntary/comments_helper.rb +13 -0
  25. data/app/helpers/voluntary/form_helper.rb +46 -0
  26. data/app/helpers/voluntary/language_helper.rb +17 -0
  27. data/app/helpers/voluntary/layout_helper.rb +42 -0
  28. data/app/helpers/voluntary/product_helper.rb +36 -0
  29. data/app/helpers/voluntary/show_helper.rb +67 -0
  30. data/app/helpers/voluntary/wizard_helper.rb +29 -0
  31. data/app/models/ability.rb +20 -4
  32. data/app/models/candidature.rb +10 -7
  33. data/app/models/column.rb +1 -0
  34. data/app/models/concerns/user/extensions.rb +5 -0
  35. data/app/models/concerns/user/listable.rb +10 -0
  36. data/app/models/list.rb +30 -0
  37. data/app/models/list_item.rb +22 -0
  38. data/app/models/organization.rb +1 -0
  39. data/app/models/page.rb +2 -1
  40. data/app/models/product.rb +3 -2
  41. data/app/models/project.rb +2 -2
  42. data/app/models/result.rb +1 -0
  43. data/app/models/role.rb +1 -1
  44. data/app/models/state_machines/candidature.rb +17 -1
  45. data/app/models/state_machines/story.rb +15 -2
  46. data/app/models/state_machines/task.rb +33 -0
  47. data/app/models/story.rb +3 -2
  48. data/app/models/task.rb +44 -6
  49. data/app/models/thing.rb +3 -0
  50. data/app/models/user.rb +15 -4
  51. data/app/models/vacancy.rb +7 -5
  52. data/app/presenters/resources/general/wizards/story/steps/setup_tasks_presenter.rb +1 -1
  53. data/app/presenters/shared/collection/table_presenter.rb +1 -1
  54. data/app/views/candidatures/index.html.erb +1 -1
  55. data/app/views/candidatures/show.html.erb +1 -1
  56. data/app/views/columns/_collection.html.erb +0 -0
  57. data/app/views/comments/_resource.html.erb +1 -1
  58. data/app/views/layouts/application.html.erb +12 -0
  59. data/app/views/layouts/shared/_navigation.html.erb +3 -3
  60. data/app/views/organizations/show.html.erb +0 -1
  61. data/app/views/products/index.html.erb +53 -4
  62. data/app/views/projects/_form.html.erb +1 -0
  63. data/app/views/projects/show.html.erb +2 -1
  64. data/app/views/shared/collection/_list.html.erb +1 -1
  65. data/app/views/shared/resource/_actions.html.erb +2 -2
  66. data/app/views/stories/_column_fields.html.erb +0 -0
  67. data/app/views/stories/_form.html.erb +1 -1
  68. data/app/views/stories/steps/_activate.html.erb +1 -1
  69. data/app/views/workflow/products/show.html.erb +1 -1
  70. data/app/views/workflow/project_owner/_candidatures.html.erb +2 -1
  71. data/app/views/workflow/tasks/_work_head.html.erb +1 -1
  72. data/app/views/workflow/tasks/steps/_complete.html.erb +6 -2
  73. data/app/views/workflow/tasks/steps/_review.html.erb +6 -2
  74. data/app/views/workflow/tasks/steps/_work.html.erb +4 -2
  75. data/app/views/workflow/user/product/areas/show.html.erb +0 -0
  76. data/app/views/workflow/user/projects/show.html.erb +0 -0
  77. data/config/initializers/devise.rb +2 -5
  78. data/config/initializers/filter_parameters_logging.rb +1 -0
  79. data/config/initializers/friendly_id.rb +88 -0
  80. data/config/initializers/wrap_parameters.rb +15 -0
  81. data/config/locales/general/en.yml +15 -9
  82. data/config/locales/resources/story/en.yml +1 -0
  83. data/config/routes.rb +9 -0
  84. data/config/routes/workflow.rb +15 -15
  85. data/db/migrate/20120907144853_create_schema.rb +1 -1
  86. data/db/migrate/20120922201955_create_mongo_db_documents.rb +1 -1
  87. data/db/migrate/20121004132105_create_professions.rb +1 -1
  88. data/db/migrate/20121006162913_add_public_attribute_to_roles.rb +20 -1
  89. data/db/migrate/20130817090734_create_lists.rb +33 -0
  90. data/db/migrate/20131018143613_replace_user_by_polymorphic_resource_in_candidatures.rb +46 -0
  91. data/db/migrate/20140307113214_add_user_id_to_organizations.rb +5 -0
  92. data/lib/api_constraints.rb +10 -0
  93. data/lib/applicat/mvc/model/tree.rb +1 -1
  94. data/lib/concerns/model/base_list_item.rb +30 -0
  95. data/lib/concerns/model/base_thing.rb +50 -0
  96. data/lib/db_seed.rb +15 -4
  97. data/lib/generators/voluntary/install/install_generator.rb +17 -16
  98. data/lib/generators/voluntary/install/templates/app/views/layouts/application.html.erb +17 -1
  99. data/lib/generators/voluntary/install/templates/config/main_navigation.rb +1 -260
  100. data/lib/generators/voluntary/install/templates/features/support/integration_sessions_controller.rb +1 -2
  101. data/lib/generators/voluntary/install/templates/spec/factories.rb +19 -0
  102. data/lib/generators/voluntary/install/templates/spec/support/mongo_database_cleaner.rb +14 -4
  103. data/lib/generators/voluntary/product_dummy/product_dummy_generator.rb +23 -17
  104. data/lib/generators/voluntary/product_dummy/templates/config/database.example.yml +1 -1
  105. data/lib/generators/voluntary/product_dummy/templates/dummy/spec/factories.rb +19 -0
  106. data/lib/generators/voluntary/product_dummy/templates/dummy/spec/spec_helper.rb +75 -0
  107. data/lib/generators/voluntary/product_dummy/templates/features/support/integration_sessions_controller.rb +1 -2
  108. data/lib/generators/voluntary/product_dummy/templates/spec/factories.rb +19 -0
  109. data/lib/voluntary.rb +10 -22
  110. data/lib/voluntary/engine.rb +27 -3
  111. data/lib/voluntary/navigation.rb +358 -0
  112. data/lib/voluntary/test/rspec_helpers/factories.rb +123 -0
  113. data/lib/voluntary/version.rb +1 -1
  114. data/vendor_extensions/active_model/naming.rb +1 -1
  115. metadata +526 -308
  116. data/app/helpers/application_helper.rb +0 -65
  117. data/app/helpers/collection_helper.rb +0 -35
  118. data/app/helpers/comments_helper.rb +0 -11
  119. data/app/helpers/form_helper.rb +0 -43
  120. data/app/helpers/language_helper.rb +0 -15
  121. data/app/helpers/layout_helper.rb +0 -39
  122. data/app/helpers/product_helper.rb +0 -34
  123. data/app/helpers/show_helper.rb +0 -65
  124. data/app/helpers/wizard_helper.rb +0 -27
  125. data/app/observers/candidature_observer.rb +0 -29
  126. data/app/observers/story_observer.rb +0 -6
  127. data/app/observers/task_observer.rb +0 -34
  128. data/lib/voluntary/helpers/application.rb +0 -69
  129. data/lib/voluntary/helpers/collection.rb +0 -35
  130. data/lib/voluntary/helpers/comments.rb +0 -15
  131. data/lib/voluntary/helpers/form.rb +0 -43
  132. data/lib/voluntary/helpers/language.rb +0 -19
  133. data/lib/voluntary/helpers/layout.rb +0 -28
  134. data/lib/voluntary/helpers/product.rb +0 -36
  135. data/lib/voluntary/helpers/show.rb +0 -69
  136. data/lib/voluntary/helpers/wizard.rb +0 -31
@@ -46,7 +46,7 @@ class UsersController < ApplicationController
46
46
  private
47
47
 
48
48
  def find_resource
49
- @user = User.find(params[:id])
49
+ @user = User.friendly.find(params[:id])
50
50
  @presenter = Resources::User::FormPresenter.new(self.view_context, resource: resource)
51
51
  end
52
- end
52
+ end
@@ -1,6 +1,8 @@
1
1
  class VacanciesController < ApplicationController
2
2
  include Applicat::Mvc::Controller::Resource
3
3
 
4
+ before_filter :find_vacancy
5
+
4
6
  load_and_authorize_resource
5
7
 
6
8
  before_filter :find_project, only: [:index, :new, :edit]
@@ -12,7 +14,6 @@ class VacanciesController < ApplicationController
12
14
  end
13
15
 
14
16
  def show
15
- @vacancy = Vacancy.includes(:project, :candidatures, :comments).find(params[:id])
16
17
  @comments = @vacancy.comments
17
18
  end
18
19
 
@@ -40,11 +41,11 @@ class VacanciesController < ApplicationController
40
41
  end
41
42
 
42
43
  def edit
43
- @vacancy = Vacancy.find(params[:id])
44
+ @vacancy = Vacancy.friendly.find(params[:id])
44
45
  end
45
46
 
46
47
  def update
47
- @vacancy = Vacancy.find(params[:id])
48
+ @vacancy = Vacancy.friendly.find(params[:id])
48
49
 
49
50
  if @vacancy.update_attributes(params[:vacancy])
50
51
  redirect_to @vacancy, notice: t('general.form.successfully_updated')
@@ -54,7 +55,7 @@ class VacanciesController < ApplicationController
54
55
  end
55
56
 
56
57
  def destroy
57
- @vacancy = Vacancy.find(params[:id])
58
+ @vacancy = Vacancy.friendly.find(params[:id])
58
59
  @vacancy.destroy
59
60
  redirect_to vacancies_url, notice: t('general.form.destroyed')
60
61
  end
@@ -73,7 +74,15 @@ class VacanciesController < ApplicationController
73
74
 
74
75
  private
75
76
 
77
+ def find_vacancy
78
+ return unless params[:id].present?
79
+
80
+ @vacancy = Vacancy
81
+ @vacancy = @vacancy.includes(:project, :candidatures, :comments) if action_name == 'show'
82
+ @vacancy = @vacancy.friendly.find(params[:id])
83
+ end
84
+
76
85
  def find_project
77
- @project = params[:project_id].present? ? Project.find(params[:project_id]) : nil
86
+ @project = params[:project_id].present? ? Project.friendly.find(params[:project_id]) : nil
78
87
  end
79
88
  end
@@ -0,0 +1,9 @@
1
+ module Voluntary
2
+ module Api
3
+ module V1
4
+ class BaseController < ActionController::API
5
+ include Voluntary::V1::BaseController
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1,5 +1,6 @@
1
1
  class Voluntary::ApplicationController < ActionController::Base
2
2
  include Applicat::Mvc::Controller
3
+ include Voluntary::V1::BaseController
3
4
 
4
5
  protect_from_forgery
5
6
 
@@ -7,24 +8,10 @@ class Voluntary::ApplicationController < ActionController::Base
7
8
 
8
9
  layout Proc.new { |controller| controller.request.xhr? ? 'facebox' : 'application' }
9
10
 
10
- rescue_from CanCan::AccessDenied, with: :access_denied
11
- rescue_from ActiveRecord::RecordNotFound, with: :not_found
12
- rescue_from Mongoid::Errors::DocumentNotFound, with: :not_found
13
-
14
11
  respond_to :html, :js, :json
15
12
 
16
- def parent
17
- @parent
18
- end
19
-
20
- helper_method :parent
21
-
22
13
  protected
23
-
24
- def current_ability
25
- Ability.new(current_user, controller_namespace: current_namespace)
26
- end
27
-
14
+
28
15
  def after_sign_in_path_for(resource_or_scope)
29
16
  if resource_or_scope.main_role.is_a? Role::ProjectOwner
30
17
  workflow_project_owner_index_path
@@ -39,58 +26,7 @@ class Voluntary::ApplicationController < ActionController::Base
39
26
  @twitter_sidenav_level = 3
40
27
  end
41
28
 
42
- def find_parent(types, parent_key = nil)
43
- parent_type, id = nil, nil
44
-
45
- if parent_type = types.select{|p| params.keys.include?("#{p}_id") }.first
46
- id = params["#{parent_type}_id"]
47
- elsif parent_type = types.select{|p| params[parent_key] && params[parent_key].keys.include?("#{p}_id") }.first
48
- id = params[parent_key]["#{parent_type}_id"]
49
- end
50
-
51
- return if parent_type.blank?
52
-
53
- parent = parent_type.classify.constantize.find(id)
54
- root_model_class_name = Voluntary::Helpers::Application.root_model_class_name_helper(parent)
55
- eval("@#{root_model_class_name.tableize.singularize} = parent")
56
-
57
- parent
58
- end
59
-
60
29
  def response_with_standard(format = nil, error = nil)
61
30
  render status: error ? 500 : 200, json: { success: error ? false : true, error: error} and return true
62
31
  end
63
-
64
- private
65
-
66
- def current_namespace
67
- controller_name_segments = params[:controller].split('/')
68
- controller_name_segments.pop
69
- controller_namespace = controller_name_segments.join('/').downcase
70
- end
71
-
72
- def access_denied
73
- message = I18n.t('general.exceptions.access_denied')
74
-
75
- if request.format.try('json?')
76
- render status: 403, json: { error: message } and return
77
- else
78
- flash[:alert] = message
79
-
80
- if request.env["HTTP_REFERER"]
81
- redirect_to :back
82
- else
83
- redirect_to root_path
84
- end
85
- end
86
- end
87
-
88
- def not_found(e)
89
- if Rails.env.development?
90
- raise e
91
- else
92
- logger.info "not found (#{e.inspect})"
93
- redirect_to root_path, notice: t('general.exceptions.not_found')
94
- end
95
- end
96
32
  end
@@ -14,7 +14,7 @@ class Workflow::CandidaturesController < ApplicationController
14
14
  private
15
15
 
16
16
  def state_action
17
- @candidatures = current_user.offeror_candidatures.where(state: action_name).includes(:vacancy, :user)
17
+ @candidatures = current_user.offeror_candidatures.where(state: action_name).includes(:vacancy, :resource)
18
18
  render 'candidatures/index'
19
19
  end
20
20
  end
@@ -1,7 +1,7 @@
1
- class Workflow::ProductsController < ApplicationController
2
- def show
3
- @stories = Product.stories(params[:id], current_user)
4
- @areas = Area.find_by_product_id(params[:id])
5
- @product = Product.find(params[:id]) unless params[:id] == 'no-name'
6
- end
7
- end
1
+ class Workflow::ProductsController < ApplicationController
2
+ def show
3
+ @stories = Product.stories(params[:id], current_user)
4
+ @areas = Area.find_by_product_id(params[:id])
5
+ @product = Product.find(params[:id]) unless params[:id] == 'no-name'
6
+ end
7
+ end
@@ -1,6 +1,6 @@
1
1
  class Workflow::StoriesController < ApplicationController
2
2
  def index
3
- @product = Product.find(params[:product_id])
3
+ @product = Product.friendly.find(params[:product_id])
4
4
  @stories = @product.stories
5
5
  end
6
6
  end
@@ -78,7 +78,7 @@ class Workflow::TasksController < ApplicationController
78
78
  method = params[:event] ? params[:event].keys.first : 'save'
79
79
  success = false
80
80
 
81
- if @result.valid?
81
+ if (@task.with_result? && @result.valid?) || (!@task.with_result? && @task.valid?)
82
82
  success = if params[:next_step] == '1' || (params[:event] && params[:event][:next])
83
83
  @task.send(step)
84
84
  elsif (method == 'save' && can?(:update, @task)) || can?(method.to_sym, @task)
@@ -90,7 +90,7 @@ class Workflow::TasksController < ApplicationController
90
90
 
91
91
  render 'edit' and return unless success
92
92
 
93
- @result.save
93
+ @result.save if @task.with_result?
94
94
 
95
95
  if params[:event] && params[:event][:next]
96
96
  redirect_to(
@@ -1,8 +1,8 @@
1
1
  class Workflow::User::Product::AreasController < ApplicationController
2
2
  def show
3
- @area = Area.find(params[:id])
3
+ @area = Area.friendly.find(params[:id])
4
4
  @areas = @area.children_for_product_id(params[:product_id])
5
5
  @projects = @area.projects.for_product_id(params[:product_id])
6
- @product = Product.find(params[:product_id]) unless params[:product_id] == 'no-name'
6
+ @product = ::Product.find(params[:product_id]) unless params[:product_id] == 'no-name'
7
7
  end
8
8
  end
@@ -1,8 +1,16 @@
1
1
  class Workflow::User::ProjectsController < ApplicationController
2
2
  def show
3
- @project = Project.find(params[:id])
3
+ @project = Project.friendly.find(params[:id])
4
4
 
5
- @stories = @project.product.stories_for_user(current_user).
5
+ product = if @project.product
6
+ @project.product
7
+ else
8
+ value = ::Product.new
9
+ value.id = 'no-name'
10
+ value
11
+ end
12
+
13
+ @stories = product.stories_for_user(current_user).
6
14
  where(project_id: @project.try(:id)).paginate(page: params[:page])
7
15
  end
8
16
  end
@@ -0,0 +1,79 @@
1
+ module Voluntary
2
+ module ApplicationHelper
3
+ include AutoHtml
4
+
5
+ def self.root_model_class_name_helper(resource)
6
+ if resource.class.superclass.name == 'ActiveRecord::Base'
7
+ resource.class.name
8
+ elsif resource.class.superclass.name == 'Object'
9
+ # classes like mongo db models without a specific superclass
10
+ resource.class.name
11
+ else
12
+ resource.class.superclass.name
13
+ end
14
+ end
15
+
16
+ def markdown(text)
17
+ text = Redcarpet::Markdown.new(Redcarpet::Render::XHTML.new(filter_html: true)).render(text)
18
+
19
+ auto_html(text) do
20
+ youtube(width: 515, height: 300)
21
+ dailymotion(width: 515, height: 300)
22
+ vimeo(width: 515, height: 300)
23
+ google_video(width: 515, height: 300)
24
+ image
25
+
26
+ redcarpet(
27
+ renderer: Redcarpet::Render::XHTML.new(
28
+ no_images: true, no_styles: true, hard_wrap: true, with_toc_data: true
29
+ ),
30
+ markdown_options: { no_intra_emphasis: true, autolink: true, fenced_code_blocks: true }
31
+ )
32
+ link :target => "_blank", :rel => "nofollow"
33
+ end.gsub(/(>https?:\/\/[^\<\\]+)/) do |match|
34
+ truncate(match)
35
+ end.html_safe
36
+ end
37
+
38
+ def root_model_class_name(resource)
39
+ ::Voluntary::ApplicationHelper.root_model_class_name_helper(resource)
40
+ end
41
+
42
+ def directory_for_resource(resource)
43
+ resource.class.name.split('::').last.underscore
44
+ end
45
+
46
+ def link_list(collection)
47
+ raw collection.map{|a| link_to a.name, a}.join(', ')
48
+ end
49
+
50
+ def general_attribute?(attribute)
51
+ begin
52
+ I18n.t("attributes.#{attribute}", raise: true)
53
+ true
54
+ rescue
55
+ false
56
+ end
57
+ end
58
+
59
+ def attribute_translation(attribute, current_resource = nil)
60
+ current_resource = current_resource || resource
61
+ t("activerecord.attributes.#{root_model_class_name(current_resource).underscore}.#{attribute}",
62
+ default: t("attributes.#{attribute}")
63
+ )
64
+ end
65
+
66
+ def polymorphic_or_resource_path(record)
67
+ begin
68
+ polymorphic_path(record)
69
+ rescue NoMethodError
70
+ resource_path(record)
71
+ end
72
+ end
73
+
74
+ def resource_path(record)
75
+ klass = ::Voluntary::ApplicationHelper.root_model_class_name_helper(record)
76
+ eval("#{klass.tableize.singularize}_path(record)")
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,45 @@
1
+ module Voluntary
2
+ module CollectionHelper
3
+ def table_cell column, resource, alternative_value = nil
4
+ value = '-'
5
+
6
+ if column == 'name'
7
+ value = resource.send(column)
8
+
9
+ if alternative_value.is_a?(Proc)
10
+ return alternative_value.call(resource)
11
+ elsif value.blank? && alternative_value.present?
12
+ value = eval("resource.#{alternative_value}")
13
+ elsif value.blank?
14
+ value = '-'
15
+ end
16
+
17
+ begin
18
+ link_to value, eval("#{root_model_class_name(resource).tableize.singularize}_path(resource)")
19
+ rescue
20
+ link_to value, eval("#{root_model_class_name(resource).constantize.table_name.singularize}_path(resource)")
21
+ end
22
+ elsif column.match('_id')
23
+ association = nil
24
+
25
+ begin
26
+ association = resource.send(column.gsub('_id', ''))
27
+ rescue
28
+ association = eval("resource.#{alternative_value}") if alternative_value.present?
29
+ end
30
+
31
+ if association
32
+ begin
33
+ link_to(association.name, association)
34
+ rescue NoMethodError
35
+ link_to(association.name, resource_path(association))
36
+ end
37
+ else
38
+ value
39
+ end
40
+ else
41
+ resource.send(column)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,13 @@
1
+ module Voluntary
2
+ module CommentsHelper
3
+ def nested_comments(comments)
4
+ comments.map do |comment, sub_comments|
5
+ next if comment.id.blank?
6
+
7
+ content = render(partial: 'comments/resource', locals: { resource: comment })
8
+ content += content_tag(:div, nested_comments(sub_comments), class: 'nested_comments')
9
+ content
10
+ end.join.html_safe
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,46 @@
1
+ module Voluntary
2
+ module FormHelper
3
+ def link_to_add_fields(name, f, association, options = {})
4
+ attributes = {
5
+ "#{root_model_class_name(f.object).tableize.singularize}".to_sym => f.object
6
+ }
7
+
8
+ new_object = if f.object.respond_to? "#{association.to_s.singularize}_class"
9
+ f.object.send("#{association.to_s.singularize}_class").new(attributes)
10
+ else
11
+ f.object.send(association).new(attributes)
12
+ end
13
+
14
+ id = new_object.object_id
15
+
16
+ #fields = f.fields_for(association, new_object, child_index: id) do |builder|
17
+ fields = f.simple_fields_for(association) do |builder|
18
+ render_product_specific_partial_if_available(
19
+ new_object, "#{controller_name}/#{association.to_s.singularize}_fields",
20
+ f: builder
21
+ )
22
+ end
23
+
24
+ data = {id: id, fields: fields.gsub("\n", '')}
25
+ data[:target] = options[:target] if options.has_key?(:target)
26
+
27
+ link_to(name, '#', class: 'add_fields', data: data)
28
+ end
29
+
30
+ def remove_fields(f)
31
+ if f.object.try(:new_record?)
32
+ link_to t('general.remove'), '#', class: 'remove_fields'
33
+ else
34
+ f.check_box(:_destroy) + f.label(:_destroy, t('general.destroy'))
35
+ end
36
+ end
37
+
38
+ def autocomplete_input(f, field, namespace = nil)
39
+ if namespace
40
+ f.input "#{field}_name", input_html: { data: {autocomplete: eval("autocomplete_#{namespace}_#{field.to_s.tableize}_path")} }
41
+ else
42
+ f.input "#{field}_name", input_html: { data: {autocomplete: eval("autocomplete_#{field.to_s.tableize}_path")} }
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,17 @@
1
+ module Voluntary
2
+ module LanguageHelper
3
+ def available_language_options
4
+ options = []
5
+
6
+ AVAILABLE_LANGUAGES.each do |locale, language|
7
+ options << [language, locale]
8
+ end
9
+
10
+ options.sort_by { |o| o[0] }
11
+ end
12
+
13
+ def all_language_options
14
+ User.languages.sort_by { |o| o[0] }
15
+ end
16
+ end
17
+ end