启动实训Api等

This commit is contained in:
huang 2017-02-18 17:44:50 +08:00
parent d4eb4c0d56
commit a43c5cdb2f
23 changed files with 816 additions and 1552 deletions

View File

@ -125,6 +125,8 @@ class PraiseTreadController < ApplicationController
@obj = User.find_by_id(id)
when 'Issue'
@obj = Issue.find_by_id(id)
when 'TrainingTask'
@obj = TrainingTask.find_by_id(id)
when 'Project'
@obj = Project.find_by_id(id)
when 'Bid'

View File

@ -806,6 +806,7 @@ class ProjectsController < ApplicationController
# 资源库fork弹框
def forked_pop
@type = params[:type]
respond_to do |format|
format.js
end

View File

@ -132,6 +132,52 @@ class RepositoriesController < ApplicationController
# send_file "/path/to/file.zip"
end
# 开启实训项目
def training_task_execute
@project = Project.find(params[:id])
@repository = Repository.where("project_id =? and type =?", @project.id, "Repository::Gitlab")
# 如果当前用户已经fork过该项目不会新fork项目则跳至已fork的项
unless has_forked?(@project, User.current)
project = project_from_current_project(@project.id, User.current.id)
redirect_to project_path(project)
else
ActiveRecord::Base.transaction do
g = Gitlab.client
if User.current.gid.nil?
begin
s = Trustie::Gitlab::Sync.new
s.sync_user(User.current)
ensure
logger.error "Synv user failed ==>#{User.current.id}"
end
end
gproject = g.fork(@project.gpid, User.current.gid)
if gproject
new_training_project = copy_project(@project, gproject)
forked_count = @project.forked_count.to_i + 1
@project.update_attributes(:forked_count => forked_count)
# 发布实训任务,只发布实训任务的第一个
publish_training_tasks(@project, new_training_project)
end
end
end
end
def publish_training_tasks project, new_training_project
original_task = TrainingTask.where(:project_id => project.id, :position => 1)
training_task = TrainingTask.new
training_task.save_attachments(params[:attachments] || (params[:training_task] && params[:training_task][:uploads]))
training_task.subject = params[:training_task][:subject]
training_task.description = params[:training_task][:description]
training_task.tracker_id = params[:training_task][:tracker_id]
if training_task.save
respond_to do |format|
format.html{redirect_to project_training_tasks_url(:project_id => new_training_project)}
end
end
end
# 判断用户是否已经fork过该项目
def has_forked?(project, user)
projects = Project.where("user_id =?", user)

View File

