voluntary 0.2.4 → 0.3.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 +5 -13
- data/CHANGELOG.md +7 -0
- data/{README.rdoc → README.md} +20 -6
- data/app/controllers/candidatures_controller.rb +1 -1
- data/app/controllers/voluntary/api/v1/base_controller.rb +0 -7
- data/app/helpers/voluntary/application_helper.rb +17 -0
- data/app/models/area.rb +15 -2
- data/app/models/concerns/likeable.rb +4 -1
- data/app/models/product.rb +1 -1
- data/app/models/product/project_management.rb +1 -1
- data/app/models/role.rb +1 -1
- data/app/models/state_machines/candidature.rb +6 -0
- data/app/models/state_machines/page.rb +8 -0
- data/app/models/state_machines/story.rb +6 -0
- data/app/models/state_machines/task.rb +8 -0
- data/app/models/state_machines/vacancy.rb +8 -0
- data/app/models/story.rb +2 -0
- data/app/views/products/index.html.erb +5 -4
- data/app/views/shared/resource/_actions.html.erb +4 -3
- data/app/views/shared/resource/_event_elements.html.erb +2 -4
- data/app/views/users/preferences.html.erb +1 -1
- data/app/views/workflow/user/product/areas/show.html.erb +18 -1
- data/config/initializers/cookies_serializer.rb +1 -0
- data/config/initializers/state_machine_patch_for_rails_4_1_support.rb +8 -0
- data/lib/voluntary.rb +3 -9
- data/lib/voluntary/engine.rb +7 -0
- data/lib/voluntary/test/rspec_helpers/factories.rb +1 -1
- data/lib/voluntary/version.rb +1 -1
- data/lib/wizard.rb +2 -2
- metadata +203 -285
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
ZjNkMDA4MzU1N2RhZDBhNzMyMjc1ODVhN2M5MjFhZDk3NjY1NGNkNQ==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a771ddeec412e7d388b055acff871018533619c5
|
4
|
+
data.tar.gz: c76dc81a5782f89e7309a4391297aa1bced80d89
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
ZDg4OTM3YWM0N2ZhZWZlYjQ4YTg5MjVmMDlkYzVlZjE0NWZhNGM0N2QwMDI1
|
11
|
-
ZmNlNzM0NTc2NTdkMWZjZTk4YjZkNWMyNmVmMTA4ZjY4M2U3NjE=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
ZWJkYzg0ZmRjYTlmYjFmMWNmZDgxZmRkMzcwOTg2ODEwZmVkM2Q3ZDhjZmQ1
|
14
|
-
ZjE1YzE0ODUzZjVlNDYyZWMyOTQ0Mzk3Y2EwNmVlZjA4NWMyOWJlMDFiOWFl
|
15
|
-
ZDlhNDY3NTBhMWZlOWI4OTI5NTUyMDdmZDUxNWE5NmJhYWExZDY=
|
6
|
+
metadata.gz: 98f5ff05154ed1c5c22dad03918f3648f3935b2e46fbeb8eb877d86afe74196858cf4352460033c6499b42a49d988efb4538ed703b344c1bc4195dab1992b6ff
|
7
|
+
data.tar.gz: 996f49f84e99d8b219029c9fbeebd57733eceb89475a640964e98375dc27eb514a383bfcae6ed8b3209372b0d2b5cb8d07ffcd3ff51c23f08d87884a41a64795
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
## unreleased ##
|
2
2
|
|
3
|
+
## 0.3.0 (April 8, 2015) ##
|
4
|
+
|
5
|
+
* #40 Rails 4.2.1 upgrade.
|
6
|
+
* #46 Continuous integration server Travis setup.
|
7
|
+
* #77 Workflow product and (user) product area page: consider areas with projects assigned to sub areas deeper than the direct child areas.
|
8
|
+
* Removes rails-api gem (temporarily?).
|
9
|
+
|
3
10
|
## 0.2.4 (March 23, 2015) ##
|
4
11
|
|
5
12
|
* #73 Sticky Footer for Application Layout (Twitter Bootstrap).
|
data/{README.rdoc → README.md}
RENAMED
@@ -1,35 +1,43 @@
|
|
1
|
-
=
|
1
|
+
# Voluntary [](https://travis-ci.org/volontariat/voluntary) [](https://codeclimate.com/github/volontariat/voluntary) [](https://codeclimate.com/github/volontariat/voluntary)
|
2
2
|
|
3
3
|
This is a gem which turns your rails application into a crowdsourcing platform to run on your intranet or on the internet.
|
4
4
|
|
5
5
|
Then you can add existing voluntary products like text creation or create your own products.
|
6
6
|
|
7
|
-
|
7
|
+
## Installation
|
8
8
|
|
9
|
-
|
9
|
+
### New Application
|
10
10
|
|
11
11
|
Run this in your console:
|
12
12
|
|
13
|
+
```bash
|
13
14
|
rvm --create use 1.9.3@your_crowdsourcing_platform_name
|
14
15
|
gem update bundler
|
15
16
|
gem install rails -v 4.0.13 --no-rdoc --no-ri
|
16
17
|
rails new your_crowdsourcing_platform_name
|
17
18
|
cd your_crowdsourcing_platform_name
|
19
|
+
```
|
18
20
|
|
19
21
|
Add this to your Gemfile:
|
20
22
|
|
23
|
+
```ruby
|
21
24
|
gem 'voluntary'
|
25
|
+
```
|
22
26
|
|
23
27
|
Add voluntary products to your Gemfile.
|
24
28
|
|
25
29
|
Run this in your console:
|
26
30
|
|
31
|
+
```bash
|
27
32
|
bundle install
|
33
|
+
```
|
28
34
|
|
29
35
|
Run this in your console (confirm all overwrite questions):
|
30
36
|
|
37
|
+
```bash
|
31
38
|
rails g voluntary:install
|
32
39
|
rake railties:install:migrations
|
40
|
+
```
|
33
41
|
|
34
42
|
Remove gem 'sqlite3' from your Gemfile.
|
35
43
|
|
@@ -37,9 +45,11 @@ Copy the content of config/database.example.yml into config/database.yml
|
|
37
45
|
|
38
46
|
Add this to your application.rb:
|
39
47
|
|
48
|
+
```ruby
|
40
49
|
config.generators do |g|
|
41
50
|
g.orm :active_record
|
42
51
|
end
|
52
|
+
```
|
43
53
|
|
44
54
|
Remove public/index.html
|
45
55
|
|
@@ -49,14 +59,17 @@ Add a Capfile to your Rails root.
|
|
49
59
|
|
50
60
|
Run this in your console:
|
51
61
|
|
62
|
+
```bash
|
52
63
|
bundle install
|
53
64
|
rake db:create
|
54
65
|
rake db:migrate
|
55
66
|
rake db:seed
|
56
67
|
rails s
|
68
|
+
```
|
57
69
|
|
58
|
-
|
59
|
-
|
70
|
+
### New Product
|
71
|
+
|
72
|
+
```bash
|
60
73
|
git clone https://github.com/user/voluntary_product_name.git
|
61
74
|
cd voluntary_product_name
|
62
75
|
rvm --create use --rvmrc 1.9.3@voluntary_product_name # if you use RVM
|
@@ -85,7 +98,8 @@ Run this in your console:
|
|
85
98
|
bundle exec rake db:migrate && bundle exec rake db:test:clone_structure
|
86
99
|
# create a class for your new product under app/models/product/product_name.rb like: https://github.com/volontariat/voluntary_scholarship/blob/master/app/models/product/scholarship.rb
|
87
100
|
bundle exec rails s
|
101
|
+
```
|
88
102
|
|
89
|
-
|
103
|
+
## License
|
90
104
|
|
91
105
|
This project uses MIT-LICENSE.
|
@@ -16,7 +16,7 @@ class CandidaturesController < ApplicationController
|
|
16
16
|
@candidatures = if @vacancy
|
17
17
|
@vacancy.candidatures.includes(:vacancy, :resource)
|
18
18
|
else
|
19
|
-
Candidature.includes(:vacancy, :resource).where(resource_type: 'User')
|
19
|
+
Candidature.includes(:vacancy, :resource).where(resource_type: 'User')
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
@@ -5,13 +5,6 @@ module Voluntary
|
|
5
5
|
#include ActionController::Rendering # enables rendering
|
6
6
|
#include ActionController::MimeResponds # enables serving different content types like :xml or :json
|
7
7
|
#include AbstractController::Callbacks # callbacks for your authentication logic
|
8
|
-
|
9
|
-
after_filter :set_access_control_headers
|
10
|
-
|
11
|
-
def set_access_control_headers
|
12
|
-
headers['Access-Control-Allow-Origin'] = '*'
|
13
|
-
headers['Access-Control-Request-Method'] = '*'
|
14
|
-
end
|
15
8
|
end
|
16
9
|
end
|
17
10
|
end
|
@@ -79,5 +79,22 @@ module Voluntary
|
|
79
79
|
def name_with_apostrophe(value)
|
80
80
|
value =~ /s$/i ? "#{value}'" : "#{value}'s"
|
81
81
|
end
|
82
|
+
|
83
|
+
def event_links_for_resource(current_resource, type)
|
84
|
+
return [] unless current_resource.respond_to? :state_events
|
85
|
+
|
86
|
+
links = []
|
87
|
+
|
88
|
+
current_resource.state_events.select{|event| can? event, current_resource }.each do |event|
|
89
|
+
path = "#{event}_#{type.singularize}_path"
|
90
|
+
|
91
|
+
next unless respond_to? path
|
92
|
+
|
93
|
+
path = eval("#{path}(current_resource)")
|
94
|
+
links << link_to(t("#{type}.show.events.#{event}"), path, method: :put)
|
95
|
+
end
|
96
|
+
|
97
|
+
links
|
98
|
+
end
|
82
99
|
end
|
83
100
|
end
|
data/app/models/area.rb
CHANGED
@@ -6,6 +6,17 @@ class Area < ActiveRecord::Base
|
|
6
6
|
has_and_belongs_to_many :users
|
7
7
|
has_and_belongs_to_many :projects
|
8
8
|
|
9
|
+
scope :with_projects_for_product, ->(product_id) do
|
10
|
+
select('DISTINCT(areas.id), areas.*').joins(%Q{
|
11
|
+
LEFT JOIN areas areas2 ON areas2.id = areas.id OR areas2.ancestry like CONCAT(areas.id, '/', '%')
|
12
|
+
OR areas2.ancestry like CONCAT('%', '/', areas.id)
|
13
|
+
OR areas2.ancestry like CONCAT('%', '/', areas.id, '/', '%')
|
14
|
+
OR areas2.ancestry = CONCAT(areas.id, '')
|
15
|
+
LEFT JOIN areas_projects ON areas_projects.area_id = areas2.id
|
16
|
+
LEFT JOIN projects ON projects.id = areas_projects.project_id
|
17
|
+
}).where('areas2.id IS NOT NULL AND projects.product_id = ?', product_id)
|
18
|
+
end
|
19
|
+
|
9
20
|
validates :name, presence: true, uniqueness: true
|
10
21
|
|
11
22
|
attr_accessible :name, :parent_id
|
@@ -15,11 +26,13 @@ class Area < ActiveRecord::Base
|
|
15
26
|
friendly_id :name, :use => :slugged
|
16
27
|
|
17
28
|
def self.find_by_product_id(product_id)
|
18
|
-
roots.joins(:projects).merge(Project.for_product_id(product_id))
|
29
|
+
#roots.joins(:projects).merge(Project.for_product_id(product_id))
|
30
|
+
roots.with_projects_for_product(product_id)
|
19
31
|
end
|
20
32
|
|
21
33
|
def children_for_product_id(product_id)
|
22
|
-
children.joins(:projects).merge(Project.for_product_id(product_id))
|
34
|
+
#children.joins(:projects).merge(Project.for_product_id(product_id))
|
35
|
+
children.with_projects_for_product(product_id)
|
23
36
|
end
|
24
37
|
|
25
38
|
def products
|
@@ -10,7 +10,10 @@ module Likeable
|
|
10
10
|
has_many :dislikers, class_name: 'User', through: :dislikes, source: :user
|
11
11
|
|
12
12
|
scope :liked_by, ->(user_id) do
|
13
|
-
positive_likes_string = if
|
13
|
+
positive_likes_string = if (
|
14
|
+
defined?(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter) &&
|
15
|
+
ActiveRecord::Base.connection.instance_of?(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)
|
16
|
+
)
|
14
17
|
"likes.positive = 't'"
|
15
18
|
else
|
16
19
|
'likes.positive = 1'
|
data/app/models/product.rb
CHANGED
data/app/models/role.rb
CHANGED
@@ -8,6 +8,8 @@ module StateMachines::Candidature
|
|
8
8
|
const_set 'STATES', [:new, :accepted, :denied]
|
9
9
|
const_set 'EVENTS', [:accept, :deny, :quit]
|
10
10
|
|
11
|
+
after_initialize :set_initial_state
|
12
|
+
|
11
13
|
state_machine :state, initial: :new do
|
12
14
|
event :accept do
|
13
15
|
transition [:new, :denied] => :accepted
|
@@ -50,6 +52,10 @@ module StateMachines::Candidature
|
|
50
52
|
errors[:state] << I18n.t('activerecord.errors.models.vacancy.attributes.limit.reached')
|
51
53
|
end
|
52
54
|
end
|
55
|
+
|
56
|
+
def set_initial_state
|
57
|
+
self.state ||= :new
|
58
|
+
end
|
53
59
|
end
|
54
60
|
end
|
55
61
|
|
@@ -8,8 +8,16 @@ module StateMachines::Page
|
|
8
8
|
const_set 'STATES', [:active]
|
9
9
|
const_set 'EVENTS', []
|
10
10
|
|
11
|
+
after_initialize :set_initial_state
|
12
|
+
|
11
13
|
state_machine :state, initial: :active do
|
12
14
|
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def set_initial_state
|
19
|
+
self.state ||= :active
|
20
|
+
end
|
13
21
|
end
|
14
22
|
end
|
15
23
|
|
@@ -10,6 +10,8 @@ module StateMachines::Story
|
|
10
10
|
const_set 'STATES', [:new, :tasks_defined, :active, :completed, :closed]
|
11
11
|
const_set 'EVENTS', [:initialization, :setup_tasks, :activate, :complete]
|
12
12
|
|
13
|
+
after_initialize :set_initial_state
|
14
|
+
|
13
15
|
state_machine :state, initial: :new do
|
14
16
|
event :initialization do
|
15
17
|
transition :new => :initialized
|
@@ -44,6 +46,10 @@ module StateMachines::Story
|
|
44
46
|
|
45
47
|
private
|
46
48
|
|
49
|
+
def set_initial_state
|
50
|
+
self.state ||= :new
|
51
|
+
end
|
52
|
+
|
47
53
|
def presence_of_tasks
|
48
54
|
self.tasks.delete_if{|t| t.name.blank? && t.text.blank? }
|
49
55
|
|
@@ -10,6 +10,8 @@ module StateMachines::Task
|
|
10
10
|
const_set 'STATES', [:new, :assigned, :under_supervision, :completed]
|
11
11
|
const_set 'EVENTS', [:assign, :cancel, :review, :follow_up, :complete]
|
12
12
|
|
13
|
+
after_initialize :set_initial_state
|
14
|
+
|
13
15
|
state_machine :state, initial: :new do
|
14
16
|
event :assign do
|
15
17
|
transition :new => :assigned
|
@@ -74,6 +76,12 @@ module StateMachines::Task
|
|
74
76
|
end
|
75
77
|
end
|
76
78
|
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def set_initial_state
|
83
|
+
self.state ||= :new
|
84
|
+
end
|
77
85
|
end
|
78
86
|
end
|
79
87
|
end
|
@@ -8,6 +8,8 @@ module StateMachines::Vacancy
|
|
8
8
|
const_set 'STATES', [:open, :recommended, :denied, :closed]
|
9
9
|
const_set 'EVENTS', [:accept_recommendation, :deny_recommendation, :close, :reopen]
|
10
10
|
|
11
|
+
after_initialize :set_initial_state
|
12
|
+
|
11
13
|
state_machine :state, initial: :new do
|
12
14
|
event :recommend do
|
13
15
|
transition :new => :recommended
|
@@ -33,6 +35,12 @@ module StateMachines::Vacancy
|
|
33
35
|
transition [:denied, :closed] => :open
|
34
36
|
end
|
35
37
|
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def set_initial_state
|
42
|
+
self.state ||= :new
|
43
|
+
end
|
36
44
|
end
|
37
45
|
end
|
38
46
|
|
data/app/models/story.rb
CHANGED
@@ -15,6 +15,8 @@ class Story
|
|
15
15
|
|
16
16
|
accepts_nested_attributes_for :tasks, allow_destroy: true, reject_if: ->(t) { t['name'].blank? && t['text'].blank? }
|
17
17
|
|
18
|
+
# see https://github.com/mongoid/mongoid/issues/2222
|
19
|
+
field(:_type, default: ->{ self.class.name }, type: String)
|
18
20
|
field :project_id, type: Integer
|
19
21
|
field :offeror_id, type: Integer
|
20
22
|
field :name, type: String
|
@@ -37,10 +37,11 @@
|
|
37
37
|
<% if can? :edit, product %>
|
38
38
|
<li><%= link_to t('general.edit'), eval("edit_product_path(product)") %></li>
|
39
39
|
<% end %>
|
40
|
-
<%
|
41
|
-
|
42
|
-
|
43
|
-
|
40
|
+
<% links = event_links_for_resource(product, 'products') %>
|
41
|
+
<% if links.any? %>
|
42
|
+
<li class="divider"></li>
|
43
|
+
<%= render 'shared/resource/event_elements', links: links %>
|
44
|
+
<% end %>
|
44
45
|
</ul>
|
45
46
|
</div>
|
46
47
|
<% end %>
|
@@ -21,10 +21,11 @@
|
|
21
21
|
<% if can? :edit, resource %>
|
22
22
|
<li><%= link_to t('general.edit'), eval("edit_#{(namespace.present? ? namespace.to_s + '_' : '')}#{type.gsub('/', '_').singularize}_path(resource)") %></li>
|
23
23
|
<% end %>
|
24
|
-
<%
|
25
|
-
|
24
|
+
<% links = event_links_for_resource(resource, type) %>
|
25
|
+
<% if links.any? %>
|
26
|
+
<li class="divider"></li>
|
27
|
+
<%= render 'shared/resource/event_elements', links: links %>
|
26
28
|
<% end %>
|
27
|
-
<%= render 'shared/resource/event_elements', resource: resource, type: type %>
|
28
29
|
</ul>
|
29
30
|
</div>
|
30
31
|
<% end %>
|
@@ -1,7 +1,5 @@
|
|
1
|
-
<%
|
2
|
-
<% resource.state_events.select{|event| can? event, resource }.each do |event| %>
|
1
|
+
<% links.each do |link| %>
|
3
2
|
<li>
|
4
|
-
<%=
|
3
|
+
<%= raw link %>
|
5
4
|
</li>
|
6
|
-
<% end %>
|
7
5
|
<% end %>
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
<%= simple_form_for(current_user, url: preferences_user_path(current_user), html: { class: 'form-horizontal block-form' }) do |f| %>
|
4
4
|
<div class="form-inputs">
|
5
|
-
<%= f.input :main_role_id, collection: Role.
|
5
|
+
<%= f.input :main_role_id, collection: Role.is_public %>
|
6
6
|
</div>
|
7
7
|
|
8
8
|
<div class="form-actions">
|
@@ -1,4 +1,21 @@
|
|
1
|
-
|
1
|
+
<% content_for :breadcrumbs do %>
|
2
|
+
<% product_key = nil %>
|
3
|
+
<% Voluntary::Navigation::Base.products.each{|s,k| product_key = k if s == params[:product_id] } %>
|
4
|
+
<%= raw(
|
5
|
+
(
|
6
|
+
[
|
7
|
+
link_to(t('workflow.index.title'), workflow_path),
|
8
|
+
link_to(t('workflow.user.index.title'), workflow_user_index_path),
|
9
|
+
link_to(t(product_key), product_workflow_user_index_path(params[:product_id]))
|
10
|
+
] +
|
11
|
+
(@area.ancestors + [@area]).map do |a|
|
12
|
+
link_to(a.name, product_area_workflow_user_index_path(params[:product_id], a))
|
13
|
+
end
|
14
|
+
).join(' > ')
|
15
|
+
) %>
|
16
|
+
<% end %>
|
17
|
+
|
18
|
+
<h3><%= @area.name %></h3>
|
2
19
|
|
3
20
|
<%= render 'shared/collection/table',
|
4
21
|
type: 'areas', collection: @areas, columns: {
|
@@ -0,0 +1 @@
|
|
1
|
+
Rails.application.config.action_dispatch.cookies_serializer = :json
|