Merge branch 'dev_newproject' into 'develop'
Issue和commit关联功能 See merge request !49
This commit is contained in:
commit
74a20dddc1
4
Gemfile
4
Gemfile
|
@ -50,10 +50,10 @@ gem 'elasticsearch-model'
|
|||
gem 'elasticsearch-rails'
|
||||
|
||||
#rails 3.2.22.2 bug
|
||||
gem "test-unit", "~>3.0"
|
||||
# gem "test-unit", "~>3.0"
|
||||
|
||||
### profile
|
||||
gem 'oneapm_rpm'
|
||||
# gem 'oneapm_rpm'
|
||||
|
||||
group :development do
|
||||
gem 'grape-swagger'
|
||||
|
|
|
@ -55,7 +55,7 @@ class ApplicationController < ActionController::Base
|
|||
include Redmine::Search::Controller
|
||||
include Redmine::MenuManager::MenuController
|
||||
helper Redmine::MenuManager::MenuHelper
|
||||
|
||||
|
||||
def user_agent
|
||||
logger.info "HTTP_USER_AGENT #{request.env["HTTP_USER_AGENT"]}"
|
||||
end
|
||||
|
|
|
@ -22,9 +22,9 @@ class IssuesController < ApplicationController
|
|||
before_filter :authorize1, :only => [:show]
|
||||
before_filter :find_issue, :only => [:show, :edit, :update,:add_journal, :add_journal_in_org]
|
||||
before_filter :find_issues, :only => [:bulk_edit, :bulk_update, :destroy]
|
||||
before_filter :find_project, :only => [:new, :create, :update_form]
|
||||
before_filter :find_project, :only => [:new, :create, :update_form, :issue_commits, :commit_for_issue, :issue_commit_delete]
|
||||
#before_filter :authorize, :except => [:index, :show]
|
||||
before_filter :authorize, :except => [:index,:add_journal, :add_journal_in_org,:delete_journal,:reply,:add_reply]
|
||||
before_filter :authorize, :except => [:index,:add_journal, :add_journal_in_org,:delete_journal,:reply,:add_reply, :issue_commits, :commit_for_issue, :issue_commit_delete]
|
||||
|
||||
before_filter :find_optional_project, :only => [:index]
|
||||
before_filter :check_for_default_issue_status, :only => [:new, :create]
|
||||
|
@ -57,6 +57,57 @@ class IssuesController < ApplicationController
|
|||
helper :project_score
|
||||
include ApplicationHelper
|
||||
|
||||
# issue和代码提交id关联模块 --> over
|
||||
# 获取某个项目的commit_ids
|
||||
def issue_commits
|
||||
begin
|
||||
return render_404 if @project.gpid.nil?
|
||||
@issue_commit_ids = (params[:issue_commit_ids].is_a?(Array) ? params[:issue_commit_ids] : params[:issue_commit_ids].split(",")) unless params[:issue_commit_ids].nil?
|
||||
search = params[:search].to_s.strip
|
||||
@type = params[:type]
|
||||
limit = 15
|
||||
g = Gitlab.client
|
||||
g_project = g.project(@project.gpid)
|
||||
rev = params[:branch].nil? ? g_project.default_branch : params[:branch]
|
||||
@project_branches = g.branches(@project.gpid)
|
||||
@branch_names = @project_branches.map{|b| b.name}
|
||||
@default_branch = g_project.default_branch
|
||||
# 搜索的分页需要单独处理,因为搜索不容易获取总数
|
||||
if search.present?
|
||||
@commits = g.commits(@project.gpid, ref_name:rev, :search => search)
|
||||
@commits_count = @commits.count
|
||||
@commits_pages = Paginator.new @commits_count, limit, params['page'] || 1
|
||||
@offset ||= @commits_pages.offset
|
||||
@commits = paginateHelper @commits,limit
|
||||
else
|
||||
@commits = g.commits(@project.gpid, page:(params[:page].to_i - 1).to_s, ref_name:rev, :search => search)
|
||||
@commits_count = g.user_static(@project.gpid, :rev => rev).count
|
||||
@commits_pages = Redmine::Pagination::Paginator.new @commits_count, limit, params[:page]
|
||||
end
|
||||
rescue Exception => e
|
||||
puts e
|
||||
end
|
||||
end
|
||||
|
||||
# 选择对应的Commit
|
||||
def commit_for_issue
|
||||
history_commit_ids = params[:issue_for_commit_ids].split(",") unless params[:issue_for_commit_ids].nil?
|
||||
@issue_commit_ids = (history_commit_ids.blank? ? params[:checkbox1] : params[:checkbox1] | history_commit_ids).uniq
|
||||
end
|
||||
|
||||
def issue_commit_delete
|
||||
commit_id = params[:commit_id].split(",")
|
||||
issue_commit_ids = params[:issue_commit_ids]
|
||||
# issue_id存在则为issue详情或者编辑的时候,否则为新建Issue
|
||||
# 编辑和详情的时候需要在数据库中删除记录,新建的时候在内存中删除
|
||||
if params[:issue_id]
|
||||
commit_issue = CommitIssues.where(:commit_id => commit_id, :issue_id => params[:issue_id], :project_id => @project.id).first
|
||||
commit_issue.delete if commit_issue
|
||||
end
|
||||
@issue_commit_ids = issue_commit_ids - commit_id
|
||||
end
|
||||
# over
|
||||
|
||||
def index
|
||||
# 顶部导航
|
||||
@project_menu_type = 2
|
||||
|
@ -163,14 +214,14 @@ class IssuesController < ApplicationController
|
|||
def show
|
||||
# 顶部导航
|
||||
@project_menu_type = 2
|
||||
|
||||
# 打开编辑内容
|
||||
@is_edit = true unless params[:edit].nil?
|
||||
|
||||
# 当前用户查看指派给他的缺陷消息,则设置消息为已读
|
||||
query = ForgeMessage.where("forge_message_type =? and user_id =? and forge_message_id =?", "Issue", User.current, @issue).first
|
||||
query.update_attribute(:viewed, true) unless query.nil?
|
||||
|
||||
# issue 关联的commit
|
||||
commit_issues = CommitIssues.where(:issue_id => @issue.id, :project_id => @issue.project_id)
|
||||
@issue_commit_ids = commit_issues.map{|commit_issue| commit_issue.commit_id}
|
||||
# issue 新建的at消息
|
||||
User.current.at_messages.unviewed('Issue', @issue.id).each {|x| x.viewed!}
|
||||
# 回复的at消息
|
||||
|
@ -238,6 +289,8 @@ class IssuesController < ApplicationController
|
|||
@issue.fixed_version_id = nil if @issue.fixed_version_id == 0
|
||||
@issue.assigned_to_id = nil if @issue.assigned_to_id == 0
|
||||
if @issue.save
|
||||
# 关联commmit
|
||||
update_issue_commit params[:commit_ids]
|
||||
#params[:issue][:assigned_to_id] = nil if params[:issue][:assigned_to_id].to_i == 0
|
||||
senduser = User.find(params[:issue][:assigned_to_id])
|
||||
issue_id = @issue.id
|
||||
|
@ -276,6 +329,9 @@ class IssuesController < ApplicationController
|
|||
def edit
|
||||
# 修改实例变量的值
|
||||
return unless update_issue_from_params
|
||||
# issue 关联的commit
|
||||
commit_issues = CommitIssues.where(:issue_id => @issue.id, :project_id => @issue.project_id)
|
||||
@issue_commit_ids = commit_issues.map{|commit_issue| commit_issue.commit_id}
|
||||
|
||||
respond_to do |format|
|
||||
format.html {render :layout => 'base_projects' }#added by young
|
||||
|
@ -309,9 +365,9 @@ class IssuesController < ApplicationController
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if @saved
|
||||
# 更新commit关联情况
|
||||
update_issue_commit params[:commit_ids]
|
||||
#修改界面增加跟踪者
|
||||
watcherlist = @issue.watcher_users
|
||||
select_users = []
|
||||
|
@ -356,6 +412,26 @@ class IssuesController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
# 保存issue的时候相关的commit操作
|
||||
# commit_ids => "9b9845ff,poor56el"
|
||||
def update_issue_commit commit_ids
|
||||
# 关联commmit
|
||||
commit_ids = params[:commit_ids]
|
||||
unless commit_ids.blank?
|
||||
commit_ids = commit_ids.split(",").uniq
|
||||
if params[:action] == "update"
|
||||
exist_commit_ids = CommitIssues.where(:issue_id => @issue, :project_id => @issue.project_id)
|
||||
unless exist_commit_ids.blank?
|
||||
exist_commit_ids = exist_commit_ids.map{|commit| commit.commit_id}
|
||||
commit_ids = commit_ids - exist_commit_ids
|
||||
end
|
||||
end
|
||||
commit_ids.each do |commit_id|
|
||||
CommitIssues.create(:commit_id => commit_id, :project_id => @issue.project_id, :issue_id => @issue.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def update_user_issue_detail(issue, params)
|
||||
case params[:type]
|
||||
when "status"
|
||||
|
@ -794,7 +870,6 @@ class IssuesController < ApplicationController
|
|||
|
||||
# 更新issue状态时,journal表产生记录,返回@current_journal
|
||||
@issue.init_journal(User.current)
|
||||
|
||||
issue_attributes = params[:issue]
|
||||
if issue_attributes && params[:conflict_resolution]
|
||||
case params[:conflict_resolution]
|
||||
|
@ -809,18 +884,18 @@ class IssuesController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
senduser = User.find(params[:issue][:assigned_to_id])
|
||||
|
||||
if senduser.id != User.current.id && @issue.assigned_to_id != params[:issue][:assigned_to_id].to_i
|
||||
issue_id = @issue.id
|
||||
issue_title = params[:issue][:subject]
|
||||
priority_id = params[:issue][:priority_id]
|
||||
ps = ProjectsService.new
|
||||
ps.send_wechat_project_issue_notice senduser,@issue.project,issue_id,issue_title,priority_id
|
||||
if params[:action] == "update"
|
||||
senduser = User.find(params[:issue][:assigned_to_id])
|
||||
if senduser.id != User.current.id && @issue.assigned_to_id != params[:issue][:assigned_to_id].to_i
|
||||
issue_id = @issue.id
|
||||
issue_title = params[:issue][:subject]
|
||||
priority_id = params[:issue][:priority_id]
|
||||
ps = ProjectsService.new
|
||||
ps.send_wechat_project_issue_notice senduser,@issue.project,issue_id,issue_title,priority_id
|
||||
end
|
||||
end
|
||||
|
||||
@issue.safe_attributes = issue_attributes
|
||||
|
||||
@priorities = IssuePriority.active
|
||||
@allowed_statuses = @issue.new_statuses_allowed_to(User.current)
|
||||
true
|
||||
|
|
|
@ -77,12 +77,36 @@ module ApplicationHelper
|
|||
user.nil? ? User.find(2) : user
|
||||
end
|
||||
|
||||
# 通过邮件查找用户,能查到返回用户,否则返回邮件地址
|
||||
def user_by_mail mail
|
||||
user = User.find_by_mail(mail)
|
||||
user.nil? ? mail : user.try(:show_name)
|
||||
end
|
||||
|
||||
def link_to_user_mail(mail, css_class)
|
||||
user = User.find_by_mail(mail)
|
||||
user = user.nil? ? mail : user
|
||||
if user.is_a?(User)
|
||||
name = user.show_name
|
||||
link_to name, {:controller=> 'users', :action => 'show', id: user.id}, :class => css_class, :target => "_blank"
|
||||
else
|
||||
"<a class='#{css_class}'>#{h(user.to_s)}</a>".html_safe
|
||||
end
|
||||
end
|
||||
|
||||
# 通过系统外部用户名查找用户,如果用户不存在则用邮箱替换
|
||||
def get_user_by_login_and login
|
||||
user = User.find_by_login(login)
|
||||
(user.nil? || login == "root") ? User.find(2) : user
|
||||
end
|
||||
|
||||
# 登录名来自外部系统
|
||||
# 通过登录名查找用户,如果用户存在则显示用户姓名,否则显示登录名
|
||||
def get_user_by_login login
|
||||
user = User.find_by_login(login)
|
||||
user.nil? ? login : user.show_name
|
||||
end
|
||||
|
||||
# 重置user_path,目的是将id转换成用户名
|
||||
def user_path(resource, parameters = {})
|
||||
if Fixnum === resource
|
||||
|
|
|
@ -27,6 +27,21 @@ module RepositoriesHelper
|
|||
REPO_IP_ADDRESS = Setting.host_repository
|
||||
REPO_GITLAB_ADDRESS = "git.trustie.net"
|
||||
|
||||
# 获取某次提交的关联Issue
|
||||
# REDO:一次关联查询
|
||||
# type为true则为详情页面,全部显示
|
||||
def get_commit_issues commit_id, project_id, type
|
||||
commit_issues = CommitIssues.where(:commit_id => commit_id, :project_id => project_id)
|
||||
unless commit_issues.blank?
|
||||
if commit_issues.count > 2 && type != 1
|
||||
result = commit_issues.map{|commit_issue| commit_issue.issue_id}.first(2) << "more"
|
||||
else
|
||||
result = commit_issues.map{|commit_issue| commit_issue.issue_id}
|
||||
end
|
||||
end
|
||||
return result unless result.blank?
|
||||
end
|
||||
|
||||
# 因为gitlab的提交总数不是实时同步的,说以取总数用两种方法
|
||||
def choise_commit_count git_count, pro_count
|
||||
git_count > pro_count ? git_count : pro_count
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
class CommitIssues < ActiveRecord::Base
|
||||
attr_accessible :commit_id, :issue_id, :project_id
|
||||
# 之所以没建立关联表,主要是应为commit_id是直接通过api获取的,不存在trustie端
|
||||
has_many :issues
|
||||
end
|
|
@ -56,6 +56,8 @@ class Issue < ActiveRecord::Base
|
|||
has_one :praise_tread_cache, as: :object, dependent: :destroy
|
||||
# ForgeMessage虚拟关联(多态)
|
||||
has_many :forge_messages, :class_name => 'ForgeMessage',:as =>:forge_message ,:dependent => :destroy
|
||||
# 该关联不能关联删除,因为commit记录没有存在Trustie数据库中
|
||||
has_many :commit_issueses
|
||||
|
||||
has_many :at_messages, class_name: 'AtMessage', as: :at_message ,:dependent => :destroy
|
||||
|
||||
|
|
|
@ -2,5 +2,6 @@
|
|||
<%#= watcher_link_issue(@issue, User.current) %>
|
||||
<%= link_to l(:button_copy), project_copy_issue_path(@project, @issue), :class => 'talk_edit fr' if User.current.allowed_to?(:add_issues, @project) %>
|
||||
<%= link_to l(:button_delete), issue_path(@issue.id), :data => {:confirm => issues_destroy_confirmation_message(@issue)}, :method => :delete, :class => 'talk_edit fr' if User.current.allowed_to?(:delete_issues, @project) %>
|
||||
<%= link_to l(:button_edit), 'javascript:void(0);', :onclick => 'issueEditShow();', :class => 'talk_edit fr', :accesskey => accesskey(:edit) if @issue.editable? && User.current.allowed_to?(:edit_issues, @project) %>
|
||||
<%#= link_to l(:button_edit), 'javascript:void(0);', :onclick => 'issueEditShow();', :class => 'talk_edit fr', :accesskey => accesskey(:edit) if @issue.editable? && User.current.allowed_to?(:edit_issues, @project) %>
|
||||
<%= link_to l(:button_edit), edit_issue_path(@issue), :class => 'talk_edit fr', :accesskey => accesskey(:edit) if @issue.editable? && User.current.allowed_to?(:edit_issues, @project) %>
|
||||
<%#= link_to l(:label_user_newfeedback), edit_issue_path(@issue.id), :onclick => 'showAndScrollTo("update", "issue_journal_kind_reply"); return false;', :class => 'talk_edit fr', :accesskey => accesskey(:edit) if @issue.editable? && User.current.allowed_to?(:add_issue_notes, @project) %>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<div id="issue_edit" style="display: none">
|
||||
<div id="issue_edit">
|
||||
<%= content_for(:header_tags) do %>
|
||||
<%= import_ke(enable_at: true, prettify: false, init_activity: false) %>
|
||||
<% end %>
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
<% end %>
|
||||
<!--<a href="javascript:void(0);" class="sy_btn_blue mr5 fr"> 保存并继续</a>-->
|
||||
<!--<a href="javascript:void(0);" onclick="issue_desc_editor.sync();$('#issue-form').submit();" class="sy_btn_blue mr5 fr" id="issue_confirm"> 保存</a>-->
|
||||
<input onclick="issue_desc_editor.sync();$('#issue-form').submit();" class="sy_btn_blue fr mr5" onfocus="this.blur()" id="issue_confirm" style="width: 28px;color: #FFF" value="保存">
|
||||
<input onclick="issue_create();" class="sy_btn_blue fr mr5" onfocus="this.blur()" id="issue_confirm" style="width: 28px;color: #FFF" value="保存">
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="fl pro_new_conbox_right ml10 mb10">
|
||||
|
@ -74,28 +74,28 @@
|
|||
<label class="fl ml5" for="issue_is_private" id="issue_is_private_tips"><%= l(:field_set_private_tips)%></label>
|
||||
<% end %>
|
||||
</li>
|
||||
<li class=" clear" id="versions_assigned_id">
|
||||
<li class="clear" id="versions_assigned_id">
|
||||
<% if @issue.safe_attribute? 'assigned_to_id' %>
|
||||
<%= f.select :assigned_to_id, assigned_options_for_select(@issue.assignable_users, @issue.assigned_to),
|
||||
{:required => @issue.required_attribute?('assigned_to_id'), :no_label => true},
|
||||
{:onchange => "change_assigned_tip();",:class => "w150"} %>
|
||||
<% end %>
|
||||
</li>
|
||||
<li class=" clear" id="assigned_to_tips">
|
||||
<li class="clear" id="assigned_to_tips">
|
||||
<%= @issue.assigned_to.nil? ? "未指派" : "已指派" %>
|
||||
</li>
|
||||
<li class=" clear" >
|
||||
<li class="clear" >
|
||||
<%= f.select :fixed_version_id, version_options_for_select(@issue.assignable_versions, @issue.fixed_version),
|
||||
{:include_blank => true, :required => @issue.required_attribute?('fixed_version_id'), :no_label => true},
|
||||
{:onchange => "change_milestone_tip();", :class => "w150"} %>
|
||||
</li>
|
||||
<li class=" clear" id="milestone_option_tips">
|
||||
<li class="clear" id="milestone_option_tips">
|
||||
<%= @issue.fixed_version.nil? ? "未选择里程碑" : "已选择里程碑" %>
|
||||
<% if params[:action] == "new" %>
|
||||
<%= link_to "", new_project_version_path(@project, :is_issue => true, :issue_project_id => @project.id), :class => "pic_add mt5 ml5 fr", :remote => true %>
|
||||
<% end %>
|
||||
</li>
|
||||
<li class=" clear" style="border:1px solid #c8c8c8;">
|
||||
<li class="clear" style="border:1px solid #c8c8c8;">
|
||||
<% if @issue.safe_attribute? 'start_date' %>
|
||||
<%= f.text_field :start_date, :size => 22, :disabled => !@issue.leaf?, :no_label => true,
|
||||
:required => @issue.required_attribute?('start_date'), :onchange => "issue_start_date_change();",
|
||||
|
@ -103,41 +103,86 @@
|
|||
<%= calendar_for('issue_start_date', 'start_date') if @issue.leaf? %>
|
||||
<% end %>
|
||||
</li>
|
||||
<li class=" clear" id="option_start_date_tips">
|
||||
<li class="clear" id="option_start_date_tips">
|
||||
<%= @issue.start_date.nil? ? "未选择开始日期" : "已选择开始日期" %>
|
||||
</li>
|
||||
<li class=" clear" style="border:1px solid #c8c8c8;">
|
||||
<li class="clear" style="border:1px solid #c8c8c8;">
|
||||
<label class="label02" ></label>
|
||||
<% if @issue.safe_attribute? 'due_date' %>
|
||||
<%= f.text_field :due_date, :size => 22, :disabled => !@issue.leaf?, :no_label => true,
|
||||
:required => @issue.required_attribute?('due_date'), :onchange => "issue_end_date_change();",
|
||||
:class => "fl calendar_input",:style => "width: 170px;", :placeholder => "请选择结束日期" %>
|
||||
:required => @issue.required_attribute?('due_date'), :onchange => "issue_end_date_change();",
|
||||
:class => "fl calendar_input",:style => "width: 170px;", :placeholder => "请选择结束日期" %>
|
||||
<%= calendar_for('issue_due_date', 'start_date') if @issue.leaf? %>
|
||||
<% end %>
|
||||
</li>
|
||||
<li class=" clear " id="option_end_date_tips">
|
||||
<li class="clear " id="option_end_date_tips">
|
||||
<%= @issue.due_date.nil? ? "未选择结束日期" : "已选择结束日期" %>
|
||||
</li>
|
||||
<li class=" clear">
|
||||
<li class="clear">
|
||||
<% if @issue.safe_attribute? 'estimated_hours' %>
|
||||
<%= f.text_field :estimated_hours, :size => 22, :disabled => !@issue.leaf?, :no_label => true,
|
||||
:required => @issue.required_attribute?('estimated_hours'), :placeholder => "请填写预计工时" %>
|
||||
:required => @issue.required_attribute?('estimated_hours'), :placeholder => "请填写预计工时" %>
|
||||
<% end %>
|
||||
</li>
|
||||
<li class=" clear"><%= l(:field_estimated_hours) %></li>
|
||||
<li class="clear"><%= l(:field_estimated_hours) %></li>
|
||||
|
||||
<li class=" clear">
|
||||
<li class="clear">
|
||||
<% if @issue.safe_attribute?('done_ratio') && @issue.leaf? && Issue.use_field_for_done_ratio? %>
|
||||
<%= f.select :done_ratio, ((0..10).to_a.collect { |r| ["#{r*10} %", r*10] }),
|
||||
{:required => @issue.required_attribute?('done_ratio'), :no_label => true},
|
||||
:onchange => "PrecentChange(this.value)",
|
||||
:class => "w150" %>
|
||||
{:required => @issue.required_attribute?('done_ratio'), :no_label => true},
|
||||
:onchange => "PrecentChange(this.value)",
|
||||
:class => "w150" %>
|
||||
<% end %>
|
||||
<li class=" clear">完成度</li>
|
||||
</li>
|
||||
<li class="clear">完成度</li>
|
||||
<% if @project.gpid %>
|
||||
<%#= hidden_field_tag @issue_commit_ids %>
|
||||
<input value="" name="commit_ids" id="commit_ids" type="hidden">
|
||||
<li class="clear"><span>关联Commit</span>
|
||||
<a href="javascript:void(0)" onclick="get_issue_commit_ids('issue_commit_ids','<%= @project.id %>');">
|
||||
<span class='btn-commit btn-blue mt-2 fr'>+</span>
|
||||
</a>
|
||||
</li>
|
||||
<div id="issue_commit_ids">
|
||||
<%= render :partial => "issues/issue_commit_ids", :locals => {:f => f} %>
|
||||
</div>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
<script>
|
||||
function issue_create(){
|
||||
var issue_commit_ids = $("#issue_commit_ids .commit_id_value");
|
||||
var str = "";
|
||||
for(var i=0; i < issue_commit_ids.length; i++){
|
||||
str += $(issue_commit_ids[i]).html();
|
||||
if(i != issue_commit_ids.length -1){
|
||||
str += ",";
|
||||
}
|
||||
}
|
||||
issue_desc_editor.sync();
|
||||
$('#commit_ids').val(str);
|
||||
$('#issue-form').submit();
|
||||
}
|
||||
|
||||
function get_issue_commit_ids(id, project_id){
|
||||
var issue_commit_ids = $("#issue_commit_ids .commit_id_value");
|
||||
var str = "";
|
||||
for(var i=0; i < issue_commit_ids.length; i++){
|
||||
str += $(issue_commit_ids[i]).html();
|
||||
if(i != issue_commit_ids.length -1){
|
||||
str += ",";
|
||||
}
|
||||
}
|
||||
$.ajax({
|
||||
url: '<%= url_for(:controller => 'issues', :action => 'issue_commits') %>',
|
||||
type:'get',
|
||||
data:{
|
||||
project_id: project_id,
|
||||
issue_commit_ids: str
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function change_assigned_tip() {
|
||||
if( document.getElementById('issue_assigned_to_id').options[document.getElementById('issue_assigned_to_id').selectedIndex].value == 0 ){
|
||||
$('#assigned_to_tips').html("未指派");
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<% if @issue_commit_ids %>
|
||||
<% @issue_commit_ids.each do |commit_id| %>
|
||||
<div class="btn btn-blue mb5">
|
||||
<%= link_to commit_id[0,8], {:controller => 'repositories', :action => 'commit_diff', :id => @project.id, :changeset => commit_id}, :target => "_blank", :class => "commit_id_value" %>
|
||||
<%= link_to "×", issue_commit_delete_issues_path(:commit_id => commit_id, :project_id => @project.id, :issue_commit_ids => @issue_commit_ids, :issue_id => @issue.try(:id)), :remote => true, :style => "color:#fff;" %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<div class="c_grey">暂无</div>
|
||||
<% end %>
|
|
@ -0,0 +1,42 @@
|
|||
<div style="width:745px;">
|
||||
<div class="muban_popup_top">
|
||||
<h3 class="fl">关联Commit</h3>
|
||||
<a href="javascript:void(0);" class="muban_icons_close fr"></a>
|
||||
<div class="cl"></div>
|
||||
</div>
|
||||
<div class="muban_popup_con " >
|
||||
<div class="newupload_conbox " >
|
||||
<% if @commits.blank? %>
|
||||
<%= render :partial => "projects/no_data" %>
|
||||
<% else %>
|
||||
<div class=" clear">
|
||||
<div class="cl"></div>
|
||||
<%= form_tag(url_for(:controller => 'issues', :action => 'issue_commits', :project_id => @project.id, :type => "search"),
|
||||
:remote => true, :method => 'get', :id => 'issue_commit_form', :class => "fl") do %>
|
||||
<ul class="clear lightheight28 fl mr100">
|
||||
<li class="mb10 clear fl">
|
||||
<span class=" fl"> 分支 : </span>
|
||||
<%= select_tag :branch, options_for_select(["#{@default_branch}"]+ @branch_names, @rev),
|
||||
:class => "fl newupload_select", :style => "width:180px;height:28px;",
|
||||
:onchange => "$('#issue_commit_form').submit();" %>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="hw_search_box fr mb10" >
|
||||
<input type="text" name="search" placeholder="输入资源关键词进行搜索" class="hw_search-input" style="width:300px;">
|
||||
<%= submit_tag '', :class => 'hw_btn_search', :onfocus => 'this.blur();', :style => 'border-style:none' %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<div id="issue_commit_list">
|
||||
<%= render :partial => "issues/issue_commits_list" %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function remote_function(id) {
|
||||
$(id).submit();
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,59 @@
|
|||
<%= form_tag(url_for(:controller => 'issues', :action => 'commit_for_issue', :project_id => @project.id), :remote => true, :method => 'get', :id => 'commit_for_issue', :class => "fl") do %>
|
||||
<table class="newupload_table " cellspacing="0" cellpadding="0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="newupload_td01"> </th>
|
||||
<th class="newupload_td04">修订号</th>
|
||||
<th>描述</th>
|
||||
<th class="newupload_td04">提交者</th>
|
||||
<th class="newupload_td05">提交日期</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% @commits.each do |commit| %>
|
||||
<tr>
|
||||
<td class="newupload_td01"><input type="checkbox" value="<%= commit.short_id %>" name="checkbox1[]"> </td>
|
||||
<td class="newupload_td04"><span class="newupload_table_name">
|
||||
<%= link_to commit.id[0,8], {:controller => 'repositories', :action => 'commit_diff', :id => @project.id, :changeset => commit.id}, :target => "_blank" %></span>
|
||||
</td>
|
||||
<td class="newupload_td02"><p><%= commit.title %></p></td>
|
||||
<td class="newupload_td04"><span class="newupload_table_name"><%= link_to_user_mail(commit.author_email, "") %></span></td>
|
||||
<td class="newupload_td05"><%= format_date(commit.created_at) %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
<input value="" name="issue_for_commit_ids" id="issue_for_commit_ids" type="hidden">
|
||||
</table>
|
||||
<div class="clear">
|
||||
<div class="clear fl mt10 mb10">
|
||||
<a href="javascript:void(0);" class="sy_btn_blue fl" onclick="search_and_branch_for_commit_ids();">确 定</a>
|
||||
<a href="javascript:void(0);" class="sy_btn_grey fl ml10" onclick="hideModal()">取 消</a>
|
||||
</div>
|
||||
<div style="text-align:center;">
|
||||
<div class="pages" style="width:auto; display:inline-block;">
|
||||
<ul id="homework_pository_ref_pages">
|
||||
<%= pagination_links_full @commits_pages, @commits_count, :per_page_links => false, :remote => true, :flag => true, :is_new => true %>
|
||||
</ul>
|
||||
<div class="cl"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cl"></div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<script>
|
||||
function search_and_branch_for_commit_ids(){
|
||||
var issue_commit_ids = $("#issue_commit_ids .commit_id_value");
|
||||
var str = "";
|
||||
for(var i=0; i < issue_commit_ids.length; i++){
|
||||
str += $(issue_commit_ids[i]).html();
|
||||
if(i != issue_commit_ids.length -1){
|
||||
str += ",";
|
||||
}
|
||||
}
|
||||
alert(str);
|
||||
$('#issue_for_commit_ids').val(str);
|
||||
$('#commit_for_issue').submit();
|
||||
hideModal();
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1 @@
|
|||
$("#issue_commit_ids").html('<%= escape_javascript(render :partial => 'issues/issue_commit_ids') %>');
|
|
@ -1,6 +1,7 @@
|
|||
<h3><%=h "#{@issue.tracker.name} ##{@issue.id}" %></h3>
|
||||
<div id="issue_edit_show" class="mt10 pro_newissue_con">
|
||||
<%= render :partial => 'issues/edit' %>
|
||||
<% content_for :header_tags do %>
|
||||
<%= robot_exclusion_tag %>
|
||||
<% end %>
|
||||
|
||||
<%= render :partial => 'edit' %>
|
||||
<% content_for :header_tags do %>
|
||||
<%= robot_exclusion_tag %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
$("#issue_commit_ids").html('<%= escape_javascript(render :partial => 'issues/issue_commit_ids') %>');
|
|
@ -0,0 +1,7 @@
|
|||
<% if @type %>
|
||||
$("#issue_commit_list").html('<%= escape_javascript(render :partial => 'issues/issue_commits_list') %>');
|
||||
<% else %>
|
||||
var htmlvalue = "<%= escape_javascript(render :partial => 'issues/issue_commits') %>";
|
||||
pop_box_new(htmlvalue,760,600);
|
||||
<% end %>
|
||||
|
|
@ -5,16 +5,7 @@
|
|||
<script>
|
||||
sd_create_editor_from_data(<%= @issue.id%>, null, "100%", "<%= @issue.class.name %>");
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
$(function(){
|
||||
$("#RSide").removeAttr("id");
|
||||
$("#Container").css("width","1000px");
|
||||
is_edit = <%= @is_edit.present? && @is_edit == true %>
|
||||
if(is_edit) {
|
||||
issueEditShow();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="mt10 mb10" id =issue_show_total"">
|
||||
<div class="banner-big f16 fontGrey3">
|
||||
问题跟踪
|
||||
|
@ -46,9 +37,6 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div id="issue_edit_show" class="mt10 pro_newissue_con">
|
||||
<%= render :partial => 'issues/edit'%>
|
||||
</div>
|
||||
<ul class="fr pro_new_conbox_right" id="project_issue_info_show">
|
||||
<li class="clear">
|
||||
<span class="pro_new_conbox_leftspan fl">当前状态</span>
|
||||
|
@ -86,6 +74,11 @@
|
|||
<span class="pro_new_conbox_rightspan fl ml10"><%= @issue.done_ratio %>%</span>
|
||||
</li>
|
||||
<% end %>
|
||||
<li class="clear"><span class="pro_new_conbox_leftspan mb5">关联Commit</span>
|
||||
<div id="issue_commit_ids">
|
||||
<%= render :partial => "issues/issue_commit_ids" %>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="cl"></div>
|
||||
</div>
|
||||
|
|
|
@ -14,9 +14,19 @@
|
|||
<% commits.each do |commit| %>
|
||||
<li class="clear">
|
||||
<span class="fl c_grey ml15 "><%= time_tag(commit.created_at) %>前</span>
|
||||
<%= link_to get_user_by_mail(commit.author_email).show_name, user_path(get_user_by_mail(commit.author_email)), :target => "_blank", :class => "pullreques_pull_name fl ml10" %>
|
||||
<%= link_to_user_mail(commit.author_email, "pullreques_pull_name fl ml10") %>
|
||||
<p class="pullreques_pull_txt ml10 fl"><%= commit.title %></p>
|
||||
<%= link_to truncate(commit.short_id, :length => 20), {:controller => 'repositories', :action => 'commit_diff', :id => @project.id, :changeset => commit.id}, :target => "_blank", :class => "fr mr15 c_grey" %>
|
||||
<% get_commit_issues(commit.short_id, @project.id, 0).each do |issue_id| %>
|
||||
<div class="btn-commit-issue btn-blue mb5 mr5 fr">
|
||||
<% if issue_id == "more" %>
|
||||
<%= link_to "更多", {:controller => 'repositories', :action => 'commit_diff', :id => @project.id, :changeset => commit.id}, :target => "_blank", :class => "commit_id_value mr5" %>
|
||||
<% else %>
|
||||
<%= link_to "##{issue_id}", issue_path(issue_id), :target => "_blank", :class => "commit_id_value mr5" %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="cl"></div>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
|
|
|
@ -8,12 +8,18 @@
|
|||
<div class="c_grey02 mb10">
|
||||
<p><%= @commit_details.message %></p>
|
||||
</div>
|
||||
<!--<div class=" clear mb10">-->
|
||||
<!--<p class="fb">关联Issue:</p>-->
|
||||
<!--<a href="javascript:void(0);" class="btn-small fl mr10">#123</a>-->
|
||||
<!--<a href="javascript:void(0);" class="btn-small fl mr10">#123</a>-->
|
||||
<!--<a href="javascript:void(0);" class="btn-small fl mr10">#123</a>-->
|
||||
<!--</div>-->
|
||||
<div class=" clear mb10">
|
||||
<p class="fb c_grey">关联Issue:</p>
|
||||
<% get_commit_issues(@commit_details.short_id, @project.id, 1).each do |issue_id| %>
|
||||
<div class="btn-commit-issue btn-blue mb5 mr5">
|
||||
<% if issue_id == "more" %>
|
||||
<%= link_to "更多", {:controller => 'repositories', :action => 'commit_diff', :id => @project.id, :changeset => @commit_details.id}, :target => "_blank", :class => "commit_id_value mr5" %>
|
||||
<% else %>
|
||||
<%= link_to "##{issue_id}", issue_path(issue_id), :target => "_blank", :class => "commit_id_value mr5" %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<li class="commit js-toggle-container">
|
||||
<%= render :partial => 'commit_details', :locals => {:changeset => @commit_details} %>
|
||||
</li>
|
||||
|
|
|
@ -952,6 +952,9 @@ RedmineApp::Application.routes.draw do
|
|||
collection do
|
||||
match 'bulk_edit', :via => [:get, :post]
|
||||
post 'bulk_update'
|
||||
get 'issue_commits'
|
||||
get 'commit_for_issue'
|
||||
get 'issue_commit_delete'
|
||||
end
|
||||
member do
|
||||
post 'add_journal'
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
class CreateCommitIssues < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :commit_issues do |t|
|
||||
t.string :commit_id
|
||||
t.integer :issue_id
|
||||
t.integer :project_id
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
|
@ -52,6 +52,7 @@ class Gitlab::Client
|
|||
# @option options [String] :ref_name The branch or tag name of a project repository.
|
||||
# @option options [Integer] :page The page number.
|
||||
# @option options [Integer] :per_page The number of results per page.
|
||||
# @option options [String] :search The obj of results's search value.
|
||||
# @return [Array<Gitlab::ObjectifiedHash>]
|
||||
def commits(project, options={})
|
||||
get("/projects/#{project}/repository/commits", :query => options)
|
||||
|
|
|
@ -1488,6 +1488,8 @@ function pop_up_box(value,tWidth,tTop,tLeft){
|
|||
}
|
||||
|
||||
// 公共弹框样式
|
||||
// 建议左右栏的:Width:460,Height:190
|
||||
// 建议宽屏对应值:Width:760,Height:500
|
||||
function pop_box_new(value, Width, Height){
|
||||
w = ($(window).width() - Width)/2;
|
||||
h = ($(window).height() - Height)/2;
|
||||
|
|
|
@ -20,6 +20,8 @@ input.radio-width90{ width: 90px; }
|
|||
.muban_icons_blue{font-size: 12px;padding: 0 5px;border-radius: 3px;line-height: 14px;color: #3b94d6;border: 1px solid #3b94d6;}
|
||||
/*模板buttons 20161013byLB*/
|
||||
.btn{display: inline-block;border:none; padding:0 10px;color: #333;background: #e1e1e1; text-align:center;font-size: 12px; height: 30px;line-height: 30px;-webkit-border-radius: 3px;-moz-border-radius: 3px; -o-border-radius: 3px; border-radius: 3px; }
|
||||
.btn-commit-issue{display: inline-block;border:none; padding:0 5px;color: #333;background: #e1e1e1; text-align:center;font-size: 12px; height: 20px;line-height: 20px;-webkit-border-radius: 3px;-moz-border-radius: 3px; -o-border-radius: 3px; border-radius: 3px; margin-top: 6px;}
|
||||
.btn-commit{display: inline-block;border:none; padding:0 10px;color: #333;background: #e1e1e1; text-align:center;font-size: 12px; height: 20px;-webkit-border-radius: 3px;-moz-border-radius: 3px; -o-border-radius: 3px; border-radius: 3px; }
|
||||
.btn:hover{background: #c3c3c3; color: #333;}
|
||||
.btn-grey{background: #d9d9d9; color: #656565;}
|
||||
.btn-grey:hover{background: #717171; color: #fff;}
|
||||
|
|
|
@ -788,6 +788,7 @@ a:hover.issues_list_title{color:#3b94d6;}
|
|||
.hw_search_box{ position:relative; }
|
||||
.hw_search_box input.hw_search-input{ width:293px; height:28px; border:none; border:1px solid #e7e7e7; background:#fff; padding-left:5px;padding-right: 25px;}
|
||||
.hw_search_box a.hw_btn_search{display:block; width:20px; height:20px; background:url(/images/hw/icons_hw.png) 0 -57px no-repeat; position:absolute; right:5px; top:5px; cursor:pointer;}
|
||||
.hw_search_box input.hw_btn_search{display:block; width:20px; height:20px; background:url(/images/hw/icons_hw.png) 0 -57px no-repeat; position:absolute; right:5px; top:5px; cursor:pointer;}
|
||||
.hw_search_box a:hover.hw_btn_search{background:url(/images/hw/icons_hw.png) -40px -57px no-repeat;}
|
||||
.hw_files_icon{display:block; width:17px; height:14px; background:url(../images/hw/icons_hw.png) 0 -135px no-repeat;}
|
||||
/* 编辑删除 与课程相同 */
|
||||
|
@ -1001,8 +1002,8 @@ a.pullreques_reply_name{ font-weight: bold; color: #333;}
|
|||
.pullreques_reply_txt{ width: 900px;color: #666;}
|
||||
.pullreques_pull_top { width: 100%; height: 40px; line-height: 40px; background: #f4f4f4; border-top:1px solid #e1e1e1;border-bottom:1px solid #e1e1e1;}
|
||||
a.pullreques_pull_name{display: block; margin-left: 5px;max-width:80px; color:#3b94d6 !important; overflow:hidden;white-space: nowrap; text-overflow:ellipsis;}
|
||||
.pullreques_pull_list li{ height: 30px; line-height: 30px; }
|
||||
.pullreques_pull_txt{display: block; margin-left: 10px;max-width:740px; overflow:hidden;white-space: nowrap; text-overflow:ellipsis;}
|
||||
.pullreques_pull_list li{ height: 35px; line-height: 35px; }
|
||||
.pullreques_pull_txt{display: block; margin-left: 10px;max-width:640px; overflow:hidden;white-space: nowrap; text-overflow:ellipsis;}
|
||||
.pullreques_change_list li{height: 40px; line-height: 40px;border-bottom:1px solid #e1e1e1; }
|
||||
.pullreques_change_list li:last-child{ border-bottom: none;}
|
||||
.pullreques_icons_add{background: url(/images/new_project/icons_issue.png) 0 -374px no-repeat; display: inline-block; width: 19px; height: 16px;}
|
||||
|
@ -1056,4 +1057,5 @@ table.text-file{}
|
|||
.old{ background:#ffecec; }
|
||||
.old:hover{ background:#fffaf1; }
|
||||
.new{ background: #eaffea;}
|
||||
.new:hover{ background:#fffaf1; }
|
||||
.new:hover{ background:#fffaf1; }
|
||||
.commit_id_value{color: white !important;}
|
|
@ -0,0 +1,8 @@
|
|||
FactoryGirl.define do
|
||||
factory :commit_issue, :class => 'CommitIssues' do
|
||||
commit_id "MyString"
|
||||
issue_id 1
|
||||
project_id 1
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe CommitIssues, :type => :model do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
end
|
Loading…
Reference in New Issue