voluntary 0.5.2 → 0.6.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 +4 -0
- data/README.md +1 -1
- data/app/assets/javascripts/voluntary/lib/jquery.cookie.js +139 -0
- data/app/assets/javascripts/voluntary/lib/jquery.toggle_text.js.coffee +27 -0
- data/app/controllers/concerns/voluntary/v1/base_controller.rb +8 -0
- data/app/controllers/stories_controller.rb +10 -5
- data/app/controllers/voluntary/api/v1/arguments_controller.rb +4 -0
- data/app/controllers/voluntary/api/v1/stories_controller.rb +90 -0
- data/app/models/area.rb +6 -0
- data/app/models/argument.rb +41 -1
- data/app/models/concerns/likeable.rb +3 -2
- data/app/models/organization.rb +6 -0
- data/app/models/profession.rb +6 -0
- data/app/models/project.rb +4 -0
- data/app/models/result.rb +4 -4
- data/app/models/state_machines/story.rb +12 -2
- data/app/models/story.rb +6 -0
- data/app/models/task.rb +7 -6
- data/app/models/user.rb +4 -0
- data/app/models/wikidata.rb +20 -16
- data/app/serializers/story_serializer.rb +3 -0
- data/app/serializers/task_serializer.rb +3 -0
- data/app/views/workflow/user/index.html.erb +2 -2
- data/app/views/workflow/user/stories/_next_task.html.erb +1 -0
- data/app/views/workflow/user/stories/index.html.erb +5 -1
- data/config/locales/resources/argument/en.yml +2 -0
- data/config/locales/resources/story/en.yml +12 -0
- data/config/locales/resources/thing/en.yml +7 -0
- data/config/routes/api.rb +11 -2
- data/lib/voluntary.rb +1 -0
- data/lib/voluntary/navigation.rb +4 -0
- data/lib/voluntary/version.rb +1 -1
- metadata +23 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9e0d6d9bf2a37688124de536d7859f1830abf3c6
|
4
|
+
data.tar.gz: 94f456e0b313a7d306724a1612e0bedea268d0f6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7e2b60e9b3b05d5f3c0bd8733b96908fd3cc687db7c03999dcd36c69834030e595c7ec77cfa961ebc93ff739830e53d228e67f74931e19732a3cd53d195eff74
|
7
|
+
data.tar.gz: d5affd0cc24ceb1af706ce02afaedaf1e9441509f033b6f884ee1b3516b93fe91f6409f4692b4241726e2d1f9180e4458eebe2ea3f7dac545ced13e0a6033b74
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -89,7 +89,7 @@ Run this in your console:
|
|
89
89
|
bundle exec rake db:create:all && bundle exec rails g voluntary:product_dummy # confirm all overwrite questions except of Gemfile
|
90
90
|
cd ..
|
91
91
|
# add gitignore file from voluntary: https://github.com/volontariat/voluntary/blob/master/.gitignore
|
92
|
-
rails g migration add_product_name_product
|
92
|
+
bundle exec rails g migration add_product_name_product
|
93
93
|
# fill migration file with template: https://github.com/volontariat/voluntary_scholarship/blob/master/db/migrate/20140306201232_add_scholarship_product.rb
|
94
94
|
cd dummy
|
95
95
|
bundle exec rake railties:install:migrations
|
@@ -0,0 +1,139 @@
|
|
1
|
+
/*!
|
2
|
+
* JavaScript Cookie v2.0.3
|
3
|
+
* https://github.com/js-cookie/js-cookie
|
4
|
+
*
|
5
|
+
* Copyright 2006, 2015 Klaus Hartl & Fagner Brack
|
6
|
+
* Released under the MIT license
|
7
|
+
*/
|
8
|
+
(function (factory) {
|
9
|
+
if (typeof define === 'function' && define.amd) {
|
10
|
+
define(factory);
|
11
|
+
} else if (typeof exports === 'object') {
|
12
|
+
module.exports = factory();
|
13
|
+
} else {
|
14
|
+
var _OldCookies = window.Cookies;
|
15
|
+
var api = window.Cookies = factory();
|
16
|
+
api.noConflict = function () {
|
17
|
+
window.Cookies = _OldCookies;
|
18
|
+
return api;
|
19
|
+
};
|
20
|
+
}
|
21
|
+
}(function () {
|
22
|
+
function extend () {
|
23
|
+
var i = 0;
|
24
|
+
var result = {};
|
25
|
+
for (; i < arguments.length; i++) {
|
26
|
+
var attributes = arguments[ i ];
|
27
|
+
for (var key in attributes) {
|
28
|
+
result[key] = attributes[key];
|
29
|
+
}
|
30
|
+
}
|
31
|
+
return result;
|
32
|
+
}
|
33
|
+
|
34
|
+
function init (converter) {
|
35
|
+
function api (key, value, attributes) {
|
36
|
+
var result;
|
37
|
+
|
38
|
+
// Write
|
39
|
+
|
40
|
+
if (arguments.length > 1) {
|
41
|
+
attributes = extend({
|
42
|
+
path: '/'
|
43
|
+
}, api.defaults, attributes);
|
44
|
+
|
45
|
+
if (typeof attributes.expires === 'number') {
|
46
|
+
var expires = new Date();
|
47
|
+
expires.setMilliseconds(expires.getMilliseconds() + attributes.expires * 864e+5);
|
48
|
+
attributes.expires = expires;
|
49
|
+
}
|
50
|
+
|
51
|
+
try {
|
52
|
+
result = JSON.stringify(value);
|
53
|
+
if (/^[\{\[]/.test(result)) {
|
54
|
+
value = result;
|
55
|
+
}
|
56
|
+
} catch (e) {}
|
57
|
+
|
58
|
+
value = encodeURIComponent(String(value));
|
59
|
+
value = value.replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent);
|
60
|
+
|
61
|
+
key = encodeURIComponent(String(key));
|
62
|
+
key = key.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent);
|
63
|
+
key = key.replace(/[\(\)]/g, escape);
|
64
|
+
|
65
|
+
return (document.cookie = [
|
66
|
+
key, '=', value,
|
67
|
+
attributes.expires && '; expires=' + attributes.expires.toUTCString(), // use expires attribute, max-age is not supported by IE
|
68
|
+
attributes.path && '; path=' + attributes.path,
|
69
|
+
attributes.domain && '; domain=' + attributes.domain,
|
70
|
+
attributes.secure ? '; secure' : ''
|
71
|
+
].join(''));
|
72
|
+
}
|
73
|
+
|
74
|
+
// Read
|
75
|
+
|
76
|
+
if (!key) {
|
77
|
+
result = {};
|
78
|
+
}
|
79
|
+
|
80
|
+
// To prevent the for loop in the first place assign an empty array
|
81
|
+
// in case there are no cookies at all. Also prevents odd result when
|
82
|
+
// calling "get()"
|
83
|
+
var cookies = document.cookie ? document.cookie.split('; ') : [];
|
84
|
+
var rdecode = /(%[0-9A-Z]{2})+/g;
|
85
|
+
var i = 0;
|
86
|
+
|
87
|
+
for (; i < cookies.length; i++) {
|
88
|
+
var parts = cookies[i].split('=');
|
89
|
+
var name = parts[0].replace(rdecode, decodeURIComponent);
|
90
|
+
var cookie = parts.slice(1).join('=');
|
91
|
+
|
92
|
+
if (cookie.charAt(0) === '"') {
|
93
|
+
cookie = cookie.slice(1, -1);
|
94
|
+
}
|
95
|
+
|
96
|
+
try {
|
97
|
+
cookie = converter && converter(cookie, name) || cookie.replace(rdecode, decodeURIComponent);
|
98
|
+
|
99
|
+
if (this.json) {
|
100
|
+
try {
|
101
|
+
cookie = JSON.parse(cookie);
|
102
|
+
} catch (e) {}
|
103
|
+
}
|
104
|
+
|
105
|
+
if (key === name) {
|
106
|
+
result = cookie;
|
107
|
+
break;
|
108
|
+
}
|
109
|
+
|
110
|
+
if (!key) {
|
111
|
+
result[name] = cookie;
|
112
|
+
}
|
113
|
+
} catch (e) {}
|
114
|
+
}
|
115
|
+
|
116
|
+
return result;
|
117
|
+
}
|
118
|
+
|
119
|
+
api.get = api.set = api;
|
120
|
+
api.getJSON = function () {
|
121
|
+
return api.apply({
|
122
|
+
json: true
|
123
|
+
}, [].slice.call(arguments));
|
124
|
+
};
|
125
|
+
api.defaults = {};
|
126
|
+
|
127
|
+
api.remove = function (key, attributes) {
|
128
|
+
api(key, '', extend(attributes, {
|
129
|
+
expires: -1
|
130
|
+
}));
|
131
|
+
};
|
132
|
+
|
133
|
+
api.withConverter = init;
|
134
|
+
|
135
|
+
return api;
|
136
|
+
}
|
137
|
+
|
138
|
+
return init();
|
139
|
+
}));
|
@@ -0,0 +1,27 @@
|
|
1
|
+
@toggleText = ->
|
2
|
+
showChar = 255
|
3
|
+
ellipsesText = '...'
|
4
|
+
moreText = 'Show more >'
|
5
|
+
lessText = 'Show less'
|
6
|
+
|
7
|
+
$('.more').each ->
|
8
|
+
content = $(this).html()
|
9
|
+
|
10
|
+
if content.length > showChar
|
11
|
+
c = content.substr(0, showChar)
|
12
|
+
h = content.substr(showChar, content.length - showChar)
|
13
|
+
html = c + '<span class="more_ellipses">' + ellipsesText + ' </span><span style="display:none;">' + h + '</span> <a href="" class="more_link" style="display:block;">' + moreText + '</a>'
|
14
|
+
$(this).html html
|
15
|
+
|
16
|
+
$('.more_link').click ->
|
17
|
+
if $(this).hasClass('less')
|
18
|
+
$(this).removeClass 'less'
|
19
|
+
$(this).html moreText
|
20
|
+
else
|
21
|
+
$(this).addClass 'less'
|
22
|
+
$(this).html lessText
|
23
|
+
|
24
|
+
$(this).siblings('.more_ellipses').toggle()
|
25
|
+
$(this).prev().toggle()
|
26
|
+
|
27
|
+
false
|
@@ -26,6 +26,14 @@ module Voluntary
|
|
26
26
|
|
27
27
|
protected
|
28
28
|
|
29
|
+
def product_serializer(class_name, record)
|
30
|
+
begin
|
31
|
+
"#{record.product.class.name.gsub('Product::', '')}#{class_name}Serializer".constantize.new(record)
|
32
|
+
rescue NameError
|
33
|
+
"#{class_name}Serializer".constantize.new(record)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
29
37
|
def application_navigation
|
30
38
|
:main
|
31
39
|
end
|
@@ -18,6 +18,7 @@ class StoriesController < ApplicationController
|
|
18
18
|
|
19
19
|
def show
|
20
20
|
@comments = @story.comments
|
21
|
+
@twitter_sidenav_level = 5
|
21
22
|
end
|
22
23
|
|
23
24
|
def new
|
@@ -33,10 +34,7 @@ class StoriesController < ApplicationController
|
|
33
34
|
end
|
34
35
|
|
35
36
|
def edit
|
36
|
-
|
37
|
-
#@story.tasks << @story.tasks.new
|
38
|
-
#@story.tasks.first.errors.clear
|
39
|
-
#end
|
37
|
+
@twitter_sidenav_level = 5
|
40
38
|
|
41
39
|
render_wizard
|
42
40
|
end
|
@@ -90,6 +88,13 @@ class StoriesController < ApplicationController
|
|
90
88
|
@presenter = Resources::General::Wizards::StoryPresenter.new(
|
91
89
|
self.view_context, resource: resource
|
92
90
|
)
|
93
|
-
|
91
|
+
|
92
|
+
begin
|
93
|
+
raise NotImplementedError if @project.product_id.blank?
|
94
|
+
|
95
|
+
render "products/types/#{@project.product.class.name.split('Product::').last.tableize.singularize}/wizard"
|
96
|
+
rescue NotImplementedError, ActionView::MissingTemplate
|
97
|
+
render 'general/wizard'
|
98
|
+
end
|
94
99
|
end
|
95
100
|
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
class Voluntary::Api::V1::StoriesController < ActionController::Base
|
2
|
+
include Voluntary::V1::BaseController
|
3
|
+
|
4
|
+
respond_to :json
|
5
|
+
|
6
|
+
def show
|
7
|
+
story = Story.find(params[:id])
|
8
|
+
|
9
|
+
respond_to do |format|
|
10
|
+
format.json do
|
11
|
+
render json: product_serializer('Story', story)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def create
|
17
|
+
project = Project.find(params[:story][:project_id])
|
18
|
+
story = project.story_class.new({ project_id: project.id }.merge(params[:story] || {}))
|
19
|
+
|
20
|
+
authorize! :create, story
|
21
|
+
|
22
|
+
story.save
|
23
|
+
|
24
|
+
respond_to do |format|
|
25
|
+
format.json do
|
26
|
+
render json: story.persisted? ? product_serializer('Story', story) : { errors: story.errors.to_hash }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def update
|
32
|
+
story = Story.find params[:id]
|
33
|
+
|
34
|
+
authorize! :update, story
|
35
|
+
|
36
|
+
story.update_attributes params[:story]
|
37
|
+
|
38
|
+
respond_to do |format|
|
39
|
+
format.json do
|
40
|
+
render json: story.valid? ? product_serializer('Story', story) : { errors: story.errors.to_hash }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def activate
|
46
|
+
story = Story.find params[:id]
|
47
|
+
|
48
|
+
authorize! :update, story
|
49
|
+
|
50
|
+
story.activate
|
51
|
+
|
52
|
+
respond_to do |format|
|
53
|
+
format.json do
|
54
|
+
render json: story.errors.empty? && story.valid? ? product_serializer('Story', story) : { errors: story.errors.to_hash }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def deactivate
|
60
|
+
story = Story.find params[:id]
|
61
|
+
|
62
|
+
authorize! :update, story
|
63
|
+
|
64
|
+
story.deactivate
|
65
|
+
|
66
|
+
respond_to do |format|
|
67
|
+
format.json do
|
68
|
+
render json: story.errors.empty? && story.valid? ? product_serializer('Story', story) : { errors: story.errors.to_hash }
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def destroy
|
74
|
+
story = current_user.stories.friendly.find params[:id]
|
75
|
+
|
76
|
+
authorize! :destroy, story
|
77
|
+
|
78
|
+
story.destroy
|
79
|
+
|
80
|
+
respond_to do |format|
|
81
|
+
format.json do
|
82
|
+
render json: if story.persisted?
|
83
|
+
{ error: I18n.t('activerecord.errors.models.story.attributes.base.deletion_failed') }
|
84
|
+
else
|
85
|
+
{}
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
data/app/models/area.rb
CHANGED
data/app/models/argument.rb
CHANGED
@@ -27,7 +27,7 @@ class Argument < ActiveRecord::Base
|
|
27
27
|
|
28
28
|
attr_accessible :topic_id, :argumentable_type, :argumentable_id, :vote, :value
|
29
29
|
|
30
|
-
attr_accessor :positive
|
30
|
+
attr_accessor :vote, :positive
|
31
31
|
|
32
32
|
def self.create_with_topic(user_id, attributes)
|
33
33
|
topic = ArgumentTopic.find_or_create_by_name attributes[:topic_name]
|
@@ -55,4 +55,44 @@ class Argument < ActiveRecord::Base
|
|
55
55
|
{ errors: { topic: topic.errors.to_hash } }
|
56
56
|
end
|
57
57
|
end
|
58
|
+
|
59
|
+
def self.matrix(argumentables)
|
60
|
+
arguments = []
|
61
|
+
|
62
|
+
argumentables.each do |index, argumentable|
|
63
|
+
arguments += Argument.where(
|
64
|
+
argumentable_type: argumentable['type'], argumentable_id: argumentable['id']
|
65
|
+
).includes(:topic).to_a
|
66
|
+
end
|
67
|
+
|
68
|
+
arguments_by_name = {}
|
69
|
+
|
70
|
+
arguments.each do |argument|
|
71
|
+
arguments_by_name[argument.topic.name] ||= []
|
72
|
+
arguments_by_name[argument.topic.name] << argument
|
73
|
+
end
|
74
|
+
|
75
|
+
json = { argumentables: [], matrix: [] }
|
76
|
+
|
77
|
+
argumentables.keys.map(&:to_i).sort.each do |argumentable_index|
|
78
|
+
argumentable = argumentables[argumentable_index.to_s]
|
79
|
+
argumentable = argumentable['type'].constantize.find(argumentable['id'])
|
80
|
+
|
81
|
+
json[:argumentables] << { id: argumentable.id, slug: argumentable.try(:slug), name: argumentable.name }
|
82
|
+
end
|
83
|
+
|
84
|
+
arguments_by_name.keys.sort.each do |topic_name|
|
85
|
+
item = { topic_name: topic_name, values: [] }
|
86
|
+
arguments = arguments_by_name[topic_name]
|
87
|
+
|
88
|
+
argumentables.keys.map(&:to_i).sort.each do |argumentable_index|
|
89
|
+
argumentable = argumentables[argumentable_index.to_s]
|
90
|
+
item[:values] << arguments.select{|a| a.argumentable_type == argumentable['type'] && a.argumentable_id == argumentable['id'].to_i }.first.try(:value)
|
91
|
+
end
|
92
|
+
|
93
|
+
json[:matrix] << item
|
94
|
+
end
|
95
|
+
|
96
|
+
json
|
97
|
+
end
|
58
98
|
end
|
@@ -4,9 +4,10 @@ module Likeable
|
|
4
4
|
included do
|
5
5
|
belongs_to :target, polymorphic: true
|
6
6
|
|
7
|
-
has_many :
|
7
|
+
has_many :likes_or_dislikes, class_name: 'Like', dependent: :delete_all, as: :target
|
8
|
+
has_many :likes, -> { where(positive: true) }, as: :target
|
8
9
|
has_many :likers, class_name: 'User', through: :likes, source: :user
|
9
|
-
has_many :dislikes, -> { where(positive: false) }, class_name: 'Like',
|
10
|
+
has_many :dislikes, -> { where(positive: false) }, class_name: 'Like', as: :target
|
10
11
|
has_many :dislikers, class_name: 'User', through: :dislikes, source: :user
|
11
12
|
|
12
13
|
scope :liked_by, ->(user_id) do
|
data/app/models/organization.rb
CHANGED
data/app/models/profession.rb
CHANGED
data/app/models/project.rb
CHANGED
data/app/models/result.rb
CHANGED
@@ -23,7 +23,7 @@ class Result
|
|
23
23
|
|
24
24
|
validates :task_id, presence: true
|
25
25
|
validates :story_id, presence: true
|
26
|
-
validates :offeror_id, presence: true
|
26
|
+
validates :offeror_id, presence: true, if: 'task_id.present? && (task rescue nil) && task.story.with_offeror'
|
27
27
|
validates :text, presence: true
|
28
28
|
|
29
29
|
after_initialize :cache_associations
|
@@ -48,13 +48,13 @@ class Result
|
|
48
48
|
|
49
49
|
def cache_associations
|
50
50
|
self.story_id = task.story_id if task_id.present? && (task rescue nil)
|
51
|
-
self.offeror_id = task.offeror_id if task_id.present? && (task rescue nil)
|
51
|
+
self.offeror_id = task.offeror_id if task_id.present? && (task rescue nil) && task.story.with_offeror
|
52
52
|
end
|
53
53
|
|
54
54
|
def cache_product_association
|
55
55
|
self.product_id = task.product_id if task_id.present? && (task rescue nil)
|
56
56
|
end
|
57
57
|
|
58
|
-
def set_tasks_result_association; task.update_attribute(:result_id, id); end
|
59
|
-
def unset_tasks_result_association; task.update_attribute(:result_id, nil); end
|
58
|
+
def set_tasks_result_association; task.update_attribute(:result_id, id) unless task.respond_to?(:results); end
|
59
|
+
def unset_tasks_result_association; task.update_attribute(:result_id, nil) unless task.respond_to?(:results); end
|
60
60
|
end
|
@@ -26,8 +26,16 @@ module StateMachines::Story
|
|
26
26
|
validate :presence_of_tasks
|
27
27
|
end
|
28
28
|
|
29
|
+
state :active do
|
30
|
+
validate :presence_of_tasks
|
31
|
+
end
|
32
|
+
|
29
33
|
event :activate do
|
30
|
-
transition [:tasks_defined, :completed] => :active
|
34
|
+
transition [:new, :tasks_defined, :completed] => :active
|
35
|
+
end
|
36
|
+
|
37
|
+
event :deactivate do
|
38
|
+
transition :active => :tasks_defined
|
31
39
|
end
|
32
40
|
|
33
41
|
event :complete do
|
@@ -51,7 +59,9 @@ module StateMachines::Story
|
|
51
59
|
end
|
52
60
|
|
53
61
|
def presence_of_tasks
|
54
|
-
self.tasks.delete_if
|
62
|
+
self.tasks.delete_if do |t|
|
63
|
+
t.name.blank? && (t.class.name == 'Task' && t.text.blank?)
|
64
|
+
end
|
55
65
|
|
56
66
|
if tasks.select{|t| !t.valid?}.any?
|
57
67
|
errors[:base] << I18n.t(
|
data/app/models/story.rb
CHANGED
data/app/models/task.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
class Task
|
2
2
|
include Mongoid::Document
|
3
3
|
include Mongoid::Timestamps
|
4
|
-
include Mongoid::Slug
|
5
4
|
#include Mongoid::History::Trackable
|
6
5
|
include ActiveModel::MassAssignmentSecurity
|
7
6
|
|
@@ -21,8 +20,6 @@ class Task
|
|
21
20
|
field :text, type: String
|
22
21
|
field :state, type: String
|
23
22
|
field :unassigned_user_ids, type: Array
|
24
|
-
|
25
|
-
slug :name, reserve: ['new', 'edit', 'next']
|
26
23
|
|
27
24
|
attr_accessible :story, :story_id, :name, :text, :result_attributes
|
28
25
|
|
@@ -33,7 +30,7 @@ class Task
|
|
33
30
|
scope :incomplete, -> { ne(state: 'completed') }
|
34
31
|
|
35
32
|
validates :story_id, presence: true
|
36
|
-
validates :offeror_id, presence: true
|
33
|
+
validates :offeror_id, presence: true, if: 'story_id.present? && (story rescue nil) && story.with_offeror'
|
37
34
|
validates :text, presence: true, if: ->(t) { t.class.name == 'Task' }
|
38
35
|
validate :name_valid?
|
39
36
|
|
@@ -124,11 +121,15 @@ class Task
|
|
124
121
|
private
|
125
122
|
|
126
123
|
def destroy_result
|
127
|
-
|
124
|
+
if respond_to? :results
|
125
|
+
results.map(&:destroy)
|
126
|
+
else
|
127
|
+
result.try(:destroy)
|
128
|
+
end
|
128
129
|
end
|
129
130
|
|
130
131
|
def cache_associations
|
131
|
-
self.offeror_id = story.offeror_id if story_id.present? && (story rescue nil)
|
132
|
+
self.offeror_id = story.offeror_id if story_id.present? && (story rescue nil) && story.with_offeror
|
132
133
|
end
|
133
134
|
|
134
135
|
def cache_product_association
|
data/app/models/user.rb
CHANGED
data/app/models/wikidata.rb
CHANGED
@@ -1,20 +1,24 @@
|
|
1
1
|
class Wikidata
|
2
2
|
def self.search(term, known_things)
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
3
|
+
begin
|
4
|
+
JSON.parse(
|
5
|
+
HTTParty.get(
|
6
|
+
"https://www.wikidata.org/w/api.php?action=wbsearchentities&search=" +
|
7
|
+
"#{URI.encode(term, /\W/)}&format=json&language=en&type=item&continue=0",
|
8
|
+
verify: false
|
9
|
+
).body
|
10
|
+
)['search'].map do |item|
|
11
|
+
description = if item['description'].to_s.present? &&
|
12
|
+
item['description'] != 'Wikimedia disambiguation page'
|
13
|
+
" (#{item['description']})"
|
14
|
+
else
|
15
|
+
''
|
16
|
+
end
|
17
|
+
|
18
|
+
"#{item['label']}#{description}"
|
19
|
+
end.uniq.select{|i| known_things.select{|t| t[:name] == i }.none? }.map{|item| { name: item } }
|
20
|
+
rescue SocketError => e
|
21
|
+
[]
|
22
|
+
end
|
19
23
|
end
|
20
24
|
end
|
@@ -19,10 +19,10 @@
|
|
19
19
|
</ul>
|
20
20
|
<div class="tab-content">
|
21
21
|
<div role="tabpanel" class="tab-pane active" id="stories" style="padding-top:15px;">
|
22
|
-
|
22
|
+
<%= image_tag 'voluntary/spinner.gif' %>
|
23
23
|
</div>
|
24
24
|
<div role="tabpanel" class="tab-pane" id="assigned_tasks" style="padding-top:15px;">
|
25
|
-
|
25
|
+
<%= image_tag 'voluntary/spinner.gif' %>
|
26
26
|
</div>
|
27
27
|
</div>
|
28
28
|
</div>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= link_to t('workflow.user.next_task'), next_task_workflow_user_index_path(story) %>
|
@@ -19,7 +19,11 @@
|
|
19
19
|
-
|
20
20
|
<% end %>
|
21
21
|
</td>
|
22
|
-
<td
|
22
|
+
<td>
|
23
|
+
<%= render_product_specific_partial_if_available(
|
24
|
+
story.project, 'workflow/user/stories/next_task', { story: story }
|
25
|
+
) %>
|
26
|
+
</td>
|
23
27
|
</tr>
|
24
28
|
<% end %>
|
25
29
|
</tbody>
|
@@ -7,6 +7,13 @@ en:
|
|
7
7
|
|
8
8
|
new:
|
9
9
|
title: New Story
|
10
|
+
|
11
|
+
create:
|
12
|
+
title: Create Story
|
13
|
+
|
14
|
+
save:
|
15
|
+
failed: Something went wrong at saving story
|
16
|
+
successful: Successfully saved story.
|
10
17
|
|
11
18
|
show:
|
12
19
|
states:
|
@@ -15,6 +22,9 @@ en:
|
|
15
22
|
|
16
23
|
edit:
|
17
24
|
title: Edit Story
|
25
|
+
|
26
|
+
update:
|
27
|
+
title: Update Story
|
18
28
|
|
19
29
|
steps:
|
20
30
|
initialization:
|
@@ -26,6 +36,8 @@ en:
|
|
26
36
|
update: Update Tasks
|
27
37
|
activate:
|
28
38
|
title: Activate
|
39
|
+
deactivate:
|
40
|
+
title: Deactivate
|
29
41
|
|
30
42
|
activerecord:
|
31
43
|
attributes:
|
@@ -1,4 +1,11 @@
|
|
1
1
|
en:
|
2
|
+
things:
|
3
|
+
show:
|
4
|
+
limit_of_comparison_list: Limit of 4 items in thing comparison list reached!
|
5
|
+
add_to_comparison_list: Add to comparison list
|
6
|
+
remove_from_comparison_list: Remove from comparison list
|
7
|
+
comparison_list: Comparison List
|
8
|
+
|
2
9
|
activerecord:
|
3
10
|
errors:
|
4
11
|
models:
|
data/config/routes/api.rb
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
namespace :voluntary, path: 'api', module: 'voluntary/api', defaults: {format: 'json'} do
|
2
2
|
namespace :v1 do
|
3
|
-
resources :stories, only: [] do
|
3
|
+
resources :stories, only: [:create, :show, :update, :destroy] do
|
4
4
|
resources :tasks, only: [:index, :create]
|
5
|
+
|
6
|
+
member do
|
7
|
+
put :activate
|
8
|
+
put :deactivate
|
9
|
+
end
|
5
10
|
end
|
6
11
|
|
7
12
|
resources :argument_topics, only: [] do
|
@@ -10,7 +15,11 @@ namespace :voluntary, path: 'api', module: 'voluntary/api', defaults: {format: '
|
|
10
15
|
end
|
11
16
|
end
|
12
17
|
|
13
|
-
resources :arguments
|
18
|
+
resources :arguments do
|
19
|
+
collection do
|
20
|
+
get :matrix
|
21
|
+
end
|
22
|
+
end
|
14
23
|
|
15
24
|
get '/things/:left_thing_name/vs/:right_thing_name/arguments', to: 'things/arguments#comparison'
|
16
25
|
|
data/lib/voluntary.rb
CHANGED
data/lib/voluntary/navigation.rb
CHANGED
@@ -210,6 +210,10 @@ module Voluntary
|
|
210
210
|
comments.item(:edit, I18n.t('general.edit'), edit_comment_path(@comment))
|
211
211
|
end
|
212
212
|
end
|
213
|
+
|
214
|
+
if options[:stories_after_resource_has_many]
|
215
|
+
instance_exec story, {}, &options[:stories_after_resource_has_many]
|
216
|
+
end
|
213
217
|
end
|
214
218
|
end
|
215
219
|
end
|
data/lib/voluntary/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: voluntary
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mathias Gawlista
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-10-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -444,6 +444,20 @@ dependencies:
|
|
444
444
|
- - "~>"
|
445
445
|
- !ruby/object:Gem::Version
|
446
446
|
version: 1.0.0
|
447
|
+
- !ruby/object:Gem::Dependency
|
448
|
+
name: mongoid_orderable
|
449
|
+
requirement: !ruby/object:Gem::Requirement
|
450
|
+
requirements:
|
451
|
+
- - "~>"
|
452
|
+
- !ruby/object:Gem::Version
|
453
|
+
version: 4.1.1
|
454
|
+
type: :runtime
|
455
|
+
prerelease: false
|
456
|
+
version_requirements: !ruby/object:Gem::Requirement
|
457
|
+
requirements:
|
458
|
+
- - "~>"
|
459
|
+
- !ruby/object:Gem::Version
|
460
|
+
version: 4.1.1
|
447
461
|
- !ruby/object:Gem::Dependency
|
448
462
|
name: mongoid_slug
|
449
463
|
requirement: !ruby/object:Gem::Requirement
|
@@ -1130,7 +1144,7 @@ dependencies:
|
|
1130
1144
|
- - "~>"
|
1131
1145
|
- !ruby/object:Gem::Version
|
1132
1146
|
version: 2.2.0
|
1133
|
-
description: "#Crowdsourcing management system for #RubyOnRails: http://bit.ly/voluntary-0-
|
1147
|
+
description: "#Crowdsourcing management system for #RubyOnRails: http://bit.ly/voluntary-0-6-0"
|
1134
1148
|
email:
|
1135
1149
|
- gawlista@gmail.com
|
1136
1150
|
executables: []
|
@@ -1146,7 +1160,9 @@ files:
|
|
1146
1160
|
- app/assets/javascripts/voluntary/base.js.coffee
|
1147
1161
|
- app/assets/javascripts/voluntary/functions.js
|
1148
1162
|
- app/assets/javascripts/voluntary/lib/jquery-competitive_list.js
|
1163
|
+
- app/assets/javascripts/voluntary/lib/jquery.cookie.js
|
1149
1164
|
- app/assets/javascripts/voluntary/lib/jquery.multisortable.js
|
1165
|
+
- app/assets/javascripts/voluntary/lib/jquery.toggle_text.js.coffee
|
1150
1166
|
- app/assets/javascripts/voluntary/lib/moment.js
|
1151
1167
|
- app/assets/javascripts/voluntary/lib/sugar.js
|
1152
1168
|
- app/assets/javascripts/voluntary/likes/list.js.coffee
|
@@ -1176,6 +1192,7 @@ files:
|
|
1176
1192
|
- app/controllers/voluntary/api/v1/arguments_controller.rb
|
1177
1193
|
- app/controllers/voluntary/api/v1/base_controller.rb
|
1178
1194
|
- app/controllers/voluntary/api/v1/organizations_controller.rb
|
1195
|
+
- app/controllers/voluntary/api/v1/stories_controller.rb
|
1179
1196
|
- app/controllers/voluntary/api/v1/tasks_controller.rb
|
1180
1197
|
- app/controllers/voluntary/api/v1/things/arguments_controller.rb
|
1181
1198
|
- app/controllers/voluntary/api/v1/users_controller.rb
|
@@ -1248,6 +1265,8 @@ files:
|
|
1248
1265
|
- app/serializers/argument_serializer.rb
|
1249
1266
|
- app/serializers/basic_user_serializer.rb
|
1250
1267
|
- app/serializers/current_user_serializer.rb
|
1268
|
+
- app/serializers/story_serializer.rb
|
1269
|
+
- app/serializers/task_serializer.rb
|
1251
1270
|
- app/serializers/user_serializer.rb
|
1252
1271
|
- app/views/areas/_form.html.erb
|
1253
1272
|
- app/views/areas/edit.html.erb
|
@@ -1339,6 +1358,7 @@ files:
|
|
1339
1358
|
- app/views/workflow/user/index.html.erb
|
1340
1359
|
- app/views/workflow/user/product/areas/show.html.erb
|
1341
1360
|
- app/views/workflow/user/projects/show.html.erb
|
1361
|
+
- app/views/workflow/user/stories/_next_task.html.erb
|
1342
1362
|
- app/views/workflow/user/stories/index.html.erb
|
1343
1363
|
- app/views/workflow/user/tasks/assigned.html.erb
|
1344
1364
|
- config/initializers/1_initialize_app_config.rb
|