@ -1,21 +1,19 @@
# encoding: utf-8
class TrainingTasksController < ApplicationController
layout 'base_projects'#Added by young
default_search_scope :issues
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, :issue_commits, :commit_for_issue, :issue_commit_delete]
#before_filter :authorize, :except => [:index, :show]
# before_filter :authorize, :except => [:new, :index,:add_journal, :add_journal_in_org,:delete_journal,:reply,:add_reply, :issue_commits, :commit_for_issue, :issue_commit_delete]
layout 'base_projects'
before_filter :allow_manager, :only => []
before_filter :allow_members, :only => [:new, :create]
before_filter :build_new_task_from_params, :only => [:new, :create, :update_form]
before_filter :find_training_task, :only => [:show, :edit, :update, :add_journal, :complete_training_task]
# before_filter :find_issues, :only => [:bulk_edit, :bulk_update, :destroy]
before_filter :find_project, :only => [:index, :new, :create, :update_form, :issue_commits, :commit_for_issue, :issue_commit_delete]
# before_filter :authorize, :except => [:index, :show]
# before_filter :authorize, :except => [:new, :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]
before_filter :build_new_issue_from_params, :only => [:new, :create, :update_form]
before_filter :build_new_task_from_params, :only => [:new, :create, :update_form]
accept_rss_auth :index, :show
accept_api_auth :index, :show, :create, :update, :destroy
@ -44,44 +42,6 @@ class TrainingTasksController < 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]
@ -97,164 +57,36 @@ class TrainingTasksController < ApplicationController
def index
# 顶部导航
@project_menu_type = 2
# 为了性能所有用了两种模式issue的@query查询所有的没有优势
# 但是对过滤条件很有有时
if params[:set_filter] != "1"
@project_base_tag = (params[:project_id] || @issue.project) ? 'base_projects':'base'
if User.current.member_of?(@project)
@issues_filter = Issue.where(:project_id => @project.id).order('updated_on desc')
else
@issues_filter = Issue.where(:project_id => @project.id, :is_private => 0).order('updated_on desc')
end
open_and_close_num(@project)
@issue_count = @issues_filter.count
@limit = 10
@is_remote = true
@issue_pages = Paginator.new @issue_count, @limit, params['page'] || 1
@offset ||= @issue_pages.offset
@issues = paginateHelper @issues_filter, @limit
respond_to do |format|
format.js
format.html { render :template => 'issues/index', :layout => @project_base_tag }#by young
format.api {Issue.load_visible_relations(@issues) if include_in_api_response?('relations')}
format.xls {filename = "#{@project.name.to_s}_#{l(:label_issue_list_xls)}.xls"
send_data(issue_list_xls(@issues_filter), :type => 'application/octet-stream', :filename => filename_for_content_disposition(filename))
}
end
else
retrieve_query
sort_init(@query.sort_criteria.empty? ? [['id', 'desc']] : @query.sort_criteria)
sort_update(@query.sortable_columns)
@query.sort_criteria = sort_criteria.to_a
@project_base_tag = (params[:project_id] || @issue.project) ? 'base_projects':'base'
if @query.valid?
@tracker_id = params[:tracker_id]
@assign_to_id = params[:assigned_to_id]
@author_id = params[:author_id]
@priority_id = params[:priority_id]
@status_id = params[:status_id]
@subject = params[:subject]
@done_ratio = params[:done_ratio]
@fixed_version_id = params[:fixed_version_id]
@issue_count = @query.issue_count
@test = params[:test]
@project_sort = 'issues.updated_on desc'
if params[:test] != "0"
case @test
when "1"
@project_sort = 'issues.created_on desc'
when "2"
@project_sort = 'issues.created_on asc'
when "3"
@project_sort = 'issues.updated_on desc'
when "4"
@project_sort = 'issues.updated_on asc'
end
end
open_and_close_num(@project)
@issues_filter_assign_count = @query.issues.select{|issue| issue.assigned_to_id == User.current.id }.count
@issues_filter_author_count = @query.issues.select{|issue| issue.author_id == User.current.id }.count
@issues_filter = @query.issues(:order => @project_sort)
@limit = 10
@is_remote = true
@issue_pages = Paginator.new @issue_count, @limit, params['page'] || 1
@offset ||= @issue_pages.offset
@issues = paginateHelper @issues_filter, @limit
respond_to do |format|
format.js
format.html { render :template => 'issues/index', :layout => @project_base_tag }#by young
format.api {Issue.load_visible_relations(@issues) if include_in_api_response?('relations')}
# format.json { render :json => @issues.map { |issue| issue.to_json}} #:json => @issues.map { |issue| issue.to_json}
format.atom { render_feed(@issues, :title => "#{@project || Setting.app_title}: #{l(:label_issue_plural)}") }
format.csv { send_data(query_to_csv(@issues, @query, params), :type => 'text/csv; header=present', :filename => 'issues.csv') }
format.pdf { send_data(issues_to_pdf(@issues, @project, @query), :type => 'application/pdf', :filename => 'issues.pdf') }
format.xls {filename = "#{@project.name.to_s}_#{l(:label_issue_list_xls)}.xls"
send_data(issue_list_xls(@issues_filter), :type => 'application/octet-stream', :filename => filename_for_content_disposition(filename))
}
end
else
respond_to do |format|
format.html { render(:template => 'issues/index', :layout => @project_base_tag) }#by young
format.any(:atom, :csv, :pdf) { render(:nothing => true) }
format.api { render_validation_errors(@query) }
format.js
end
end
@project_menu_type = 11
@training_tasks = TrainingTask.where(:project_id => @project.id).order('updated_at desc')
@training_tasks_count = @training_tasks.count
@limit = 10
@is_remote = true
@training_tasks_pages = Paginator.new @training_tasks_count, @limit, params['page'] || 1
@offset ||= @training_tasks_pages.offset
@training_tasks = paginateHelper @training_tasks, @limit
respond_to do |format|
format.js
format.html
end
rescue ActiveRecord::RecordNotFound
render_404
end
# 获取issue的开启统计数
def open_and_close_num project
if User.current.member_of?(project)
@issue_open_count = Issue.where("project_id=#{project.id} and status_id in (1,2,3,4,6)").count
@issue_close_count = Issue.where(:project_id => project.id, :status_id => 5 ).count
else
@issue_open_count = Issue.where("project_id=#{project.id} and status_id in (1,2,3,4,6) and is_private = 0").count
@issue_close_count = Issue.where(:project_id => project.id, :status_id => 5, :is_private => 0).count
end
end
def show
# 顶部导航
@project_menu_type = 2
@project_menu_type = 11
# 打开编辑内容
@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消息
@issue.journals.each do |j|
User.current.at_messages.unviewed('Journal', j.id).each {|x| x.viewed!}
end
# 缺陷状态消息更新
query_journals_ids = @issue.journals.map{|journal| journal.id}
if query_journals_ids.length > 0
query_journals = ForgeMessage.where("user_id =? and forge_message_type =? and forge_message_id in (#{query_journals_ids.join(",")})", User.current.id, "Journal")
query_journals.update_all(:viewed => true)
end
@jour_reply = Journal.new
@journals = @issue.journals.includes(:user, :details).reorder("#{Journal.table_name}.id desc").all
@journals = @training_task.journals.includes(:user, :details).reorder("#{Journal.table_name}.id desc").all
@journals = get_no_children_comments_all @journals
@journals.each_with_index {|j,i| j.indice = i+1}
@journals.reject!(&:private_notes?) unless User.current.allowed_to?(:view_private_notes, @issue.project)
@journals.reject!(&:private_notes?) unless User.current.allowed_to?(:view_private_notes, @training_task.project)
@journals.reverse! if User.current.wants_comments_in_reverse_order?
@changesets = @issue.changesets.visible.all
@changesets.reverse! if User.current.wants_comments_in_reverse_order?
@relations = @issue.relations.select {|r| r.other_issue(@issue) && r.other_issue(@issue).visible? }
@allowed_statuses = @issue.new_statuses_allowed_to(User.current)
@edit_allowed = User.current.allowed_to?(:edit_issues, @project)
@priorities = IssuePriority.active
@time_entry = TimeEntry.new(:issue => @issue, :project => @issue.project)
@project_base_tag = (params[:project_id] || @issue.project) ? 'base_projects':'base'#by young
@available_watchers = (@issue.project.users.sort + @issue.watcher_users).uniq
@journal = Journal.new(:journalized => @issue)
@journal = Journal.new(:journalized => @training_task)
respond_to do |format|
format.html {
retrieve_previous_and_next_issue_ids
render :template => 'issues/show', :layout => @project_base_tag#by young
}
format.js
format.api
format.atom { render :template => 'journals/index', :layout => false, :content_type => 'application/atom+xml' }
format.pdf {
pdf = issue_to_pdf(@issue, :journals => @journals)
send_data(pdf, :type => 'application/pdf', :filename => filename_for_content_disposition("#{@project.identifier}-#{@issue.id}.pdf") )
}
format.html
end
end
@ -263,51 +95,36 @@ class TrainingTasksController < ApplicationController
def new
# 顶部导航
@project_menu_type = 11
@training_task = TrainingTask.new
respond_to do |format|
format.html { render :action => 'new', :layout => 'base_projects' }
end
end
# 用户发布新issue
# 用户发布新任务
def create
@training_task.save_attachments(params[:attachments] || (params[:issue] && params[:issue][:uploads]))
# 给该issue在它所在的项目中所有的issues中所在的位置给一个序号
@training_task.save_attachments(params[:attachments] || (params[:training_task] && params[:training_task][:uploads]))
@training_task.subject = params[:training_task][:subject]
@training_task.description = params[:training_task][:description]
@training_task.tracker_id = params[:training_task][:tracker_id]
if @training_task.save
# senduser = User.find(params[:issue][:assigned_to_id])
# issue_id = @issue.id
# issue_title = params[:training_task][:subject]
# priority_id = params[:issue][:priority_id]
# ps = ProjectsService.new
# if senduser.id != User.current.id
# ps.send_wechat_project_issue_notice senduser,@issue.project,issue_id,issue_title,priority_id
# end
# call_hook(:controller_issues_new_after_save, { :params => params, :issue => @issue})
respond_to do |format|
format.html {
render_attachment_warning_if_needed(@issue)
#flash[:notice] = l(:label_successful_create)
#flash[:notice] = l(:notice_issue_successful_create, :id => view_context.link_to("#{@issue.subject}", issue_path(@issue), :title => @issue.subject))
#flash[:notice] = l(:notice_issue_successful_create, :id => view_context.link_to("##{@issue.id}", issue_path(@issue), :title => @issue.subject))
if params[:continue]
attrs = {:tracker_id => @issue.tracker, :parent_issue_id => @issue.parent_issue_id}.reject {|k,v| v.nil?}
redirect_to new_project_issue_url(@issue.project, :issue => attrs)
else
redirect_to issue_url(@issue.id)
end
render_attachment_warning_if_needed(@training_task)
redirect_to training_task_url(@training_task)
}
format.api { render :action => 'show', :status => :created, :location => issue_url(@issue) }
end
return
else
respond_to do |format|
format.html { render :action => 'new' }
format.api { render_validation_errors(@issue) }
end
end
end
def complete_training_task
taskId = @training_task.position
end
def edit
# 修改实例变量的值
return unless update_issue_from_params
@ -394,26 +211,6 @@ class TrainingTasksController < 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"
@ -885,8 +682,8 @@ class TrainingTasksController < ApplicationController
end
def allow_members
if !User.current.member_of?(@project)
return_403
if !(User.current.member_of?(@project) || User.current.admin?)
render_403
end
end
@ -951,39 +748,22 @@ class TrainingTasksController < ApplicationController
# TODO: Refactor, lots of extra code in here
# TODO: Changing tracker on an existing issue should not trigger this
def build_new_issue_from_params
def build_new_task_from_params
if params[:id].blank?
@issue = Issue.new
if params[:copy_from]
begin
@copy_from = Issue.visible.find(params[:copy_from])
@copy_attachments = params[:copy_attachments].present? || request.get?
@copy_subtasks = params[:copy_subtasks].present? || request.get?
@issue.copy_from(@copy_from, :attachments => @copy_attachments, :subtasks => @copy_subtasks)
rescue ActiveRecord::RecordNotFound
render_404
return
end
end
@issue.project = @project
@training_task = TrainingTask.new
@training_task.project = @project
else
@issue = @project.issues.visible.find(params[:id])
@training_task = @project.training_tasks.visible.find(params[:id])
end
@issue.project = @project
@issue.author ||= User.current
@training_task.project = @project
@training_task.author ||= User.current
# Tracker must be set before custom field values
@issue.tracker ||= @project.trackers.find((params[:issue] && params[:issue][:tracker_id]) || params[:tracker_id] || :first)
if @issue.tracker.nil?
@training_task.tracker ||= @project.trackers.find((params[:training_task] && params[:training_task][:tracker_id]) || params[:tracker_id] || :first)
if @training_task.tracker.nil?
render_error l(:error_no_tracker_in_project)
return false
end
@issue.start_date ||= Date.today if Setting.default_issue_start_date_to_creation_date?
@issue.safe_attributes = params[:issue]
@priorities = IssuePriority.active
@allowed_statuses = @issue.new_statuses_allowed_to(User.current, true)
@available_watchers = (@issue.project.users.sort + @issue.watcher_users).uniq
end
def check_for_default_issue_status
@ -1008,4 +788,13 @@ class TrainingTasksController < ApplicationController
end
attributes
end
# Find the issue whose id is the :id parameter
# Raises a Unauthorized exception if the issue is not visible
def find_training_task
@training_task = TrainingTask.find(params[:id])
@project = @training_task.project
rescue ActiveRecord::RecordNotFound
render_404
end
end

