Commit 705d3c4a24cf15a5fd8e5751117225cbf2de69df
Exists in
master
and in
8 other branches
Merge with branch proposal_task_category
Showing
9 changed files
with
201 additions
and
16 deletions
Show diff stats
controllers/myprofile/proposals_discussion_plugin_confirm_tasks_controller.rb
| @@ -27,7 +27,7 @@ private | @@ -27,7 +27,7 @@ private | ||
| 27 | if params[:task_id] and request.post? | 27 | if params[:task_id] and request.post? |
| 28 | begin | 28 | begin |
| 29 | task = profile.find_in_all_tasks(params[:task_id]) | 29 | task = profile.find_in_all_tasks(params[:task_id]) |
| 30 | - task.tag_list = params[:tag_list] | 30 | + task.tag_list = params[:tag_list] if params[:tag_list].presence |
| 31 | task.article_parent_id = params[:article_parent_id] if decision.to_s == 'finish' | 31 | task.article_parent_id = params[:article_parent_id] if decision.to_s == 'finish' |
| 32 | task.email_template_id = params[:email_template_id] | 32 | task.email_template_id = params[:email_template_id] |
| 33 | task.send(decision, current_person) | 33 | task.send(decision, current_person) |
controllers/myprofile/proposals_discussion_plugin_evaluate_tasks_controller.rb
| @@ -11,10 +11,19 @@ class ProposalsDiscussionPluginEvaluateTasksController < MyProfileController | @@ -11,10 +11,19 @@ class ProposalsDiscussionPluginEvaluateTasksController < MyProfileController | ||
| 11 | 11 | ||
| 12 | 12 | ||
| 13 | task = Task.to(profile).find_by_id params[:task_id] | 13 | task = Task.to(profile).find_by_id params[:task_id] |
| 14 | - save = task.flag_accept_proposal(current_person) | ||
| 15 | 14 | ||
| 16 | - if save | ||
| 17 | - result = {:success => true } | 15 | + begin |
| 16 | + | ||
| 17 | + save = task.flag_accept_proposal(current_person) | ||
| 18 | + | ||
| 19 | + if save | ||
| 20 | + result = {:success => true } | ||
| 21 | + end | ||
| 22 | + rescue ActiveRecord::RecordInvalid => e | ||
| 23 | + result = { | ||
| 24 | + :success => false, | ||
| 25 | + :message => e.message | ||
| 26 | + } | ||
| 18 | end | 27 | end |
| 19 | end | 28 | end |
| 20 | 29 | ||
| @@ -30,10 +39,18 @@ class ProposalsDiscussionPluginEvaluateTasksController < MyProfileController | @@ -30,10 +39,18 @@ class ProposalsDiscussionPluginEvaluateTasksController < MyProfileController | ||
| 30 | } | 39 | } |
| 31 | 40 | ||
| 32 | task = Task.to(profile).find_by_id params[:task_id] | 41 | task = Task.to(profile).find_by_id params[:task_id] |
| 33 | - save = task.flag_reject_proposal(current_person) | ||
| 34 | 42 | ||
| 35 | - if save | ||
| 36 | - result = {:success => true } | 43 | + begin |
| 44 | + save = task.flag_reject_proposal(current_person) | ||
| 45 | + | ||
| 46 | + if save | ||
| 47 | + result = {:success => true } | ||
| 48 | + end | ||
| 49 | + rescue ActiveRecord::RecordInvalid => e | ||
| 50 | + result = { | ||
| 51 | + :success => false, | ||
| 52 | + :message => e.message | ||
| 53 | + } | ||
| 37 | end | 54 | end |
| 38 | end | 55 | end |
| 39 | 56 |
controllers/myprofile/proposals_discussion_plugin_tasks_controller.rb
| @@ -7,13 +7,13 @@ class ProposalsDiscussionPluginTasksController < TasksController | @@ -7,13 +7,13 @@ class ProposalsDiscussionPluginTasksController < TasksController | ||
| 7 | @filter_type = params[:filter_type].presence | 7 | @filter_type = params[:filter_type].presence |
| 8 | @filter_text = params[:filter_text].presence | 8 | @filter_text = params[:filter_text].presence |
| 9 | @filter_responsible = params[:filter_responsible] | 9 | @filter_responsible = params[:filter_responsible] |
| 10 | - @filter_tags = params[:filter_tags] | 10 | + @filter_categories = params[:filter_categories] |
| 11 | 11 | ||
| 12 | @filter_status = params[:filter_status] | 12 | @filter_status = params[:filter_status] |
| 13 | 13 | ||
| 14 | @view_only = !current_person.has_permission?(:perform_task, profile) || params[:view_only] | 14 | @view_only = !current_person.has_permission?(:perform_task, profile) || params[:view_only] |
| 15 | 15 | ||
| 16 | - @task_tags = [OpenStruct.new(:name => _('All'), :id => nil) ] + Task.all_tags | 16 | + @task_categories = [OpenStruct.new(:name => _('All'), :id => nil) ] + ProposalsDiscussionPlugin::TaskCategory.all |
| 17 | @task_types = Task.pending_types_for(profile) | 17 | @task_types = Task.pending_types_for(profile) |
| 18 | 18 | ||
| 19 | # maps statuses which would be used in status filter | 19 | # maps statuses which would be used in status filter |
| @@ -34,8 +34,6 @@ class ProposalsDiscussionPluginTasksController < TasksController | @@ -34,8 +34,6 @@ class ProposalsDiscussionPluginTasksController < TasksController | ||
| 34 | 34 | ||
| 35 | @tasks = @tasks.where(:responsible_id => @filter_responsible.to_i != -1 ? @filter_responsible : nil) if @filter_responsible.present? | 35 | @tasks = @tasks.where(:responsible_id => @filter_responsible.to_i != -1 ? @filter_responsible : nil) if @filter_responsible.present? |
| 36 | 36 | ||
| 37 | - @tasks = @tasks.tagged_with(@filter_tags, any: true) if @filter_tags.present? | ||
| 38 | - | ||
| 39 | end | 37 | end |
| 40 | 38 | ||
| 41 | @tasks = @tasks.paginate(:per_page => Task.per_page, :page => params[:page]) | 39 | @tasks = @tasks.paginate(:per_page => Task.per_page, :page => params[:page]) |
| @@ -45,4 +43,35 @@ class ProposalsDiscussionPluginTasksController < TasksController | @@ -45,4 +43,35 @@ class ProposalsDiscussionPluginTasksController < TasksController | ||
| 45 | @responsible_candidates = profile.members.by_role(profile.roles.reject {|r| !r.has_permission?('perform_task')}) if profile.organization? | 43 | @responsible_candidates = profile.members.by_role(profile.roles.reject {|r| !r.has_permission?('perform_task')}) if profile.organization? |
| 46 | end | 44 | end |
| 47 | 45 | ||
| 46 | + def save_categories | ||
| 47 | + | ||
| 48 | + if request.post? && params[:tag_list].presence | ||
| 49 | + result = { | ||
| 50 | + success: false, | ||
| 51 | + message: _('Error to save categories. Please, contact the system admin') | ||
| 52 | + } | ||
| 53 | + | ||
| 54 | + categories_list = params[:tag_list].split(',') | ||
| 55 | + task = Task.to(profile).find_by_id params[:task_id] | ||
| 56 | + | ||
| 57 | + categories_data = [] | ||
| 58 | + categories_list.each do |category_name| | ||
| 59 | + category = ProposalsDiscussionPlugin::TaskCategory.find_by_name(category_name) | ||
| 60 | + categories_data << category | ||
| 61 | + end | ||
| 62 | + task.categories = categories_data | ||
| 63 | + save = task.save! | ||
| 64 | + | ||
| 65 | + if save | ||
| 66 | + result = { | ||
| 67 | + success: true, | ||
| 68 | + message: _('Saved with success!') | ||
| 69 | + } | ||
| 70 | + end | ||
| 71 | + end | ||
| 72 | + | ||
| 73 | + render json: result | ||
| 74 | + | ||
| 75 | + end | ||
| 76 | + | ||
| 48 | end | 77 | end |
| @@ -0,0 +1,13 @@ | @@ -0,0 +1,13 @@ | ||
| 1 | +class CreateTasksCategories < ActiveRecord::Migration | ||
| 2 | + def up | ||
| 3 | + create_table :proposals_discussion_plugin_task_categories, id: false do |t| | ||
| 4 | + t.belongs_to :task, index: true | ||
| 5 | + t.belongs_to :category, index: true | ||
| 6 | + | ||
| 7 | + end | ||
| 8 | + end | ||
| 9 | + | ||
| 10 | + def down | ||
| 11 | + drop_table :proposals_discussion_plugin_task_categories | ||
| 12 | + end | ||
| 13 | +end |
lib/proposals_discussion_plugin/proposal_task.rb
| 1 | class ProposalsDiscussionPlugin::ProposalTask < Task | 1 | class ProposalsDiscussionPlugin::ProposalTask < Task |
| 2 | 2 | ||
| 3 | + has_and_belongs_to_many :categories, | ||
| 4 | + class_name: "ProposalsDiscussionPlugin::TaskCategory", | ||
| 5 | + join_table: :proposals_discussion_plugin_task_categories, | ||
| 6 | + foreign_key: :task_id, | ||
| 7 | + association_foreign_key: :category_id | ||
| 8 | + | ||
| 3 | validates_presence_of :requestor_id, :target_id | 9 | validates_presence_of :requestor_id, :target_id |
| 4 | validates_associated :article_object | 10 | validates_associated :article_object |
| 5 | 11 | ||
| 12 | + validate :require_category | ||
| 13 | + | ||
| 6 | settings_items :name, :type => String | 14 | settings_items :name, :type => String |
| 7 | settings_items :ip_address, :type => String | 15 | settings_items :ip_address, :type => String |
| 8 | settings_items :user_agent, :type => String | 16 | settings_items :user_agent, :type => String |
| @@ -284,4 +292,16 @@ class ProposalsDiscussionPlugin::ProposalTask < Task | @@ -284,4 +292,16 @@ class ProposalsDiscussionPlugin::ProposalTask < Task | ||
| 284 | 292 | ||
| 285 | alias_method_chain :to_liquid, :proposal_task | 293 | alias_method_chain :to_liquid, :proposal_task |
| 286 | 294 | ||
| 295 | + def categories_list(field = :name) | ||
| 296 | + categories.pluck(field).join(',') if categories.count > 0 | ||
| 297 | + end | ||
| 298 | + | ||
| 299 | + protected | ||
| 300 | + | ||
| 301 | + def require_category | ||
| 302 | + if categories.count == 0 && flagged? | ||
| 303 | + errors.add :categories, _('Select at least one category') | ||
| 304 | + end | ||
| 305 | + end | ||
| 306 | + | ||
| 287 | end | 307 | end |
| @@ -0,0 +1,76 @@ | @@ -0,0 +1,76 @@ | ||
| 1 | +require_relative '../test_helper' | ||
| 2 | + | ||
| 3 | +class TaskCategoryTest < ActiveSupport::TestCase | ||
| 4 | + | ||
| 5 | + def setup | ||
| 6 | + @person = fast_create(Person) | ||
| 7 | + @profile = fast_create(Community) | ||
| 8 | + @discussion = ProposalsDiscussionPlugin::Discussion.create!(:name => 'discussion', :profile => @person, :name => 'discussion') | ||
| 9 | + @proposal = ProposalsDiscussionPlugin::Proposal.create!(:name => 'test', :abstract => 'abstract', :profile => @profile, :parent => @discussion) | ||
| 10 | + end | ||
| 11 | + | ||
| 12 | + attr_reader :person, :profile, :discussion, :proposal | ||
| 13 | + | ||
| 14 | + should 'add a category to a task' do | ||
| 15 | + | ||
| 16 | + task_data = { | ||
| 17 | + article: {name: "test proposal", abstract: "teste adadd"}, | ||
| 18 | + requestor: person, | ||
| 19 | + target: profile, | ||
| 20 | + spam: false | ||
| 21 | + } | ||
| 22 | + | ||
| 23 | + task = ProposalsDiscussionPlugin::ProposalTask.new task_data | ||
| 24 | + | ||
| 25 | + category = ProposalsDiscussionPlugin::TaskCategory.create!(name: 'ProposalTest', environment: Environment.default) | ||
| 26 | + | ||
| 27 | + category.tasks << task; | ||
| 28 | + category.save! | ||
| 29 | + | ||
| 30 | + assert_equal task.id, category.tasks[0].id | ||
| 31 | + end | ||
| 32 | + | ||
| 33 | + should 'approve a proposal task without category' do | ||
| 34 | + | ||
| 35 | + task_data = { | ||
| 36 | + article: {name: "test proposal", abstract: "teste adadd"}, | ||
| 37 | + requestor: person, | ||
| 38 | + target: profile, | ||
| 39 | + spam: false | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + task = ProposalsDiscussionPlugin::ProposalTask.create! task_data | ||
| 43 | + evaluated_by = false | ||
| 44 | + | ||
| 45 | + assert_raise(ActiveRecord::RecordInvalid) { task.flag_accept_proposal evaluated_by } | ||
| 46 | + | ||
| 47 | + end | ||
| 48 | + | ||
| 49 | + should 'approve a proposal task with categories' do | ||
| 50 | + | ||
| 51 | + task_data = { | ||
| 52 | + article: {name: "test proposal", abstract: "teste adadd"}, | ||
| 53 | + requestor: person, | ||
| 54 | + target: profile, | ||
| 55 | + spam: false | ||
| 56 | + } | ||
| 57 | + task = ProposalsDiscussionPlugin::ProposalTask.create! task_data | ||
| 58 | + evaluated_by = false | ||
| 59 | + | ||
| 60 | + categories = [ | ||
| 61 | + { name: 'ProposalTest', environment: Environment.default }, | ||
| 62 | + { name: 'ProposalTestTwo', environment: Environment.default } | ||
| 63 | + ] | ||
| 64 | + categories.each do |category| | ||
| 65 | + task.categories << ProposalsDiscussionPlugin::TaskCategory.new(category) | ||
| 66 | + end | ||
| 67 | + | ||
| 68 | + assert_nothing_raised do | ||
| 69 | + task.flag_accept_proposal evaluated_by | ||
| 70 | + end | ||
| 71 | + | ||
| 72 | + assert_equal 2, task.categories.count | ||
| 73 | + | ||
| 74 | + end | ||
| 75 | + | ||
| 76 | +end |
views/proposals_discussion_plugin_tasks/_task.html.erb
| @@ -61,7 +61,10 @@ | @@ -61,7 +61,10 @@ | ||
| 61 | 61 | ||
| 62 | <div class="formfieldline"> | 62 | <div class="formfieldline"> |
| 63 | <div class="formfield tag-list-fields"> | 63 | <div class="formfield tag-list-fields"> |
| 64 | - <%= labelled_text_field(_('Tags'),"tasks[#{task.id}][task][tag_list]", task.tags_from(nil).to_s, :size => 36, :class => 'tag-list','data-submit-values'=>"{'task_id':'#{task.id}'}") %> | 64 | + <p> |
| 65 | + <%= labelled_select(_('Categories')+': ', :select_category, :id, :name, @filter_categories, @task_categories, {:class => 'add-category'}) %> | ||
| 66 | + <%= text_field_tag( :categories_list, task.categories_list, :size => 36,:id => '', :class => 'task-categories', 'data-submit-values'=>"{'task_id':'#{task.id}'}") %> | ||
| 67 | + </p> | ||
| 65 | </div> | 68 | </div> |
| 66 | </div> | 69 | </div> |
| 67 | 70 |
views/proposals_discussion_plugin_tasks/index.html.erb
| @@ -38,10 +38,6 @@ | @@ -38,10 +38,6 @@ | ||
| 38 | <p> | 38 | <p> |
| 39 | <%= labelled_select(_('Status')+': ', :filter_status, :id, :name, @filter_status, @task_statuses, {:id => 'filter-statuses'}) %> | 39 | <%= labelled_select(_('Status')+': ', :filter_status, :id, :name, @filter_status, @task_statuses, {:id => 'filter-statuses'}) %> |
| 40 | </p> | 40 | </p> |
| 41 | - <p> | ||
| 42 | - <%= labelled_select(_('Tags')+': ', :filter_tags, :id, :name, @filter_tags, @task_tags, {:id => 'filter-add-tag'}) %> | ||
| 43 | - <%= text_field_tag( :filter_tags, @filter_tags, :size => 36, :class => 'filter-tags' ) %> | ||
| 44 | - </p> | ||
| 45 | 41 | ||
| 46 | <p> | 42 | <p> |
| 47 | <%= submit_button(:search, _('Search')) %> | 43 | <%= submit_button(:search, _('Search')) %> |
| @@ -198,4 +194,31 @@ | @@ -198,4 +194,31 @@ | ||
| 198 | } | 194 | } |
| 199 | }); | 195 | }); |
| 200 | } | 196 | } |
| 197 | + | ||
| 198 | + jQuery('.task-categories').inputosaurus({ | ||
| 199 | + hideInput: true, | ||
| 200 | + submitTags: { | ||
| 201 | + url: '/myprofile/'+<%= "'#{profile.identifier}'" %>+'/plugin/proposals_discussion/tasks/save_categories', | ||
| 202 | + beforeSend: function(){ | ||
| 203 | + | ||
| 204 | + $('.ok').parent().remove(); | ||
| 205 | + | ||
| 206 | + this.element.parents('.task_box') | ||
| 207 | + .prev('.fg-state-error') | ||
| 208 | + .remove(); | ||
| 209 | + | ||
| 210 | + Task.addIcon(this,'loading'); | ||
| 211 | + | ||
| 212 | + //Add loading here! | ||
| 213 | + }, | ||
| 214 | + success: Task.onAddTag | ||
| 215 | + } | ||
| 216 | + }); | ||
| 217 | + | ||
| 218 | + $('.add-category').change(function(){ | ||
| 219 | + | ||
| 220 | + if($(this).val() != ''){ | ||
| 221 | + $(this).next('ul').find('.task-categories').inputosaurus('addTags',$(this).children(':selected').text()); | ||
| 222 | + } | ||
| 223 | + }); | ||
| 201 | </script> | 224 | </script> |