Merge pull request #271 from warpc/194-issue_page
#194 Управление назначением исполнителя и метками задачи
This commit is contained in:
commit
2735b324ac
|
@ -119,8 +119,7 @@ $(document).ready(function() {
|
|||
url: $(this).attr("action"),
|
||||
data: $(this).serialize(),
|
||||
success: function(data){
|
||||
var tmp = $('#create_issue_'+ which +'_list');
|
||||
$('#create_issue_'+ which +'_list').html(data);
|
||||
$('#manage_issue_'+ which +'_list').html(data);
|
||||
},
|
||||
error: function(data){
|
||||
alert('error') // TODO remove
|
||||
|
@ -132,20 +131,23 @@ $(document).ready(function() {
|
|||
function remExecutor(form) {
|
||||
var el = form.find('.people.selected.remove_executor');
|
||||
var id = el.attr('id');
|
||||
$('#'+id+'.add_executor.people.selected').removeClass('select');
|
||||
$('#manage_issue_users_list .add_executor.people.selected').removeClass('select');
|
||||
el.remove();
|
||||
}
|
||||
|
||||
$('.add_executor.people.selected').live('click', function() {
|
||||
var form = $('.form.issue');
|
||||
form.find('#people-span').fadeOut(0);
|
||||
remExecutor(form);
|
||||
form.find('#issue_executor').html($(this).clone().removeClass('add_executor').addClass('remove_executor'));
|
||||
var form_new = $('form.issue');
|
||||
var form_edit = $('form.edit_form.issue');
|
||||
form_new.find('#people-span').fadeOut(0);
|
||||
remExecutor(form_new);
|
||||
var clone = $(this).clone().removeClass('add_executor').addClass('remove_executor');
|
||||
form_new.find('#issue_executor').html(clone);
|
||||
$('.current_executor').html(clone.removeClass('select'));
|
||||
$(this).addClass('select');
|
||||
});
|
||||
|
||||
$('.remove_executor.people.selected').live('click', function() {
|
||||
var form = $('.form.issue');
|
||||
var form = $('form.issue, form.edit_form issue');
|
||||
form.find('#people-span').fadeIn(0);
|
||||
remExecutor(form);
|
||||
});
|
||||
|
@ -165,23 +167,28 @@ $(document).ready(function() {
|
|||
var style = $(this).find('.flag').attr('style');
|
||||
$(this).find('.flag').fadeOut(0);
|
||||
$(this).find('.labeltext.selected').attr('style', style);
|
||||
var form = $('.form.issue');
|
||||
form.find('#flag-span').fadeOut(0);
|
||||
form.find('#issue_labels').append($(this).clone());
|
||||
var form_new = $('form.form.issue');
|
||||
var clone = $(this).clone();
|
||||
form_new.find('#flag-span').fadeOut(0);
|
||||
form_new.find('#issue_labels').append(clone);
|
||||
var labels = $('#active_labels');
|
||||
labels.find('#'+$(this).attr('id')).remove();
|
||||
labels.append(clone);
|
||||
});
|
||||
|
||||
$('.remove_label.label.selected').live('click', function() {
|
||||
var id = $(this).attr('id');
|
||||
$('.current_labels, #active_labels').find('#'+id+'.label.selected.remove_label').remove();
|
||||
var form = $('.form.issue');
|
||||
if(form.find('.remove_label.label.selected').length == 1) {
|
||||
form.find('#flag-span').fadeIn(0);
|
||||
}
|
||||
var str = '.label.remove_label'+'#'+$(this).attr('id');
|
||||
var str = '.label.remove_label'+'#'+id;
|
||||
form.find(str).remove();
|
||||
var label = $(str);
|
||||
label.removeClass('selected').addClass('add_label').removeClass('remove_label');
|
||||
label.find('.labeltext.selected').attr('style', '').removeClass('selected');
|
||||
label.find('.flag').fadeIn(0);
|
||||
|
||||
});
|
||||
|
||||
$('.issue_status.switch_issue_status').live('click', function () {
|
||||
|
@ -228,10 +235,57 @@ $(document).ready(function() {
|
|||
$('.fulltext.view.issue_body').html(form.find('#issue_body').attr('value'));
|
||||
},
|
||||
error: function(data){
|
||||
alert('error') // TODO remove
|
||||
alert('error'); // TODO remove
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
$('.button.manage_executor').live('click', function() {
|
||||
$('form#search_user, .button.update_executor').fadeIn(0);
|
||||
$('.current_executor .people').addClass('remove_executor selected');
|
||||
$(this).fadeOut(0);
|
||||
});
|
||||
|
||||
$('.button.manage_labels').live('click', function() {
|
||||
$('form#search_labels, .button.update_labels').fadeIn(0);
|
||||
$(this).fadeOut(0);
|
||||
});
|
||||
|
||||
$('.button.update_executor').live('click', function() {
|
||||
var form = $('form.edit_executor.issue');
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: form.attr("action"),
|
||||
data: form.serialize(),
|
||||
success: function(data){
|
||||
$('form#search_user, .button.update_executor').fadeOut(0);
|
||||
$('.button.manage_executor').fadeIn(0);
|
||||
$('#manage_issue_users_list').html('');
|
||||
},
|
||||
error: function(data){
|
||||
alert('error'); // TODO remove
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
$('.button.update_labels').live('click', function() {
|
||||
var form = $('form.edit_labels.issue');
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: form.attr("action"),
|
||||
data: form.serialize(),
|
||||
success: function(data){
|
||||
$('form#search_labels, .button.update_labels').fadeOut(0);
|
||||
$('.button.manage_labels').fadeIn(0);
|
||||
$('#manage_issue_labels_list').html('');
|
||||
},
|
||||
error: function(data){
|
||||
alert('error'); // TODO remove
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -57,15 +57,18 @@ class IssuesController < ApplicationController
|
|||
end
|
||||
|
||||
def update
|
||||
if status = params[:issue][:status]
|
||||
if params[:issue] && status = params[:issue][:status]
|
||||
action = 'issues/_status'
|
||||
@issue.set_close(current_user) if status == 'closed'
|
||||
@issue.set_open if status == 'open'
|
||||
status = 200 if @issue.save
|
||||
render action, :status => (status || 500), :layout => false
|
||||
else
|
||||
elsif params[:issue]
|
||||
@issue.labelings.destroy_all if params[:issue][:labelings_attributes] # FIXME
|
||||
status = 200 if @issue.update_attributes(params[:issue])
|
||||
render :nothing => true, :status => (status || 500), :layout => false
|
||||
else
|
||||
render :nothing => true, :status => 200, :layout => false
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ class Issue < ActiveRecord::Base
|
|||
|
||||
has_many :comments, :as => :commentable, :dependent => :destroy #, :finder_sql => proc { "comments.commentable_id = '#{self.id}' AND comments.commentable_type = '#{self.class.name}'"}
|
||||
has_many :subscribes, :as => :subscribeable, :dependent => :destroy #, :finder_sql => proc { "subscribes.subscribeable_id = '#{self.id}' AND subscribes.subscribeable_type = '#{self.class.name}'"}
|
||||
has_many :labels, :through => :labelings
|
||||
has_many :labels, :through => :labelings, :uniq => true
|
||||
has_many :labelings
|
||||
|
||||
validates :title, :body, :project_id, :presence => true
|
||||
|
@ -20,7 +20,7 @@ class Issue < ActiveRecord::Base
|
|||
after_create :subscribe_users
|
||||
after_update :subscribe_issue_assigned_user
|
||||
|
||||
attr_accessible :labelings_attributes, :title, :body
|
||||
attr_accessible :labelings_attributes, :title, :body, :user_id
|
||||
accepts_nested_attributes_for :labelings, :allow_destroy => true
|
||||
|
||||
scope :opened, where(:status => 'open', :closed_by => nil, :closed_at => nil)
|
||||
|
|
|
@ -50,7 +50,7 @@ class CommentPresenter < ApplicationPresenter
|
|||
end
|
||||
|
||||
def header
|
||||
res = link_to @user.uname, user_path(@user.uname)
|
||||
res = link_to "#{@user.uname} (#{@user.name})", user_path(@user.uname)
|
||||
res += ' ' + t("layout.comments.has_commented")
|
||||
end
|
||||
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
-content_for :sidebar do
|
||||
- if @issue.persisted?
|
||||
.bordered.nopadding
|
||||
%h3=t('activerecord.attributes.issue.status')
|
||||
#switcher.issue_status{:class => "#{@issue.closed? ? 'switcher-off' : 'switcher'} #{can?(:write, @issue.project) ? "switch_issue_status" : ''}"}
|
||||
.swleft=t('layout.issues.status.open')
|
||||
.swright=t('layout.issues.status.closed')
|
||||
- if can? :write, @issue.project
|
||||
=form_tag [@project, @issue], :id => 'update_issue_status', :method => :put do
|
||||
=hidden_field_tag "issue_status", @issue.closed? ? 'closed' : 'open', :name => "issue[status]"
|
||||
|
||||
.bordered.nopadding
|
||||
%h3=t('layout.issues.executor')
|
||||
- if @issue.persisted? && @issue.user
|
||||
.bordered.nopadding
|
||||
.people.nopointer
|
||||
.avatar= image_tag avatar_url(@issue.user), :alt => 'avatar'
|
||||
.name="#{@issue.user.uname} (#{@issue.user.name})"
|
||||
=hidden_field_tag "user-0", @issue.user.id, :name => 'user_id'
|
||||
.both
|
||||
- else
|
||||
=form_tag search_collaborators_project_issues_path(@project), :id => 'search_user', :method => :get do
|
||||
=tracker_search_field(:search_user, t('layout.issues.search_user'))
|
||||
#create_issue_users_list
|
||||
=render 'issues/search_collaborators'
|
||||
|
||||
.block
|
||||
%h3=t('layout.issues.labels')
|
||||
- if @issue.new_record?
|
||||
=form_tag search_labels_project_issues_path(@project), :id => 'search_labels', :method => :get do
|
||||
=tracker_search_field(:search_labels, t('layout.issues.search_labels'))
|
||||
#create_issue_labels_list
|
||||
=render 'issues/search_labels'
|
||||
- else
|
||||
- (@issue.labels || []).each_with_index do |label|
|
||||
.label.selected.nopointer
|
||||
.labeltext.selected{:style => "background: ##{label.color};"}
|
||||
=label.name
|
||||
.both
|
|
@ -14,7 +14,8 @@
|
|||
=form_tag project_issues_path(@project), :id => 'search_issue', :method => :get do
|
||||
.bordered.bpadding20
|
||||
=tracker_search_field(:search_issue, t('layout.issues.search'))
|
||||
.bordered.nopadding
|
||||
%h3.bmargin10=t('layout.issues.new')
|
||||
= link_to t("layout.add"), new_project_issue_path(@project), :class => 'button' if can? :new, @project.issues.new
|
||||
- if can? :new, @project.issues.new
|
||||
.bordered.nopadding
|
||||
%h3.bmargin10=t('layout.issues.new')
|
||||
= link_to t("layout.add"), new_project_issue_path(@project), :class => 'button'
|
||||
=render :partial => 'labels'
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
%div.issue_title=issue.title
|
||||
.smalltext
|
||||
=issue.created_at.to_s(:long)
|
||||
=t("layout.issues.by") if issue.creator
|
||||
=t("layout.by") if issue.creator
|
||||
=link_to(issue.creator.uname, user_path(issue.creator)) if issue.creator
|
||||
.label.selected.tracker
|
||||
-issue.labels.each do |label|
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
-content_for :sidebar do
|
||||
- can_manage = can? :write, @issue.project
|
||||
- if @issue.persisted?
|
||||
.bordered.nopadding
|
||||
%h3=t('activerecord.attributes.issue.status')
|
||||
#switcher.issue_status{:class => "#{@issue.closed? ? 'switcher-off' : 'switcher'} #{can_manage ? "switch_issue_status" : ''}"}
|
||||
.swleft=t('layout.issues.status.open')
|
||||
.swright=t('layout.issues.status.closed')
|
||||
- if can_manage
|
||||
=form_tag [@project, @issue], :id => 'update_issue_status', :method => :put do
|
||||
=hidden_field_tag "issue_status", @issue.closed? ? 'closed' : 'open', :name => "issue[status]"
|
||||
.bordered.nopadding
|
||||
%h3=t('layout.issues.executor')
|
||||
- if @issue.persisted?
|
||||
-if can_manage
|
||||
=form_for :issue, :url => [@project, @issue], :method => :put, :html => { :class => 'edit_executor issue'} do |f|
|
||||
.current_executor
|
||||
- if @issue.user
|
||||
#user-0.people
|
||||
.avatar=image_tag avatar_url(@issue.user), :alt => 'avatar'
|
||||
.name="#{@issue.user.uname} (#{@issue.user.name})"
|
||||
=hidden_field_tag "user-0", @issue.user.id, :name => 'issue[user_id]'
|
||||
.both
|
||||
- else
|
||||
.people.nopointer
|
||||
.avatar=image_tag(@issue.user.avatar(25), :alt => 'avatar')
|
||||
.name="#{@issue.user.uname} (#{@issue.user.name})"
|
||||
.both
|
||||
=link_to(t('layout.issues.label_manage'), '#', :class => "button tmargin10 manage_executor") if can_manage
|
||||
- if can_manage
|
||||
=form_tag search_collaborators_project_issues_path(@project), :id => 'search_user', :method => :get, :style => @issue.persisted? ? 'display:none' : '' do
|
||||
=tracker_search_field(:search_user, t('layout.issues.search_user'))
|
||||
#manage_issue_users_list
|
||||
=render 'issues/search_collaborators'
|
||||
=link_to(t('layout.issues.done'), '#', :class => "button tmargin10 update_executor", :style => 'display:none') if can_manage
|
||||
|
||||
.block
|
||||
%h3=t('layout.issues.labels')
|
||||
- if @issue.persisted?
|
||||
- if can_manage
|
||||
=form_for :issue, :url => [@project, @issue], :method => :put, :html => { :class => 'edit_labels issue'} do |f|
|
||||
.current_labels
|
||||
- (@issue.labels || []).each do |label|
|
||||
.label.selected{:id => "flag#{label.id}"}
|
||||
.flag{:style => "display:none; background: ##{label.color}"}
|
||||
.labeltext.selected{:style => "background: ##{label.color}"}=label.name
|
||||
=hidden_field_tag "label-#{label.id}", label.id, :name => "issue[labelings_attributes][#{label.id}][label_id]"
|
||||
.both
|
||||
- else
|
||||
- (@issue.labels || []).each do |label|
|
||||
.label.nopointer
|
||||
.labeltext.selected{:style => "background: ##{label.color};"}
|
||||
=label.name
|
||||
.both
|
||||
=link_to(t('layout.issues.label_manage'), '#', :class => "button tmargin10 manage_labels") if can_manage
|
||||
- if can_manage
|
||||
=form_tag search_labels_project_issues_path(@project), :id => 'search_labels', :method => :get, :style => @issue.persisted? ? 'display:none' : '' do
|
||||
=tracker_search_field(:search_labels, t('layout.issues.search_labels'))
|
||||
#manage_issue_labels_list
|
||||
=render 'issues/search_labels'
|
||||
=link_to(t('layout.issues.done'), '#', :class => "button tmargin10 update_labels", :style => 'display:none') if can_manage
|
|
@ -2,5 +2,5 @@
|
|||
.people.selected{:id => "user-#{index}", :class => 'add_executor'}
|
||||
.avatar= image_tag(avatar_url(user), :alt => 'avatar')
|
||||
.name="#{user.uname} (#{user.name})"
|
||||
=hidden_field_tag "user-#{index}", user.id, :name => 'user_id'
|
||||
=hidden_field_tag "user-#{index}", user.id, :name => 'issue[user_id]'
|
||||
.both
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
- (@labels || []).each_with_index do |label, index|
|
||||
.add_label.label{:id => "flag#{index}"}
|
||||
- (@labels || []).each do |label|
|
||||
.add_label.label{:id => "flag#{label.id}"}
|
||||
.flag{:style => "background: ##{label.color};"}
|
||||
.labeltext=label.name
|
||||
=hidden_field_tag "label-#{index}", label.id, :name => "issue[labelings_attributes][#{index}][label_id]"
|
||||
=hidden_field_tag "label-#{label.id}", label.id, :name => "issue[labelings_attributes][#{label.id}][label_id]"
|
||||
.both
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
-render :partial => 'projects/submenu'
|
||||
-render :partial => 'issues/create_sidebar'
|
||||
-render :partial => 'issues/manage_sidebar'
|
||||
|
||||
%h3.bpadding10= t("layout.issues.create_header")
|
||||
= form_for :issue, :url => project_issues_path(@project), :html => { :class => 'form issue' } do |f|
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
-render :partial => 'projects/submenu'
|
||||
-render :partial => 'issues/create_sidebar'
|
||||
-render :partial => 'issues/manage_sidebar'
|
||||
-content_for :right_nopadding do
|
||||
dummy
|
||||
%h3.issue_title=@issue.title
|
||||
|
@ -8,7 +8,7 @@
|
|||
.image
|
||||
=image_tag(avatar_url(@issue.creator, :medium), :alt => 'avatar') if @issue.creator
|
||||
.text
|
||||
%span.name=link_to(@issue.creator.uname, user_path(@issue.creator)) if @issue.creator
|
||||
%span.name=link_to("#{@issue.creator.uname} (#{@issue.creator.name})", user_path(@issue.creator)) if @issue.creator
|
||||
%br/
|
||||
%span.date=@issue.created_at.to_s(:long)
|
||||
%br/
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
- if @project.is_rpm and can?(:create, @project => BuildList)
|
||||
%li= link_to t("project_menu.builds"), project_build_lists_path(@project), :class => (contr == :build_lists ? 'active' : nil)
|
||||
- if @project.has_issues
|
||||
%li= link_to t("project_menu.tracker"), project_issues_path(@project), :class => (act == :index && contr == :issues ? 'active' : nil)
|
||||
%li= link_to t("project_menu.tracker"), project_issues_path(@project), :class => (contr == :issues ? 'active' : nil)
|
||||
- if @project.has_wiki
|
||||
%li= link_to t("project_menu.wiki"), project_wiki_index_path(@project), :class => (contr == :wiki ? 'active' : nil)
|
||||
%li= link_to t("project_menu.readme"), "#" #pending
|
||||
|
|
|
@ -35,7 +35,6 @@ en:
|
|||
unsubscribe_btn: Unsubscribe
|
||||
number: Number
|
||||
description: Description
|
||||
by: by
|
||||
labels: Labels
|
||||
invalid_labels: Invalid hex color code
|
||||
new_label: New label name
|
||||
|
@ -49,6 +48,7 @@ en:
|
|||
choose_labels_on_left: Choose labels on the left
|
||||
at: at
|
||||
cancel_button: Cancel
|
||||
done: Done
|
||||
|
||||
flash:
|
||||
issue:
|
||||
|
|
|
@ -35,7 +35,6 @@ ru:
|
|||
unsubscribe_btn: Отписаться
|
||||
number: Номер
|
||||
description: Описание
|
||||
by: ' '
|
||||
labels: Метки
|
||||
invalid_labels: Неверный hex код
|
||||
new_label: Название новой метки
|
||||
|
@ -49,6 +48,7 @@ ru:
|
|||
choose_labels_on_left: выберите метки слева
|
||||
at: в
|
||||
cancel_button: Отменить
|
||||
done: Обновить
|
||||
|
||||
flash:
|
||||
issue:
|
||||
|
|
Loading…
Reference in New Issue