View File

@ -12,6 +12,8 @@ class PraiseTread < ActiveRecord::Base
@obj = User.find_by_id(id)
when 'Issue'
@obj = Issue.find_by_id(id)
when 'TrainingTask'
@obj = TrainingTask.find_by_id(id)
when 'Project'
@obj = Project.find_by_id(id)
when 'Bid'

View File

@ -1,4 +1,20 @@
class TrainingTask < ActiveRecord::Base
attr_accessible :description, :project_id, :subject, :tracker_id
belongs_to :project,:touch=> true
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
belongs_to :tracker
has_many :journals, :as => :journalized, :dependent => :destroy
has_many :visible_journals,
:class_name => 'Journal',
:as => :journalized,
:conditions => Proc.new {
["(#{Journal.table_name}.private_notes = ? OR (#{Project.allowed_to_condition(User.current, :view_private_notes)}))", false]
},
:readonly => true
has_many :praise_tread, as: :praise_tread_object, dependent: :destroy
has_one :praise_tread_cache, as: :object, dependent: :destroy
acts_as_attachable
validates_presence_of :subject, :author
validates_length_of :subject, :maximum => 255
end

View File

@ -1,5 +1,6 @@
<% project_file_num = Attachment.where(:container_type => "Project", :container_id => @project.id).count %>
<% project_issue_count = @project.issues.count %>
<% training_tasks_count = @project.training_tasks.count %>
<% project_acts = ForgeActivity.where("project_id = ?", @project.id).count %>
<% raodmaps = Version.where("project_id = ?", @project.id).count %>
<% project_score = @project.project_score %>
@ -38,9 +39,9 @@
</li>
<% end %>
<!--实训任务-->
<% unless @project.enabled_modules.where("name = 'issue_tracking'").empty? %>
<% unless @project.enabled_modules.where("name = 'training_tasks'").empty? %>
<li id="project_menu_11">
<%= link_to project_issue_count > 0 ? "#{l(:project_module_training_tasks)}<span class='issues_nav_tag ml5'>#{switch_integer_into_k project_issue_count}</span>".html_safe : "#{l(:project_module_training_tasks)}", project_issues_path(@project, :remote => true), :class => "pro_new_proname", :title => "#{project_issue_count}" %>
<%= link_to training_tasks_count > 0 ? "#{l(:project_module_training_tasks)}<span class='issues_nav_tag ml5'>#{switch_integer_into_k training_tasks_count}</span>".html_safe : "#{l(:project_module_training_tasks)}", project_training_tasks_url(@project, :remote => true), :class => "pro_new_proname", :title => "#{training_tasks_count}" %>
</li>
<% end %>
<!--讨论区-->

