Commit 00b280c3 authored by randx's avatar randx

Feature: Bulk Issues update

parent d63706d7
...@@ -52,14 +52,6 @@ $(document).ready(function(){ ...@@ -52,14 +52,6 @@ $(document).ready(function(){
} }
}); });
$("#issues-table .issue").live('click', function(e){
if(e.target.nodeName != "A" && e.target.nodeName != "INPUT") {
location.href = $(this).attr("url");
e.stopPropagation();
return false;
}
});
/** /**
* Focus search field by pressing 's' key * Focus search field by pressing 's' key
*/ */
......
...@@ -67,6 +67,10 @@ function initIssuesSearch() { ...@@ -67,6 +67,10 @@ function initIssuesSearch() {
*/ */
function issuesPage(){ function issuesPage(){
initIssuesSearch(); initIssuesSearch();
$("#update_status").chosen();
$("#update_assignee_id").chosen();
$("#update_milestone_id").chosen();
$("#label_name").chosen(); $("#label_name").chosen();
$("#assignee_id").chosen(); $("#assignee_id").chosen();
$("#milestone_id").chosen(); $("#milestone_id").chosen();
...@@ -94,4 +98,29 @@ function issuesPage(){ ...@@ -94,4 +98,29 @@ function issuesPage(){
}); });
}); });
$(".check_all_issues").click(function () {
$('.selected_issue').attr('checked', this.checked);
issuesCheckChanged();
});
$('.selected_issue').bind('change', issuesCheckChanged);
}
function issuesCheckChanged() {
var checked_issues = $('.selected_issue:checked');
if(checked_issues.length > 0) {
var ids = []
$.each(checked_issues, function(index, value) {
ids.push($(value).attr("data-id"));
})
$('#update_issues_ids').val(ids);
$('.issues_filters').hide();
$('.issues_bulk_update').show();
} else {
$('#update_issues_ids').val([]);
$('.issues_bulk_update').hide();
$('.issues_filters').show();
}
} }
...@@ -30,6 +30,13 @@ ...@@ -30,6 +30,13 @@
.issue { .issue {
padding:7px 10px; padding:7px 10px;
.issue_check {
float:left;
padding: 8px 0;
padding-right: 8px;
min-width: 15px;
}
p { p {
padding-top:0; padding-top:0;
padding-bottom:2px; padding-bottom:2px;
...@@ -41,3 +48,28 @@ ...@@ -41,3 +48,28 @@
} }
} }
} }
input.check_all_issues {
float:left;
padding: 8px 0;
margin: 14px 0;
margin-right: 10px;
}
#issues-table-holder {
.issues_bulk_update {
padding: 0 5px;
margin: 0;
form {
margin:0;
padding-bottom:5px;
}
.update_selected_issues {
position:relative;
top:-2px;
margin-left:3px;
}
}
}
...@@ -4,5 +4,17 @@ class BaseContext ...@@ -4,5 +4,17 @@ class BaseContext
def initialize(project, user, params) def initialize(project, user, params)
@project, @current_user, @params = project, user, params.dup @project, @current_user, @params = project, user, params.dup
end end
def abilities
@abilities ||= begin
abilities = Six.new
abilities << Ability
abilities
end
end
def can?(object, action, subject)
abilities.allowed?(object, action, subject)
end
end end
class IssuesBulkUpdateContext < BaseContext
def execute
update_data = params[:update]
issues_ids = update_data[:issues_ids].split(",")
milestone_id = update_data[:milestone_id]
assignee_id = update_data[:assignee_id]
status = update_data[:status]
opts = {}
opts[:milestone_id] = milestone_id if milestone_id.present?
opts[:assignee_id] = assignee_id if assignee_id.present?
opts[:closed] = (status == "closed") if status.present?
issues = Issue.where(:id => issues_ids).all
issues = issues.select { |issue| can?(current_user, :modify_issue, issue) }
issues.each { |issue| issue.update_attributes(opts) }
{
:count => issues.count,
:success => !issues.count.zero?
}
end
end
...@@ -113,6 +113,11 @@ class IssuesController < ApplicationController ...@@ -113,6 +113,11 @@ class IssuesController < ApplicationController
render :partial => 'issues' render :partial => 'issues'
end end
def bulk_update
result = IssuesBulkUpdateContext.new(project, current_user, params).execute
redirect_to :back, :notice => "#{result[:count]} issues updated"
end
protected protected
def issue def issue
......
...@@ -12,3 +12,4 @@ ...@@ -12,3 +12,4 @@
- else - else
%li %li
%h4.nothing_here_message Nothing to show here %h4.nothing_here_message Nothing to show here
%li.wll{ :id => dom_id(issue), :class => issue_css_classes(issue), :url => project_issue_path(issue.project, issue) } %li.wll{ :id => dom_id(issue), :class => issue_css_classes(issue), :url => project_issue_path(issue.project, issue) }
.list_legend .issue_check
.icon = check_box_tag dom_id(issue,"selected"), nil, false, 'data-id' => issue.id, :class => "selected_issue", :disabled => !can?(current_user, :modify_issue, issue)
.right .right
- issue.labels.each do |label| - issue.labels.each do |label|
%span.label.label-issue.grouped %span.label.label-issue.grouped
......
...@@ -14,8 +14,23 @@ ...@@ -14,8 +14,23 @@
= search_field_tag :issue_search, nil, { :placeholder => 'Search', :class => 'issue_search span3 right neib' } = search_field_tag :issue_search, nil, { :placeholder => 'Search', :class => 'issue_search span3 right neib' }
.clearfix .clearfix
%div#issues-table-holder.ui-box %div#issues-table-holder.ui-box
.title .title
= check_box_tag "check_all_issues", nil, false, :class => "check_all_issues left"
.issues_bulk_update.hide
= form_tag bulk_update_project_issues_path(@project), :method => :post do
%span Update selected issues with
&nbsp;
= select_tag('update[status]', options_for_select(['open', 'closed']), :prompt => "Status")
= select_tag('update[assignee_id]', options_from_collection_for_select(@project.users.all, "id", "name", params[:assignee_id]), :prompt => "Assignee")
= select_tag('update[milestone_id]', options_from_collection_for_select(@project.milestones.order("id desc").all, "id", "title", params[:milestone_id]), :prompt => "Milestone")
= hidden_field_tag 'update[issues_ids]', []
= hidden_field_tag :f, params[:f]
= button_tag "Save", :class => "btn update_selected_issues"
.issues_filters
.left .left
%ul.nav.nav-pills.left %ul.nav.nav-pills.left
%li{:class => ("active" if (params[:f] == issues_filter[:open] || !params[:f]))} %li{:class => ("active" if (params[:f] == issues_filter[:open] || !params[:f]))}
...@@ -42,6 +57,7 @@ ...@@ -42,6 +57,7 @@
%ul#issues-table.unstyled.issues_table %ul#issues-table.unstyled.issues_table
= render "issues" = render "issues"
:javascript :javascript
$(function(){ $(function(){
issuesPage(); issuesPage();
......
...@@ -194,6 +194,7 @@ Gitlab::Application.routes.draw do ...@@ -194,6 +194,7 @@ Gitlab::Application.routes.draw do
resources :issues do resources :issues do
collection do collection do
post :sort post :sort
post :bulk_update
get :search get :search
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment