voluntary 0.4.0 → 0.5.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -1
- data/README.md +0 -1
- data/app/assets/javascripts/voluntary/base.js.coffee +13 -12
- data/app/assets/stylesheets/voluntary/application.css +1 -1
- data/app/assets/stylesheets/voluntary/base.css.sass +3 -3
- data/app/assets/stylesheets/voluntary/bootstrap_and_overrides.css.sass +0 -1
- data/app/assets/stylesheets/voluntary/sticky_footer.css +1 -1
- data/app/controllers/products_controller.rb +2 -2
- data/app/controllers/voluntary/api/v1/base_controller.rb +24 -4
- data/app/controllers/voluntary/api/v1/tasks_controller.rb +50 -0
- data/app/controllers/voluntary/application_controller.rb +0 -4
- data/app/helpers/voluntary/show_helper.rb +2 -1
- data/app/models/area.rb +1 -2
- data/app/models/product.rb +1 -0
- data/app/models/project.rb +0 -1
- data/app/models/project_user.rb +1 -2
- data/app/models/result.rb +4 -0
- data/app/models/story.rb +21 -2
- data/app/models/task.rb +14 -1
- data/app/models/thing.rb +11 -0
- data/app/models/user.rb +9 -8
- data/app/models/wikidata.rb +20 -0
- data/app/views/areas/_form.html.erb +7 -6
- data/app/views/comments/_form.html.erb +7 -7
- data/app/views/layouts/application.html.erb +10 -10
- data/app/views/layouts/shared/_flash_messages.html.erb +1 -1
- data/app/views/layouts/shared/_navigation.html.erb +7 -9
- data/app/views/organizations/_form.html.erb +6 -6
- data/app/views/pages/_form.html.erb +7 -7
- data/app/views/products/_form.html.erb +19 -20
- data/app/views/projects/_form.html.erb +12 -12
- data/app/views/shared/form/_error_messages.html.erb +1 -1
- data/app/views/shared/layouts/twitter_bootstrap/_control_group.html.erb +5 -5
- data/app/views/shared/layouts/twitter_bootstrap/control_group/_boolean.html.erb +4 -4
- data/app/views/shared/resource/_actions.html.erb +2 -1
- data/app/views/stories/_form.html.erb +4 -14
- data/app/views/stories/show.html.erb +1 -0
- data/app/views/stories/steps/_activate.html.erb +6 -9
- data/app/views/stories/steps/_setup_tasks.html.erb +19 -18
- data/app/views/tasks/show.html.erb +20 -0
- data/app/views/users/_form.html.erb +6 -10
- data/app/views/users/preferences.html.erb +6 -8
- data/app/views/users/show.html.erb +1 -0
- data/app/views/workflow/project_owner/index.html.erb +2 -2
- data/app/views/workflow/tasks/_work_form.html.erb +5 -7
- data/app/views/workflow/tasks/steps/_complete.html.erb +9 -5
- data/app/views/workflow/tasks/steps/_review.html.erb +11 -6
- data/app/views/workflow/tasks/steps/_work.html.erb +15 -10
- data/app/views/workflow/user/index.html.erb +4 -4
- data/config/initializers/simple_form.rb +10 -10
- data/config/initializers/simple_form_bootstrap.rb +136 -0
- data/config/locales/general/en.yml +3 -10
- data/config/locales/resources/story/en.yml +5 -0
- data/config/locales/resources/thing/en.yml +8 -0
- data/config/locales/resources/user/en.yml +13 -1
- data/config/routes/api.rb +4 -3
- data/db/migrate/20120907144853_create_schema.rb +0 -2
- data/db/migrate/20131018143613_replace_user_by_polymorphic_resource_in_candidatures.rb +16 -8
- data/db/migrate/20150802141840_drop_recruiting_unless_recruiting_plugin_present.rb +3 -2
- data/db/migrate/20150808155719_add_api_key_to_users.rb +13 -0
- data/db/migrate/20150809120211_remove_roles_model.rb +63 -0
- data/lib/applicat/mvc/model/resource/base.rb +0 -8
- data/lib/concerns/model/base_thing.rb +9 -0
- data/lib/generators/voluntary/install/install_generator.rb +0 -15
- data/lib/generators/voluntary/product_dummy/product_dummy_generator.rb +0 -15
- data/lib/voluntary/test/rspec_helpers/factories.rb +0 -11
- data/lib/voluntary/version.rb +1 -1
- data/lib/voluntary.rb +3 -5
- metadata +48 -94
- data/app/models/role/admin.rb +0 -2
- data/app/models/role/master.rb +0 -2
- data/app/models/role/project_owner.rb +0 -2
- data/app/models/role/user.rb +0 -2
- data/app/models/role.rb +0 -8
- data/app/models/user_role.rb +0 -6
- data/db/seeds.rb +0 -14
- data/lib/db_seed.rb +0 -166
- data/lib/generators/voluntary/install/templates/db/seeds.rb +0 -14
- data/lib/generators/voluntary/install/templates/lib/volontariat_seed.rb +0 -36
- data/lib/volontariat_seed.rb +0 -27
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 419c8a84e348727daf69aa18cf56c4c9a6b719ff
|
|
4
|
+
data.tar.gz: 0539d0b9cf7e06254e7a892b050de1c246082ae3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 82e81ddb6f66fd0accbdae7561fd49b31a80534c884166b142e73e37a9a52cdc0189008fe56d6b4876c6cc44daf36773a3a9caf117bbc677af00b39143f415bf
|
|
7
|
+
data.tar.gz: 30be2205e906c800a754507e5391e74e2fdc0827bca932e68bc04cb1e8b38a7045af9ec98497140e9514055af877118c56b6894e0758078df87f8b973f379b9e
|
data/CHANGELOG.md
CHANGED
|
@@ -1,7 +1,21 @@
|
|
|
1
1
|
## unreleased ##
|
|
2
2
|
|
|
3
|
+
## 0.5.0 (August 17, 2015) ##
|
|
4
|
+
|
|
5
|
+
* [#87](https://github.com/volontariat/voluntary/issues/87) WikiData.org integration for things suggestion
|
|
6
|
+
* [#39](https://github.com/volontariat/voluntary/issues/39) Bootstrap 3 upgrade
|
|
7
|
+
* [#49](https://github.com/volontariat/voluntary/issues/49) Task import from CSV or Excel file
|
|
8
|
+
* [#85](https://github.com/volontariat/voluntary/issues/85) Task show page
|
|
9
|
+
* [#50](https://github.com/volontariat/voluntary/issues/50) [REFACTORING] Replace roles by new bitmap user attribute roles and remove seeds
|
|
10
|
+
* [#84](https://github.com/volontariat/voluntary/issues/84) Task import API
|
|
11
|
+
* [#42](https://github.com/volontariat/voluntary/issues/42) Secure API
|
|
12
|
+
* [#35](https://github.com/volontariat/voluntary/issues/35) API for exporting task results
|
|
13
|
+
* [#83](https://github.com/volontariat/voluntary/issues/83) [BUGFIX] Query about areas with projects without a product return nothing even if there are projects
|
|
14
|
+
|
|
3
15
|
## 0.4.0 (August 3, 2015) ##
|
|
4
16
|
|
|
17
|
+
WARNING: this release drops recruiting data tables if you don't have installed voluntary_recruiting gem.
|
|
18
|
+
|
|
5
19
|
* #47 Refactoring: outsource recruiting to voluntary_recruiting gemRefactoring: outsource recruiting to voluntary_recruiting gem.
|
|
6
20
|
* #81 Removes fork me on GitHub links.
|
|
7
21
|
* #80 Fixes twitter bootstrap style of flash messages.
|
|
@@ -106,4 +120,4 @@
|
|
|
106
120
|
|
|
107
121
|
## 0.0.1 (November 11, 2012) ##
|
|
108
122
|
|
|
109
|
-
* Initial version.
|
|
123
|
+
* Initial version.
|
data/README.md
CHANGED
|
@@ -70,19 +70,20 @@ $(document).ready ->
|
|
|
70
70
|
|
|
71
71
|
target.before($(this).data('fields').replace(regexp, time))
|
|
72
72
|
event.preventDefault()
|
|
73
|
-
|
|
74
|
-
$('input[data-autocomplete]').each (k, v) ->
|
|
75
|
-
$(v).autocomplete({
|
|
76
|
-
source: $(this).attr('data-autocomplete'),
|
|
77
|
-
select: (event, ui) ->
|
|
78
|
-
$(this).val(ui.item.value)
|
|
79
|
-
|
|
80
|
-
if ($(this).attr('id_element'))
|
|
81
|
-
$($(this).attr('id_element')).val(ui.item.id)
|
|
82
|
-
|
|
83
|
-
return false;
|
|
84
|
-
});
|
|
85
73
|
|
|
74
|
+
document.body.addEventListener 'DOMNodeInserted', ((event) ->
|
|
75
|
+
$('input[data-autocomplete]').each (k, v) ->
|
|
76
|
+
$(v).autocomplete
|
|
77
|
+
source: $(this).data('autocomplete')
|
|
78
|
+
select: (event, ui) ->
|
|
79
|
+
$(this).val(ui.item.value)
|
|
80
|
+
|
|
81
|
+
if ($(this).attr('id_element'))
|
|
82
|
+
$($(this).attr('id_element')).val(ui.item.id)
|
|
83
|
+
|
|
84
|
+
false
|
|
85
|
+
)
|
|
86
|
+
|
|
86
87
|
$( ".datepicker" ).each (k, v) ->
|
|
87
88
|
$(v).datepicker({ dateFormat: "yy-mm-dd", changeYear: true, yearRange: "c-100:c+10" });
|
|
88
89
|
|
|
@@ -24,7 +24,7 @@ class ProductsController < ApplicationController
|
|
|
24
24
|
@product.user_id = current_user.id
|
|
25
25
|
|
|
26
26
|
if @product.save
|
|
27
|
-
redirect_to @product, notice: t('general.form.successfully_created')
|
|
27
|
+
redirect_to product_path(@product), notice: t('general.form.successfully_created')
|
|
28
28
|
else
|
|
29
29
|
render :new
|
|
30
30
|
end
|
|
@@ -38,7 +38,7 @@ class ProductsController < ApplicationController
|
|
|
38
38
|
@product = Product.find(params[:id])
|
|
39
39
|
|
|
40
40
|
if @product.update_attributes(params[:product])
|
|
41
|
-
redirect_to @product, notice: t('general.form.successfully_updated')
|
|
41
|
+
redirect_to product_path(@product), notice: t('general.form.successfully_updated')
|
|
42
42
|
else
|
|
43
43
|
render :edit
|
|
44
44
|
end
|
|
@@ -1,10 +1,30 @@
|
|
|
1
1
|
module Voluntary
|
|
2
2
|
module Api
|
|
3
3
|
module V1
|
|
4
|
-
class BaseController < ActionController::Base
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
class BaseController < ActionController::Base
|
|
5
|
+
rescue_from CanCan::AccessDenied, with: :access_denied
|
|
6
|
+
rescue_from ActiveRecord::RecordNotFound, with: :not_found
|
|
7
|
+
rescue_from Mongoid::Errors::DocumentNotFound, with: :not_found
|
|
8
|
+
|
|
9
|
+
def require_api_key
|
|
10
|
+
render status: 401, json: { error: 'You need to pass your API key for this request!' } if current_user.nil?
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
protected
|
|
14
|
+
|
|
15
|
+
def current_user
|
|
16
|
+
@current_user ||= User.where(api_key: params[:api_key]).first
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def access_denied
|
|
22
|
+
render status: 401, json: { error: 'You are not authorized for this request!' }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def not_found
|
|
26
|
+
render status: 403, json: { error: 'Record not found! ' + [current_user.id, Story.first].inspect }
|
|
27
|
+
end
|
|
8
28
|
end
|
|
9
29
|
end
|
|
10
30
|
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
module Voluntary
|
|
2
|
+
module Api
|
|
3
|
+
module V1
|
|
4
|
+
class TasksController < Voluntary::Api::V1::BaseController
|
|
5
|
+
before_action :require_api_key, only: [:create]
|
|
6
|
+
|
|
7
|
+
respond_to :json
|
|
8
|
+
|
|
9
|
+
def index
|
|
10
|
+
params[:page] = nil if params[:page] == ''
|
|
11
|
+
params[:per_page] = nil if params[:per_page] == ''
|
|
12
|
+
collection = Task.where(story_id: params[:story_id])
|
|
13
|
+
collection = collection.where(state: params[:state]) if params[:state].present?
|
|
14
|
+
collection = collection.paginate(per_page: params[:per_page] || 50, page: params[:page] || 1)
|
|
15
|
+
|
|
16
|
+
respond_to do |format|
|
|
17
|
+
format.json {
|
|
18
|
+
render json: {
|
|
19
|
+
current_page: collection.current_page, per_page: collection.per_page,
|
|
20
|
+
total_entries: collection.total_entries, total_pages: collection.total_pages,
|
|
21
|
+
entries: collection.map(&:to_json),
|
|
22
|
+
}.to_json
|
|
23
|
+
}
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def create
|
|
28
|
+
tasks = current_user.stories.find(params[:story_id]).tasks
|
|
29
|
+
json = []
|
|
30
|
+
|
|
31
|
+
params[:tasks].each do |attributes|
|
|
32
|
+
task = tasks.create(attributes)
|
|
33
|
+
|
|
34
|
+
json << if task.valid?
|
|
35
|
+
task.to_json
|
|
36
|
+
else
|
|
37
|
+
hash = { errors: {}}
|
|
38
|
+
task.errors.each {|key, value| hash[:errors][key] = value }
|
|
39
|
+
hash
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
respond_to do |format|
|
|
44
|
+
format.json { render json: json }
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -15,10 +15,6 @@ class Voluntary::ApplicationController < ActionController::Base
|
|
|
15
15
|
def after_sign_in_path_for(resource_or_scope)
|
|
16
16
|
if resource_or_scope.provider == 'lastfm'
|
|
17
17
|
music_path
|
|
18
|
-
elsif resource_or_scope.main_role.is_a? Role::ProjectOwner
|
|
19
|
-
workflow_project_owner_index_path
|
|
20
|
-
elsif resource_or_scope.main_role.is_a? Role::User
|
|
21
|
-
workflow_user_index_path
|
|
22
18
|
else
|
|
23
19
|
workflow_path
|
|
24
20
|
end
|
|
@@ -57,7 +57,8 @@ module Voluntary
|
|
|
57
57
|
result = content_tag :dt, raw(' ')
|
|
58
58
|
result += content_tag :dd, render(
|
|
59
59
|
partial: 'shared/resource/actions', locals: {
|
|
60
|
-
type: root_model_class_name(resource).tableize, resource: resource, namespace: options[:namespace]
|
|
60
|
+
type: root_model_class_name(resource).tableize, resource: resource, namespace: options[:namespace],
|
|
61
|
+
after_namespace: options[:after_namespace]
|
|
61
62
|
}
|
|
62
63
|
)
|
|
63
64
|
|
data/app/models/area.rb
CHANGED
|
@@ -14,7 +14,7 @@ class Area < ActiveRecord::Base
|
|
|
14
14
|
OR areas2.ancestry = CONCAT(areas.id, '')
|
|
15
15
|
LEFT JOIN areas_projects ON areas_projects.area_id = areas2.id
|
|
16
16
|
LEFT JOIN projects ON projects.id = areas_projects.project_id
|
|
17
|
-
}).where('areas2.id IS NOT NULL AND projects.product_id = ?', product_id)
|
|
17
|
+
}).where('areas2.id IS NOT NULL AND projects.product_id = ?', product_id == 'no-name' ? '' : product_id)
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
validates :name, presence: true, uniqueness: true
|
|
@@ -26,7 +26,6 @@ class Area < ActiveRecord::Base
|
|
|
26
26
|
friendly_id :name, :use => :slugged
|
|
27
27
|
|
|
28
28
|
def self.find_by_product_id(product_id)
|
|
29
|
-
#roots.joins(:projects).merge(Project.for_product_id(product_id))
|
|
30
29
|
roots.with_projects_for_product(product_id)
|
|
31
30
|
end
|
|
32
31
|
|
data/app/models/product.rb
CHANGED
data/app/models/project.rb
CHANGED
data/app/models/project_user.rb
CHANGED
|
@@ -3,10 +3,9 @@ class ProjectUser < ActiveRecord::Base#
|
|
|
3
3
|
|
|
4
4
|
belongs_to :project
|
|
5
5
|
belongs_to :user
|
|
6
|
-
belongs_to :role
|
|
7
6
|
|
|
8
7
|
validates :project_id, presence: true
|
|
9
8
|
validates :user_id, presence: true, uniqueness: { scope: [:project_id] }
|
|
10
9
|
|
|
11
|
-
attr_accessible :project_id, :user_id
|
|
10
|
+
attr_accessible :project_id, :user_id
|
|
12
11
|
end
|
data/app/models/result.rb
CHANGED
data/app/models/story.rb
CHANGED
|
@@ -26,7 +26,9 @@ class Story
|
|
|
26
26
|
|
|
27
27
|
slug :name
|
|
28
28
|
|
|
29
|
-
attr_accessible :project_id, :name, :text, :tasks_attributes
|
|
29
|
+
attr_accessible :project_id, :name, :text, :tasks_file, :tasks_attributes
|
|
30
|
+
|
|
31
|
+
attr_accessor :tasks_file
|
|
30
32
|
|
|
31
33
|
scope :active, -> { where(state: 'active') }
|
|
32
34
|
|
|
@@ -37,7 +39,8 @@ class Story
|
|
|
37
39
|
|
|
38
40
|
after_initialize :cache_associations
|
|
39
41
|
before_validation :cache_associations
|
|
40
|
-
|
|
42
|
+
after_save :import_tasks_from_file, if: 'tasks_file.present?'
|
|
43
|
+
|
|
41
44
|
PARENT_TYPES = ['project']
|
|
42
45
|
|
|
43
46
|
def self.for_user(user)
|
|
@@ -76,6 +79,22 @@ class Story
|
|
|
76
79
|
|
|
77
80
|
private
|
|
78
81
|
|
|
82
|
+
def import_tasks_from_file
|
|
83
|
+
csv = CSV.read(tasks_file.path)
|
|
84
|
+
column_to_index = {}
|
|
85
|
+
|
|
86
|
+
csv.first.first.split(';').each_with_index do |column, index|
|
|
87
|
+
column_to_index[column.downcase.to_sym] = index
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
csv.each_with_index do |task, index|
|
|
91
|
+
next if index == 0
|
|
92
|
+
|
|
93
|
+
task = task.first.split(';')
|
|
94
|
+
tasks.create name: task[column_to_index[:name]], text: task[column_to_index[:text]]
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
79
98
|
def cache_associations
|
|
80
99
|
self.offeror_id = project.user_id if project_id.present? && (project rescue nil)
|
|
81
100
|
end
|
data/app/models/task.rb
CHANGED
|
@@ -10,7 +10,7 @@ class Task
|
|
|
10
10
|
include StateMachines::Task
|
|
11
11
|
|
|
12
12
|
belongs_to :story
|
|
13
|
-
belongs_to :result
|
|
13
|
+
belongs_to :result
|
|
14
14
|
|
|
15
15
|
accepts_nested_attributes_for :result, allow_destroy: true
|
|
16
16
|
|
|
@@ -39,6 +39,7 @@ class Task
|
|
|
39
39
|
|
|
40
40
|
after_initialize :cache_associations
|
|
41
41
|
before_validation :cache_associations
|
|
42
|
+
after_destroy :destroy_result
|
|
42
43
|
|
|
43
44
|
#track_history on: [:user_id, :name, :text, :state]
|
|
44
45
|
|
|
@@ -97,6 +98,14 @@ class Task
|
|
|
97
98
|
end
|
|
98
99
|
end
|
|
99
100
|
|
|
101
|
+
def to_json
|
|
102
|
+
record = {
|
|
103
|
+
id: id.to_s, offeror_id: offeror_id, user_id: user_id, author_id: author_id, name: name, text: text, state: state
|
|
104
|
+
}
|
|
105
|
+
record[:result] = result.to_json if result.present?
|
|
106
|
+
record
|
|
107
|
+
end
|
|
108
|
+
|
|
100
109
|
protected
|
|
101
110
|
|
|
102
111
|
# validates :name, presence: true, uniqueness: { scope: :story_id }
|
|
@@ -114,6 +123,10 @@ class Task
|
|
|
114
123
|
|
|
115
124
|
private
|
|
116
125
|
|
|
126
|
+
def destroy_result
|
|
127
|
+
result.try(:destroy)
|
|
128
|
+
end
|
|
129
|
+
|
|
117
130
|
def cache_associations
|
|
118
131
|
self.offeror_id = story.offeror_id if story_id.present? && (story rescue nil)
|
|
119
132
|
end
|
data/app/models/thing.rb
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
1
|
class Thing < ActiveRecord::Base
|
|
2
2
|
include Concerns::Model::BaseThing
|
|
3
|
+
|
|
4
|
+
def self.suggest(term)
|
|
5
|
+
known_things = Thing.order(:name).where("name LIKE ?", "%#{term}%").limit(10).map do |t|
|
|
6
|
+
{ id: t.id, name: t.name }
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
(known_things + Wikidata.search(term, known_things)).map do |item|
|
|
10
|
+
item[:value] = item[:name]
|
|
11
|
+
item
|
|
12
|
+
end
|
|
13
|
+
end
|
|
3
14
|
end
|
data/app/models/user.rb
CHANGED
|
@@ -5,14 +5,13 @@ class User < ActiveRecord::Base
|
|
|
5
5
|
include User::Omniauthable
|
|
6
6
|
include User::Liking
|
|
7
7
|
|
|
8
|
-
belongs_to :main_role, class_name: 'Role'
|
|
9
8
|
belongs_to :profession
|
|
10
9
|
|
|
11
|
-
has_and_belongs_to_many :roles, join_table: 'users_roles'
|
|
12
10
|
has_and_belongs_to_many :areas
|
|
13
11
|
has_and_belongs_to_many :projects
|
|
14
12
|
|
|
15
13
|
has_many :organizations, dependent: :destroy
|
|
14
|
+
def stories; Story.where(offeror_id: id); end
|
|
16
15
|
|
|
17
16
|
accepts_nested_attributes_for :areas, allow_destroy: true
|
|
18
17
|
|
|
@@ -29,8 +28,6 @@ class User < ActiveRecord::Base
|
|
|
29
28
|
:salutation, :marital_status, :family_status, :date_of_birth, :place_of_birth, :citizenship,
|
|
30
29
|
:email, :country, :language, :interface_language, :foreign_language_tokens, :profession_id,
|
|
31
30
|
:employment_relationship, :area_tokens, :remember_me
|
|
32
|
-
# preferences
|
|
33
|
-
:main_role_id
|
|
34
31
|
|
|
35
32
|
# :timeoutable, :token_authenticatable, :lockable,
|
|
36
33
|
# :lock_strategy => :none, :unlock_strategy => :nones
|
|
@@ -42,7 +39,9 @@ class User < ActiveRecord::Base
|
|
|
42
39
|
|
|
43
40
|
friendly_id :name, use: :slugged
|
|
44
41
|
|
|
45
|
-
|
|
42
|
+
bitmask :roles, as: [:master]
|
|
43
|
+
|
|
44
|
+
before_create :create_api_key
|
|
46
45
|
|
|
47
46
|
PARENT_TYPES = ['area', 'project']
|
|
48
47
|
|
|
@@ -67,7 +66,7 @@ class User < ActiveRecord::Base
|
|
|
67
66
|
end
|
|
68
67
|
|
|
69
68
|
def is_master?
|
|
70
|
-
roles.
|
|
69
|
+
roles.include? :master
|
|
71
70
|
end
|
|
72
71
|
|
|
73
72
|
def languages
|
|
@@ -108,7 +107,9 @@ class User < ActiveRecord::Base
|
|
|
108
107
|
|
|
109
108
|
private
|
|
110
109
|
|
|
111
|
-
def
|
|
112
|
-
|
|
110
|
+
def create_api_key
|
|
111
|
+
begin
|
|
112
|
+
self.api_key = SecureRandom.uuid.tr('-', '')
|
|
113
|
+
end while User.where(api_key: api_key).any?
|
|
113
114
|
end
|
|
114
115
|
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
class Wikidata
|
|
2
|
+
def self.search(term, known_things)
|
|
3
|
+
JSON.parse(
|
|
4
|
+
HTTParty.get(
|
|
5
|
+
"https://www.wikidata.org/w/api.php?action=wbsearchentities&search=" +
|
|
6
|
+
"#{URI.encode(term, /\W/)}&format=json&language=en&type=item&continue=0",
|
|
7
|
+
verify: false
|
|
8
|
+
).body
|
|
9
|
+
)['search'].map do |item|
|
|
10
|
+
description = if item['description'].to_s.present? &&
|
|
11
|
+
item['description'] != 'Wikimedia disambiguation page'
|
|
12
|
+
" (#{item['description']})"
|
|
13
|
+
else
|
|
14
|
+
''
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
"#{item['label']}#{description}"
|
|
18
|
+
end.uniq.select{|i| known_things.select{|t| t[:name] == i }.none? }.map{|item| { name: item } }
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
<%= simple_form_for(@area, html: {class: 'form-horizontal'}) do |f| %>
|
|
1
|
+
<%= simple_form_for(@area, html: {class: 'form-horizontal'}, wrapper: :horizontal_form) do |f| %>
|
|
2
2
|
<%= render partial: 'shared/form/error_messages', locals: { resource: @area } %>
|
|
3
3
|
|
|
4
4
|
<%= f.hidden_field :parent_id %>
|
|
5
|
-
<div class="form-inputs">
|
|
6
|
-
<%= f.input :name %>
|
|
7
|
-
</div>
|
|
8
5
|
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
<%= f.input :name %>
|
|
7
|
+
|
|
8
|
+
<div class="form-group">
|
|
9
|
+
<div class="col-sm-offset-3 col-sm-9">
|
|
10
|
+
<%= f.button :submit %>
|
|
11
|
+
</div>
|
|
11
12
|
</div>
|
|
12
13
|
<% end %>
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
<%= simple_form_for(resource, html: {class: 'form-horizontal'}) do |f| %>
|
|
1
|
+
<%= simple_form_for(resource, html: {class: 'form-horizontal'}, wrapper: :horizontal_form) do |f| %>
|
|
2
2
|
<%= render partial: 'shared/form/error_messages', locals: { resource: resource } %>
|
|
3
3
|
|
|
4
4
|
<%= f.hidden_field :parent_id %>
|
|
5
5
|
<%= f.hidden_field :commentable_type %>
|
|
6
6
|
<%= f.hidden_field :commentable_id %>
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
<%= f.input :text, input_html: {style: 'width: 500px; height:300px;'} %>
|
|
11
|
-
</div>
|
|
8
|
+
<%= f.input :name %>
|
|
9
|
+
<%= f.input :text, input_html: {style: 'width: 500px; height:300px;'} %>
|
|
12
10
|
|
|
13
|
-
<div class="form-
|
|
14
|
-
|
|
11
|
+
<div class="form-group">
|
|
12
|
+
<div class="col-sm-offset-3 col-sm-9">
|
|
13
|
+
<%= f.button :submit %>
|
|
14
|
+
</div>
|
|
15
15
|
</div>
|
|
16
16
|
<% end %>
|
|
@@ -21,26 +21,26 @@
|
|
|
21
21
|
|
|
22
22
|
<div class="container-fluid">
|
|
23
23
|
<% unless flash.empty? %>
|
|
24
|
-
<div class="row
|
|
25
|
-
<div class="
|
|
24
|
+
<div class="row">
|
|
25
|
+
<div class="col-md-12">
|
|
26
26
|
<%= render 'layouts/shared/flash_messages' %>
|
|
27
27
|
</div>
|
|
28
28
|
</div>
|
|
29
29
|
<% end %>
|
|
30
|
-
<div class="row
|
|
30
|
+
<div class="row">
|
|
31
31
|
<% if sidenav(@sidenav_links_count).present? || content_for?(:search) || content_for?(:sidebar) %>
|
|
32
|
-
<div class="
|
|
32
|
+
<div class="col-md-9">
|
|
33
33
|
<% if content_for?(:breadcrumbs) %>
|
|
34
|
-
<div class="nav">
|
|
34
|
+
<div class="nav" style="padding-bottom:15px;">
|
|
35
35
|
<%= yield :breadcrumbs %>
|
|
36
36
|
</div>
|
|
37
37
|
<% else %>
|
|
38
|
-
<%= breadcrumbs %>
|
|
38
|
+
<%= raw breadcrumbs.gsub('<div class="nav">', '<div class="nav" style="padding-bottom:15px;">') %>
|
|
39
39
|
<% end %>
|
|
40
40
|
|
|
41
41
|
<%= yield %>
|
|
42
42
|
</div>
|
|
43
|
-
<div class="
|
|
43
|
+
<div class="col-md-3">
|
|
44
44
|
<%= yield :search %>
|
|
45
45
|
|
|
46
46
|
<%= sidenav(@sidenav_links_count) %>
|
|
@@ -48,13 +48,13 @@
|
|
|
48
48
|
<%= yield :sidebar %>
|
|
49
49
|
</div>
|
|
50
50
|
<% else %>
|
|
51
|
-
<div class="
|
|
51
|
+
<div class="col-md-12">
|
|
52
52
|
<% if content_for?(:breadcrumbs) %>
|
|
53
|
-
<div class="nav">
|
|
53
|
+
<div class="nav" style="padding-bottom:15px;">
|
|
54
54
|
<%= yield :breadcrumbs %>
|
|
55
55
|
</div>
|
|
56
56
|
<% else %>
|
|
57
|
-
<%= breadcrumbs %>
|
|
57
|
+
<%= raw breadcrumbs.gsub('<div class="nav">', '<div class="nav" style="padding-bottom:15px;">') %>
|
|
58
58
|
<% end %>
|
|
59
59
|
|
|
60
60
|
<%= yield %>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<div class="flash">
|
|
2
2
|
<% flash.each do |type, message| -%>
|
|
3
|
-
<div class="alert message <%= (type.to_sym == :notice ? 'alert-info' : 'alert-
|
|
3
|
+
<div class="alert message <%= (type.to_sym == :notice ? 'alert-info' : 'alert-danger') %>">
|
|
4
4
|
<%= message %><br/>
|
|
5
5
|
</div>
|
|
6
6
|
<% end -%>
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
<
|
|
2
|
-
<div class="
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
<%= render_navigation context: application_navigation, expand_all: false, renderer: :bootstrap %>
|
|
8
|
-
</div>
|
|
1
|
+
<nav class="navbar navbar-inverse navbar-fixed-top">
|
|
2
|
+
<div class="container">
|
|
3
|
+
<a id="plattform_brand" class="navbar-brand" href="/">Volontari.at /</a>
|
|
4
|
+
<a id="product_brand" class="navbar-brand" href="<%= navigation_product_path %>"><%= navigation_product_name %></a>
|
|
5
|
+
|
|
6
|
+
<%= raw render_navigation(context: application_navigation, expand_all: false, renderer: :bootstrap).gsub('<ul class="nav">', '<ul class="nav navbar-nav">') %>
|
|
9
7
|
</div>
|
|
10
|
-
</
|
|
8
|
+
</nav>
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
<%= simple_form_for(@organization, html: {class: 'form-horizontal'}) do |f| %>
|
|
1
|
+
<%= simple_form_for(@organization, html: {class: 'form-horizontal'}, wrapper: :horizontal_form) do |f| %>
|
|
2
2
|
<%= render partial: 'shared/form/error_messages', locals: { resource: @organization } %>
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
<%= f.input :name %>
|
|
6
|
-
</div>
|
|
4
|
+
<%= f.input :name %>
|
|
7
5
|
|
|
8
|
-
<div class="
|
|
9
|
-
|
|
6
|
+
<div class="form-group">
|
|
7
|
+
<div class="col-sm-offset-3 col-sm-9">
|
|
8
|
+
<%= f.button :submit %>
|
|
9
|
+
</div>
|
|
10
10
|
</div>
|
|
11
11
|
<% end %>
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
<%= simple_form_for(@page, html: {class: 'form-horizontal'}) do |f| %>
|
|
1
|
+
<%= simple_form_for(@page, html: {class: 'form-horizontal'}, wrapper: :horizontal_form) do |f| %>
|
|
2
2
|
<%= render partial: 'shared/form/error_messages', locals: { resource: @page } %>
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
<%= f.input :text, as: :text, input_html: {style: 'width: 100%; height:300px;'} %>
|
|
7
|
-
</div>
|
|
4
|
+
<%= f.input :name %>
|
|
5
|
+
<%= f.input :text, as: :text, input_html: {style: 'width: 100%; height:300px;'} %>
|
|
8
6
|
|
|
9
|
-
<div class="
|
|
10
|
-
|
|
7
|
+
<div class="form-group">
|
|
8
|
+
<div class="col-sm-offset-3 col-sm-9">
|
|
9
|
+
<%= f.button :submit %>
|
|
10
|
+
</div>
|
|
11
11
|
</div>
|
|
12
12
|
<% end %>
|