View File

@ -35,9 +35,15 @@
<!--项目fork-->
<li class="mr5 fl">
<%= link_to "<span class='vl_fork'></span>".html_safe+"Fork", forked_pop_project_path(@project),
:class=>"pro_new_topbtn_left fl", :remote => true %>
<a href="<%= member_forked_project_path(@project) %>" class=" pro_new_topbtn fl" title="fork成员列表"><%= project_fork_count %></a>
<!--实训项目条件1、modules中选中了实训任务 2、不是fork的项目-->
<% if !@project.enabled_modules.where("name = 'training_tasks'").empty? && @project.forked_from_project_id.nil? %>
<%= link_to "开始实训", forked_pop_project_path(@project, :task => true), :class => "sy_btn_green fr" %>
<% else %>
<%= link_to "<span class='vl_fork'></span>".html_safe+"Fork", forked_pop_project_path(@project),
:class=>"pro_new_topbtn_left fl", :remote => true %>
<a href="<%= member_forked_project_path(@project) %>" class=" pro_new_topbtn fl" title="fork成员列表"><%= project_fork_count %></a>
<% end %>
</li>

View File

@ -6,31 +6,61 @@
</div>
<div class="sy_popup_con" style="width:380px;">
<ul class="sy_popup_add" >
<% if User.current.id == @project.user_id %>
<li class="center mb30" style="line-height:20px">
自己不能Fork自己创建的项目
</li>
<% else %>
<% if @project.gpid.blank? %>
<%# 实训项目和非实训项目,@type为true的时候为实训 %>
<% if @type %>
<% if User.current.id == @project.user_id %>
<li class="center mb30" style="line-height:20px">
该项目还没有创建版本库暂时不能Fork
很抱歉,您不能在自己的实训项目中启动训练
</li>
<% else %>
<li class="center mb5" style="line-height:20px">
<% if has_forked_cur_project(@project) %>
您已经Fork过该项目点击“确定”将会跳入您Fork的项目主页请问是否继续
<% else %>
Fork将在后台执行<br>平台将为您创建一个新的同名项目和版本库,请问是否继续?
<% end %>
<% else %>
<% if @project.gpid.blank? %>
<li class="center mb30" style="line-height:20px">
该项目还没有创建版本库,暂时不支持实训
</li>
<% else %>
<li class="center mb5" style="line-height:20px">
<% if has_training_cur_project(@project) %>
您已经实训过该项目,点击“确定”将会跳转到您的实训项目主页,请问您是否继续?
<% else %>
实训将在后台为您创建一个新的同名项目,并为您推送第一个任务,请问您是否继续?
<% end %>
</li>
<li class="mt10">
<label class="mr27">&nbsp;</label>
<a href="javascript:void(0);" class="sy_btn_grey fl " onclick="hideModal()">取&nbsp;&nbsp;消</a>
<%= link_to "确 定", {:controller => 'projects', :action => 'training_task_execute'}, :class => "sy_btn_blue fl ml20", :onclick => "hideModal();", :target => "_blank" %>
<div class="cl"></div>
</li>
<% end %>
<% end %>
<% else %>
<% if User.current.id == @project.user_id %>
<li class="center mb30" style="line-height:20px">
自己不能Fork自己创建的项目
</li>
<li class="mt10">
<label class="mr27">&nbsp;</label>
<a href="javascript:void(0);" class="sy_btn_grey fl " onclick="hideModal()">取&nbsp;&nbsp;消</a>
<%= link_to "确 定", {:controller => 'repositories', :action => 'forked'}, :class => "sy_btn_blue fl ml20", :onclick => "hideModal();", :target => "_blank" %>
<div class="cl"></div>
</li>
<% end %>
<% else %>
<% if @project.gpid.blank? %>
<li class="center mb30" style="line-height:20px">
该项目还没有创建版本库暂时不能Fork
</li>
<% else %>
<li class="center mb5" style="line-height:20px">
<% if has_forked_cur_project(@project) %>
您已经Fork过该项目点击“确定”将会跳入您Fork的项目主页请问是否继续
<% else %>
Fork将在后台执行<br>平台将为您创建一个新的同名项目和版本库,请问是否继续?
<% end %>
</li>
<li class="mt10">
<label class="mr27">&nbsp;</label>
<a href="javascript:void(0);" class="sy_btn_grey fl " onclick="hideModal()">取&nbsp;&nbsp;消</a>
<%= link_to "确 定", {:controller => 'repositories', :action => 'forked'}, :class => "sy_btn_blue fl ml20", :onclick => "hideModal();", :target => "_blank" %>
<div class="cl"></div>
</li>
<% end %>
<% end %>
<% end %>
</ul>
</div>
</div>

View File

@ -0,0 +1,12 @@
<% tasks.each do |task| -%>
<%= render :partial => 'content_list', :locals => {:activity => task, :user_activity_id => task.id} %>
<% end %>
<div style="text-align:left;">
<div class="pages fr" style="width:auto; display:inline-block;">
<ul id="issue_list_pagination" class="fr">
<%= pagination_links_full @training_tasks_pages, @training_tasks_count, :per_page_links => false, :remote => @is_remote, :flag => true, :is_new => true %>
</ul>
<div class="cl"></div>
</div>
</div>

View File

@ -0,0 +1,71 @@
<% unless activity.author.nil? %>
<div class="issues_list_box clear" id="user_activity_<%= user_activity_id%>">
<div class="issues_ciricons fl ">
<span class="issues_ciricons_01"></span>
</div>
<div class=" fl ml5">
<div class="issues_list_titlebox clear">
<a href="<%= issue_path(activity) %>" class="issues_list_title fl" target="_blank" title="<%= activity.subject.to_s %>"><%= activity.subject.to_s %></a>
<div class="cl"></div>
</div>
<div class="issues_list_small">
<%# if activity.try(:author).try(:realname) == ' ' %>
<%#= link_to activity.try(:author), user_path(activity.author_id), :class => "fl issues_list_name" %>
<%# else %>
<%#= link_to activity.try(:author).try(:realname), user_path(activity.author_id), :class => "fl issues_list_name" %>
<%# end %>
<!--p class="fl ml10"> <span class="mr5"><%#=format_time(activity.created_on) %></span>发布</p-->
<p class="fl" ><span class="mr5"><%= format_time(activity.created_at) %> </span>发布</p>
<p class="fl ml10"> <span class="mr5"><%= format_time(activity.updated_at) %> </span>更新</p>
</div>
</div>
<ul class="issues_list_txt fr">
<li class="c_grey">
<% if activity.try(:author).try(:realname) == ' ' %>
<%= link_to activity.try(:author), user_path(activity.author_id)%>
<% else %>
<%= link_to activity.try(:author).try(:realname), user_path(activity.author_id)%>
<% end %>
</li>
<li class="issues_list_min c_grey mr5">
<% case activity.tracker_id %>
<% when 1%>
缺陷
<% when 2%>
功能
<% when 3%>
支持
<% when 4%>
任务
<% when 5%>
周报
<% end %>
</li>
</ul>
</div>
<% end %>
<script>
$(".issues_list_box").mouseover(function(){
var iconOrder;
var iconSize = $(this).children().eq(2).children().eq(7).children().size();
if(iconSize > 1){
iconOrder = 2;
} else{
iconOrder = 0;
}
$(this).children().eq(2).children().eq(7).children().eq(iconOrder).show();
});
$(".issues_list_box").mouseout(function(){
var iconOrder;
var iconSize = $(this).children().eq(2).children().eq(7).children().size();
if(iconSize > 1){
iconOrder = 2;
} else{
iconOrder = 0;
}
$(this).children().eq(2).children().eq(7).children().eq(iconOrder).hide();
});
</script>

View File

@ -0,0 +1,54 @@
<div id="issue_detail" style="display: block">
<div class="ping_dispic">
<%= link_to image_tag(url_to_avatar(@training_task.author), :width => 46, :height => 46), user_path(@training_task.author), :class => "ping_dispic" %>
</div>
<div class="talk_txt fl">
<p class="pro_page_tit" style="word-break:break-all;">
<% case @training_task.tracker_id %>
<% when 1%>
<span class="fl" title="缺陷">【缺陷】</span>
<% when 2%>
<span class="fl" title="功能">【功能】</span>
<% when 3%>
<span class="fl" title="支持">【支持】</span>
<% when 4%>
<span class="fl" title="任务">【任务】</span>
<% when 5%>
<span class="fl" title="周报">【周报】</span>
<% end %>
</span> <span style="padding-left: 5px;"><%= @training_task.subject %></span></p>
<!--<span class='<%#= "#{get_issue_priority(@training_task.priority_id)[0]} " %>'><%#= get_issue_priority(@training_task.priority_id)[1] %></span></p>-->
<br>
<div class="cl"></div>
由<%=link_to @training_task.author.show_name, user_path(@training_task.author), :class => "link-blue" %>添加于 <%= format_time(@training_task.created_at).html_safe %>
</div>
<%= link_to "完成", complete_training_task_training_task_path(@training_task), :class => "sy_btn_green fr" %>
<!--talk_txt end-->
<a href="javascript:void(0)" class="talk_edit fr"> </a>
<%#= render :partial => 'action_menu' %>
<div class="cl"></div>
<% if @training_task.description? || @training_task.attachments.any? -%>
<div class="talk_info mb10 issue_desc ke-block" id="issue_desc_<%= @training_task.id %>" style="word-break:break-all;">
<% if @training_task.description? %>
<%#= link_to l(:button_quote), quoted_issue_path(@issue.id), :remote => true, :method => 'post', :class => 'icon icon-comment' if authorize_for('issues', 'edit') %>
<%= textAreailizable @training_task, :description, :attachments => @training_task.attachments %>
<% end %>
</div>
<% end -%>
<%# 附件局部刷新 %>
<div id = "div_issue_attachment_<%=@training_task.id %>">
<%= render :partial => 'task_attachments',:locals => {:training_task => @training_task} %>
</div>
<!--属性-->
<%#= render :partial => 'issues/attributes_show' %>
<div class="cl"></div>
</div>
<script type="text/javascript">
$(function(){
showNormalImage('issue_desc_<%= @training_task.id %>');
autoUrl('issue_desc_<%= @training_task.id %>');
});
</script>

View File

@ -7,7 +7,8 @@
</li>
<li>
<label class="label"><span class="c_red f12">*</span>&nbsp;主题&nbsp;&nbsp;:&nbsp;</label>
<%= f.text_field :subject, :style => "font-size:small;width:606px;", :no_label => true %>
<%= f.text_field :subject, :style => "font-size:small;width:606px;", :no_label => true, :id => "training_task_id" %>
<span style="display: none">标题不能为空</span>
<!--Added by young-->
<%= javascript_tag do %>
observeAutocompleteField('issue_subject',
@ -19,7 +20,6 @@
<% end %>
</li>
<li class="clear">
<% if @issue.safe_attribute? 'description' %>
<label class="label">&nbsp;描述&nbsp;&nbsp;:&nbsp;</label>
<%= f.label_for_field :description, :no_label => true, :class => "label" %>
<%#= link_to_function image_tag('edit.png'), '$(this).hide(); $("#issue_description_and_toolbar").show()' unless @issue.new_record? %>
@ -27,12 +27,12 @@
<%= f.kindeditor :description,:editor_id => "training_task_desc_editor", :width=>'85%', :height =>159, :resizeType => 0, :no_label => true, at_id: @project.id, at_type: @project.class.to_s %>
<%# end %>
<%#= wikitoolbar_for 'issue_description' %>
<% end %>
</li>
<li class="clear">
<label class="label"><%= l(:label_attachment_plural) %></label>
<%#= render :partial => 'attachments/form', :locals => {:container => @training_task} %>
<%= render :partial => 'attachments/form', :locals => {:container => @training_task} %>
</li>
<li class="clear">
<% if params[:action] == "new" %>

View File

@ -0,0 +1,89 @@
<ul>
<% @journals.each do |comment| %>
<script type="text/javascript">
$(function(){
showNormalImage('reply_content_<%= comment.id %>');
autoUrl('reply_content_<%= comment.id %>');
});
</script>
<li class="homepagePostReplyContainer" nhname="reply_rec">
<div class="homepagePostReplyPortrait" >
<%= link_to image_tag(url_to_avatar(comment.user), :width => "33", :height => "33"), user_path(comment.user_id), :alt => "用户头像" %>
</div>
<div class="homepagePostReplyDes" onmouseover="$('#delete_reply_<%=comment.id %>').show();" onmouseout="$('#delete_reply_<%=comment.id %>').hide();">
<%= render :partial => 'users/news_contents', :locals => {:comment => comment, :type => 'Issue', :user_activity_id => issue.id}%>
<div class="homepagePostReplyContent break_word list_style upload_img table_maxWidth" id="reply_content_<%= comment.id %>">
<% if comment.details.any? %>
<% details_to_strings(comment.details).each do |string| %>
<p><%= string %></p>
<% end %>
<% end %>
<P><%= comment.notes.html_safe %></P>
</div>
<div class="orig_reply mb10 mt-10">
<div class="reply">
<span class="reply-right">
<span class="reply_praise_count_<%= comment.id %>">
<%= render :partial => "praise_tread/praise", :locals => {:activity => comment, :user_activity_id => comment.id, :type => "reply"} %>
</span>
<span style="position: relative" class="fr mr20">
<%= link_to(
l(:button_reply),
{:controller => 'issues', :action => 'reply', :user_id => comment.user_id, :id => issue.id, :journal_id => comment.id},
:remote => true,
:method => 'get',
:title => l(:button_reply)) %>
<span id="reply_iconup_<%= comment.id %>" class="reply_iconup02" style="display: none"> ︿</span>
</span>
<%= link_to(
l(:button_delete),
{:controller => 'issues',:action => 'delete_journal', :id => issue.id, :journal_id=>comment.id},
:method => :get,
:remote => true,
:id => "delete_reply_#{comment.id}",
:class => 'fr mr20 undis',
:data => {:confirm => l(:text_are_you_sure)},
:title => l(:button_delete)
) if comment.user_id == User.current.id %>
</span>
<div class="cl"></div>
</div>
</div>
<p id="reply_message_<%= comment.id%>"></p>
</div>
<div class="cl"></div>
</li>
<% end %>
</ul>
<div class="homepagePostReplyContainer borderBottomNone minHeight48">
<div class="homepagePostReplyPortrait mr15 imageFuzzy" id="reply_image_<%= @training_task.id %>">
<%= link_to image_tag(url_to_avatar(User.current), :width => "33", :height => "33"), user_path(@training_task.author_id), :alt => "用户头像" %>
</div>
<div class="homepagePostReplyInputContainer mb10">
<% if User.current.logged? %>
<div nhname='new_message_<%= @training_task.id %>' style="display:none;">
<%= form_for('new_form', :url => add_journal_issue_path(@training_task.id, :is_issue_show => true), :method => "post", :remote => true) do |f| %>
<input type="hidden" name="issue_id" value="<%=@training_task.id%>"/>
<div nhname='toolbar_container_<%= @training_task.id %>' ></div>
<div class="cl"></div>
<textarea placeholder="有问题或有建议,请直接给我留言吧!" style="display: none" nhname='new_message_textarea_<%= @training_task.id %>' name="notes"></textarea>
<div class="cl"></div>
<div class="mt5 fl">
<%= render :partial => 'attachments/issue_reply', :locals => {:container => @training_task} %>
</div>
<span nhname='contentmsg_<%= @training_task.id %>' class="fl mt5"></span>
<a id="new_message_submit_btn_<%= @training_task.id %>" href="javascript:void(0)" onclick="this.style.display='none'" class="blue_n_btn fr mt5" style="display:none;">发送</a>
<div class="cl"></div>
<% end %>
</div>
<% else %>
<%= render :partial => "users/show_unlogged" %>
<% end %>
<div class="cl"></div>
</div>
<div class="cl"></div>
</div>

View File

@ -0,0 +1,5 @@
<% count = @training_task.journals.count %>
回复<sapn class="mr15"><%= count>0 ? "#{count}" : "" %></sapn><span style="color: #cecece;">▪</span>
<span id="praise_count_<%= @training_task.id %>">
<%=render :partial=> "praise_tread/praise", :locals => {:activity => @training_task, :user_activity_id=> @training_task.id, :type => "activity"}%>
</span>

View File

@ -0,0 +1,10 @@
<% if training_task.attachments.any? %>
<div class="pro_pic_box mb10">
<a href="javascript:void(0)" class="link_img fl">
<!--显示附件、图片-->
<%= link_to_attachment_project training_task, :thumbnails => true %>
</a><br/>
<%#= call_hook(:view_issues_show_description_bottom, :training_task => training_task) %>
</div><!--pro_pic_box end-->
<div class="cl"></div>
<% end %>

View File

@ -0,0 +1,232 @@
<%= content_for(:header_tags) do %>
<%= import_ke(enable_at: true,init_activity: true) %>
<% end %>
<script xmlns="http://www.w3.org/1999/html">
function add_style(){
if($("select[id='tracker_id']").val() != 0){
$("#tracker_id").addClass('issues_filter_active');
}
if($("select[id='author_id']").val() != 0){
$("#author_id").addClass('issues_filter_active');
}
if($("select[id='assigned_to_id']").val() !=0){
$("#assigned_to_id").addClass('issues_filter_active');
}
if($("select[id='priority_id']").val() !=0){
$("#priority_id").addClass('issues_filter_active');
}
if($("select[id='fixed_version_id']").val() !=0){
$("#fixed_version_id").addClass('issues_filter_active');
}
if($("select[id='status_id']").val() != 0 ){
$("#status_id").addClass('issues_filter_active');
}
if($("select[id='done_ratio']").val() != -1){
$("#done_ratio").addClass('issues_filter_active');
}
if($("select[id='test']").val() != 0 ){
$("#test").addClass('issues_filter_active');
}
if($("select[id='tracker_id']").val() == 0){
$("#tracker_id").removeClass('issues_filter_active');
}
if($("select[id='author_id']").val() == 0){
$("#author_id").removeClass('issues_filter_active');
}
if($("select[id='assigned_to_id']").val() ==0){
$("#assigned_to_id").removeClass('issues_filter_active');
}
if($("select[id='priority_id']").val() ==0){
$("#priority_id").removeClass('issues_filter_active');
}
if($("select[id='fixed_version_id']").val() ==0){
$("#fixed_version_id").removeClass('issues_filter_active');
}
if($("select[id='status_id']").val() == 0 ){
$("#status_id").removeClass('issues_filter_active');
}
if($("select[id='done_ratio']").val() == -1){
$("#done_ratio").removeClass('issues_filter_active');
}
if($("select[id='test']").val() == 0 ){
$("#test").removeClass('issues_filter_active');
}
};
//issues列表
function g(o){
return document.getElementById(o);
}
function HoverLi(n){
//如果有N个标签,就将i<=N;
for(var i=1;i<=3;i++){
g('issues_list_nav_'+i).className='issues_nav_nomal';
g('issues_list_content_'+i).className='undis';
}
g('issues_list_content_'+n).className='dis';
g('issues_list_nav_'+n).className='issues_nav_hover';
}
$(function(){
$("#RSide").removeAttr("id");
$("#Container").css("width","1000px");
$("input[nhname='date_show']").change(function(){
if($(this).val()=='创建日期起始' || $(this).val()=='创建日期结束')return;
$("input[nhname='date_val']",$(this).parent('div')).val($(this).val());
remote_function();
});
});
function remote_function() {
if($.trim($("#issue_create_date_end_show").val()) !="" && Date.parse($.trim($("#issue_create_date_end_show").val())) < Date.parse($.trim($("#issue_create_date_start_show").val()))){
alert("开始日期不能大于结束日期!");
}
$("#issue_query_form").submit();
// $.ajax({
// url:'<%#= project_issues_path(@project)%>',
// data:{
// subject:$("#v_subject").attr("value").replace(/(^\s*)|(\s*$)/g, ""),
// status_id: $("#status_id").attr("value").replace(/(^\s*)|(\s*$)/g, ""),
// assigned_to_id: $("#assigned_to_id option:selected").attr("value").replace(/(^\s*)|(\s*$)/g, ""),
// priority_id: $("#priority_id option:selected").attr("value").replace(/(^\s*)|(\s*$)/g, ""),
// author_id: $("#author_id option:selected").attr("value").replace(/(^\s*)|(\s*$)/g, "")
// },
// success: function(data){
// },
// error: function(data){
// }
// });
}
function remote_function_export(project_id) {
// $("#export_issue_hidden").attr("value","1");
// $("#issue_query_form").attr("set_filter","1");
// $("#issue_query_form").attr("action","/projects/"+project_id+"/issues.xls");
// $("#issue_query_form").submit();
// $("#issue_query_form").attr("action","/projects/"+project_id+"/issues");
// $("#issue_query_form").removeAttr("format");
// $("#issue_query_form").attr("set_filter","0");
// $("#export_issue_hidden").attr("value","0");
var tracker_id = $("#tracker_id").attr("value");
var subject = $("#v_subject").attr("value");
var assigned_to_id = $("#assigned_to_id").attr("value");
var fixed_version_id = $("#fixed_version_id").attr("value");
var status_id = $("#status_id").attr("value");
var done_ratio = $("#done_ratio").attr("value");
var test = $("#test").attr("value");
var author_id = $("#author_id").attr("value");
var priority_id = $("#priority_id").attr("value");
var issue_create_date_start = $("#issue_date_start_issue_export").attr("value");
var issue_create_date_end = $("#issue_date_end_issue_export").attr("value");
$("#sendexcel").attr("href","/projects/"+project_id+"/issues.xls?export=true&set_filter=1&tracker_id="+tracker_id+"&assigned_to_id="+assigned_to_id+"&fixed_version_id="+fixed_version_id+"&status_id="+status_id+"&done_ratio="+done_ratio+"&test="+test+"&author_id="+author_id+"&subject="+subject+"&issue_create_date_start="+issue_create_date_start+"&issue_create_date_end="+issue_create_date_end+"&priority_id="+priority_id);
///projects/1811/issues.xls?export=true&set_filter=1
}
// function nh_reset_form() {
// $("#issue_query_form")[0].reset();
// $("input[nhname='date_val']").val('');//涛哥的火狐reset 清不掉这个值 我擦
// remote_function();
// }
function EnterPress(e){
var e = e || window.event;
if(e.keyCode == 13){
remote_function();
}
}
// 点击的时候让过滤条件选中assign_to
function switch_assign_to(assign) {
var assign = "option[value =" + assign + "]";
$("#issues_type_2").click(function(){
});
$("select[id='assigned_to_id']").find(assign).attr("selected", "selected");
$("select[id='author_id']").val('');
$("select[id='priority_id']").val('');
$("select[id='tracker_id']").val('');
$("select[id='fixed_version_id']").val('');
$("select[id='status_id']").val('');
$("select[id='done_ratio']").val('');
$("select[id='test']").val('');
$("#tracker_id").removeClass('issues_filter_active');
$("#author_id").removeClass('issues_filter_active');
$("#assigned_to_id").addClass('issues_filter_active');
$("#priority_id").removeClass('issues_filter_active');
$("#fixed_version_id").removeClass('issues_filter_active');
$("#status_id").removeClass('issues_filter_active');
$("#done_ratio").removeClass('issues_filter_active');
$("#test").removeClass('issues_filter_active');
remote_function();
}
// 点击的时候让过滤条件选中user_id
function createByMe(user_id) {
var user = "option[value =" + user_id + "]";
$("#createByMe").click(function(){
});
$("select[id='author_id']").find(user).attr("selected", "selected");
$("select[id='assigned_to_id']").val('');
$("select[id='priority_id']").val('');
$("select[id='tracker_id']").val('');
$("select[id='fixed_version_id']").val('');
$("select[id='status_id']").val('');
$("select[id='done_ratio']").val('');
$("select[id='test']").val('');
$("#tracker_id").removeClass('issues_filter_active');
$("#author_id").addClass('issues_filter_active');
$("#assigned_to_id").removeClass('issues_filter_active');
$("#priority_id").removeClass('issues_filter_active');
$("#fixed_version_id").removeClass('issues_filter_active');
$("#status_id").removeClass('issues_filter_active');
$("#done_ratio").removeClass('issues_filter_active');
$("#test").removeClass('issues_filter_active');
remote_function();
}
// 清楚表单所有选项
function all_reset_form() {
$("#issue_query_form")[0].reset();
$("select[id='author_id']").val('');
$("select[id='assigned_to_id']").val('');
$("input[nhname='date_val']").val('');
$("#tracker_id").removeClass('issues_filter_active');
$("#author_id").removeClass('issues_filter_active');
$("#assigned_to_id").removeClass('issues_filter_active');
$("#priority_id").removeClass('issues_filter_active');
$("#fixed_version_id").removeClass('issues_filter_active');
$("#status_id").removeClass('issues_filter_active');
$("#done_ratio").removeClass('issues_filter_active');
$("#test").removeClass('issues_filter_active');
remote_function();
}
</script>
<!--缺陷列表开始-->
<div id="myissues_con" class="myissues_con mb10">
<div class="clear mb5">
<div class="issues_statistics fl clear">
<ul>
<li>所有<a href="javascript:void(0);" class="issues_greycirbg_btn "><%= @training_tasks.count %></a></li>
</ul>
</div><!--issues_statistics end-->
<a href="<%= new_project_training_task_path(@project)%>" class="sy_btn_green fr">新建</a>
</div>
<% if @training_tasks.empty? %>
<%= render :partial => "projects/no_data" %>
<% else %>
<div id="issue_list">
<%= render :partial => 'all_list', :locals => {:tasks => @training_tasks, :query => @query, :training_tasks_pages=> @training_tasks_pages, :training_tasks_count=> @training_tasks_count, :project=> @project, :subject => @subject} %>
</div>
<% end %>
<%#= render :partial => 'issues/all_list', :locals => {:issues => @issues, :query => @query,:issue_pages=>@issue_pages,:issue_count=>@issue_count,:project=>@project,:subject=>@subject} %>
</div><!--issues_con_list end-->
<div class="cl"></div>
<!--issues_filter end-->
<div id="issues_list_content_1">
</div><!--issues_list_content_1 end-->
<div id="issues_list_content_2" class="undis">
</div><!--issues_list_content_2 end-->
<div id="issues_list_content_3" class="undis">
</div><!--issues_list_content_3 end-->
<!--issues_con_list end-->

View File

@ -11,7 +11,7 @@
<!--新建缺陷开始-->
<div class="pro_new_con ">
<div class="pro_newissue_con clear">
<%= call_hook(:view_issues_new_top, {:training_task => @training_task}) %>
<%#= call_hook(:view_issues_new_top, {:training_task => @training_task}) %>
<%= labelled_form_for @training_task, :url => project_training_tasks_url(@project),
:html => {:id => 'project_training_form', :multipart => true} do |f| %>
<%= error_messages_for 'training_task' %>

View File

@ -0,0 +1,42 @@
<%= content_for(:header_tags) do %>
<%= import_ke(enable_at: true) %>
<%= javascript_include_tag 'create_kindeditor'%>
<% end %>
<script>
sd_create_editor_from_data(<%= @training_task.id%>, null, "100%", "<%= @training_task.class.name %>");
</script>
<div class="mt10 mb10" id =issue_show_total"">
<div class="banner-big f16 fontGrey3">
任务详情
<a href="<%= new_project_training_task_path(@project)%>" class="sy_btn_green fr" >新建</a>
</div>
<div class="resources mt10" style="float:left;">
<div class="pro_page_box">
<div class="problem_main borderBottomNone">
<div id="issue_detail_show">
<%= render :partial => 'detail'%>
</div>
</div>
<!--problem_main end-->
<div style="clear: both;"></div>
<div class="homepagePostReply">
<div class="topBorder" style="display: <%= @training_task.journals.count>0 ? 'none': '' %>"></div>
<div class="homepagePostReplyBanner" >
<div class="homepagePostReplyBannerCount">
<%=render :partial => 'reply_banner' %>
</div>
<div class="homepagePostReplyBannerTime"></div>
</div>
<div class="" id="reply_div_<%= @training_task.id %>" >
<%= render :partial => 'issue_replies',:locals => {:issue => @training_task, :replies_all_i => 0} %>
</div>
</div>
</div>
</div>
<div class="cl"></div>
</div>

View File

@ -268,6 +268,7 @@ zh:
label_tags_numbers: "Tag统计"
label_issue_plural: 问题跟踪
label_training_task: 实训任务
# label_project_plural: 项目列表
label_user_plural: 用户列表
label_tags_call: 需求

View File

@ -1093,7 +1093,16 @@ RedmineApp::Application.routes.draw do
resources :queries, :except => [:show]
resources :training_tasks do
member do
post 'complete_training_task'
end
collection do
end
end
resources :news, :only => [:index, :show, :edit, :update, :destroy]
match '/news/:id/comments', :to => 'comments#create', :via => :post
#match '/news/:id/comments/:comment_id', :to => 'comments#destroy', :via => :delete
delete '/news/:id/comments/:comment_id', :to => 'comments#destroy', as: :delete_news_comments

File diff suppressed because it is too large Load Diff

View File

@ -194,8 +194,8 @@ Redmine::AccessControl.map do |map|
end
map.project_module :training_tasks do |map|
# map.permission :manage_training_tasks, {:training_tasks => [:new, :create]}, :require => :loggedin
# map.permission :view_training_tasks, {:training_tasks => :index, :versions => :download}, :read => true
map.permission :manage_training_tasks, {:training_tasks => [:new, :create]}, :require => :loggedin
map.permission :view_training_tasks, {:training_tasks => :index, :versions => :download}, :read => true
end
# map.project_module :time_tracking do |map|
@ -418,6 +418,7 @@ Redmine::MenuManager.map :project_menu do |menu|
#menu.push :roadmap, { :controller => 'versions', :action => 'index' }, :param => :project_id
# :if => Proc.new { |p| p.shared_versions.any? }
menu.push :issues, { :controller => 'issues', :action => 'index' },:if => Proc.new {|p| p.enabled_module_names.include?('issue_tracking') } ,:param => :project_id, :caption => :label_issue_plural
menu.push :training_tasks, { :controller => 'training_tasks', :action => 'index' },:if => Proc.new {|p| p.enabled_module_names.include?('training_tasks') } ,:param => :project_id, :caption => :label_training_task
# menu.push :new_issue, { :controller => 'issues', :action => 'new', :copy_from => nil }, :param => :project_id, :caption => :label_issue_new,
# :html => { :accesskey => Redmine::AccessKeys.key_for(:new_issue) }
# menu.push :gantt, { :controller => 'gantts', :action => 'show' }, :param => :project_id, :caption => :label_gantt