diff --git a/.gitignore b/.gitignore index 8aa87e9f2..163982b7c 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ /Gemfile.lock /db/schema.rb /Gemfile.lock +/lib/plugins/acts_as_versioned/test/debug.log diff --git a/Gemfile b/Gemfile index 9dae2827c..634af9683 100644 --- a/Gemfile +++ b/Gemfile @@ -25,6 +25,16 @@ group :development do end end +group :test do + # shoulda的版本做了改动 + #gem "shoulda", "~> 3.3.2" + gem "shoulda", "> 3.3.2" + gem "mocha", "~> 0.13.3" + gem 'capybara', '~> 2.0.0' + gem 'nokogiri', '< 1.6.0' +end + + # Gems used only for assets and not required # in production environments by default. group :assets do @@ -32,7 +42,7 @@ group :assets do gem 'coffee-rails', '~> 3.2.1' # See https://github.com/sstephenson/execjs#readme for more supported runtimes - # gem 'therubyracer', :platforms => :ruby + gem 'therubyracer', :platforms => :ruby gem 'uglifier', '>= 1.0.3' end @@ -42,6 +52,16 @@ group :ldap do gem "net-ldap", "~> 0.3.1" end + +platforms :mri, :mingw do + group :rmagick do + # RMagick 2 supports ruby 1.9 + # RMagick 1 would be fine for ruby 1.8 but Bundler does not support + # different requirements for the same gem on different platforms + gem "rmagick", ">= 2.0.0" + end +end + # Optional gem for OpenID authentication group :openid do gem "ruby-openid", "~> 2.1.4", :require => "openid" @@ -67,7 +87,7 @@ if File.exist?(database_file) adapters.each do |adapter| case adapter when 'mysql2' - gem "mysql2", "~> 0.3.11", :platforms => [:mri, :mingw] + gem "mysql2", "= 0.3.11", :platforms => [:mri, :mingw] gem "activerecord-jdbcmysql-adapter", :platforms => :jruby when 'mysql' gem "mysql", "~> 2.8.1", :platforms => [:mri, :mingw] diff --git a/Gemfile.lock b/Gemfile.lock index efc236e7e..e52990e2a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -52,6 +52,15 @@ GEM rails (>= 3, < 5) arel (3.0.2) builder (3.0.0) + capybara (2.0.3) + mime-types (>= 1.16) + nokogiri (>= 1.3.3) + rack (>= 1.0.0) + rack-test (>= 0.5.4) + selenium-webdriver (~> 2.0) + xpath (~> 1.0.0) + childprocess (0.5.3) + ffi (~> 1.0, >= 1.0.11) coderay (1.0.9) coffee-rails (3.2.2) coffee-script (>= 2.2.0) @@ -59,11 +68,11 @@ GEM coffee-script (2.2.0) coffee-script-source execjs - coffee-script-source (1.6.1) + coffee-script-source (1.7.0) erubis (2.7.0) - execjs (1.4.0) - multi_json (~> 1.0) + execjs (2.0.2) fastercsv (1.5.0) + ffi (1.9.3-x86-mingw32) hike (1.2.3) i18n (0.6.1) journey (1.0.4) @@ -74,19 +83,15 @@ GEM mail (2.5.4) mime-types (~> 1.16) treetop (~> 1.4.8) - method_source (0.8.2) + metaclass (0.0.4) mime-types (1.23) + mocha (0.13.3) + metaclass (~> 0.0.1) multi_json (1.7.6) mysql2 (0.3.11-x86-mingw32) net-ldap (0.3.1) + nokogiri (1.5.11-x86-mingw32) polyglot (0.3.3) - pry (0.9.12.6-x86-mingw32) - coderay (~> 1.0) - method_source (~> 0.8) - slop (~> 3.4) - win32console (~> 1.3) - pry-nav (0.2.3) - pry (~> 0.9.10) rack (1.4.5) rack-cache (1.2) rack (>= 0.4) @@ -112,16 +117,28 @@ GEM rake (>= 0.8.7) rdoc (~> 3.4) thor (>= 0.14.6, < 2.0) - rake (10.0.4) + rake (10.3.2) rdoc (3.12.2) json (~> 1.4) + rmagick (2.13.2) ruby-openid (2.1.8) - sass (3.2.7) + rubyzip (1.1.4) + sass (3.2.14) sass-rails (3.2.6) railties (~> 3.2.0) sass (>= 3.1.10) tilt (~> 1.3) - slop (3.5.0) + selenium-webdriver (2.42.0) + childprocess (>= 0.5.0) + multi_json (~> 1.0) + rubyzip (~> 1.0) + websocket (~> 1.0.4) + shoulda (3.5.0) + shoulda-context (~> 1.0, >= 1.0.1) + shoulda-matchers (>= 1.4.1, < 3.0) + shoulda-context (1.2.1) + shoulda-matchers (2.6.1) + activesupport (>= 3.0.0) sprockets (2.2.2) hike (~> 1.2) multi_json (~> 1.0) @@ -133,10 +150,12 @@ GEM polyglot polyglot (>= 0.3.1) tzinfo (0.3.37) - uglifier (1.0.3) + uglifier (2.4.0) execjs (>= 0.3.0) - multi_json (>= 1.0.2) - win32console (1.3.2-x86-mingw32) + json (>= 1.8.0) + websocket (1.0.7) + xpath (1.0.0) + nokogiri (~> 1.3) PLATFORMS x86-mingw32 @@ -147,19 +166,23 @@ DEPENDENCIES acts-as-taggable-on (= 2.4.1) better_errors! builder (= 3.0.0) + capybara (~> 2.0.0) coderay (~> 1.0.6) coffee-rails (~> 3.2.1) fastercsv (~> 1.5.0) i18n (~> 0.6.0) jquery-rails (~> 2.0.2) - mysql2 (~> 0.3.11) + mocha (~> 0.13.3) + mysql2 (= 0.3.11) net-ldap (~> 0.3.1) - pry - pry-nav + nokogiri (< 1.6.0) rack-mini-profiler! rack-openid rails (= 3.2.13) + rmagick (>= 2.0.0) ruby-openid (~> 2.1.4) sass-rails (~> 3.2.3) seems_rateable! + shoulda (> 3.3.2) + therubyracer uglifier (>= 1.0.3) diff --git a/app/assets/javascripts/applied_project.js b/app/assets/javascripts/applied_project.js new file mode 100644 index 000000000..dee720fac --- /dev/null +++ b/app/assets/javascripts/applied_project.js @@ -0,0 +1,2 @@ +// Place all the behaviors and hooks related to the matching controller here. +// All this logic will automatically be available in application.js. diff --git a/app/assets/javascripts/attachment_type_edit.js b/app/assets/javascripts/attachment_type_edit.js new file mode 100644 index 000000000..dee720fac --- /dev/null +++ b/app/assets/javascripts/attachment_type_edit.js @@ -0,0 +1,2 @@ +// Place all the behaviors and hooks related to the matching controller here. +// All this logic will automatically be available in application.js. diff --git a/app/assets/stylesheets/applied_project.css b/app/assets/stylesheets/applied_project.css new file mode 100644 index 000000000..afad32db0 --- /dev/null +++ b/app/assets/stylesheets/applied_project.css @@ -0,0 +1,4 @@ +/* + Place all the styles related to the matching controller here. + They will automatically be included in application.css. +*/ diff --git a/app/assets/stylesheets/attachment_type_edit.css b/app/assets/stylesheets/attachment_type_edit.css new file mode 100644 index 000000000..afad32db0 --- /dev/null +++ b/app/assets/stylesheets/attachment_type_edit.css @@ -0,0 +1,4 @@ +/* + Place all the styles related to the matching controller here. + They will automatically be included in application.css. +*/ diff --git a/app/controllers/account_controller.rb b/app/controllers/account_controller.rb index af8487868..0af388c56 100644 --- a/app/controllers/account_controller.rb +++ b/app/controllers/account_controller.rb @@ -143,15 +143,18 @@ class AccountController < ApplicationController end #added by bai - unless @user.id.nil? - ue = UserExtensions.create(:identity => params[:identity].to_i,:technical_title => params[:technical_title], :gender => params[:gender].to_i, :user_id => @user.id, :student_id => params[:no]) - unless params[:province].nil? || params[:city].nil? - ue.location = params[:province] - ue.location_city = params[:city] - ue.save - end + if @user.id != nil + ue = @user.user_extensions ||= UserExtensions.new + #ue = UserExtensions.create(:identity => params[:identity].to_i,:technical_title => params[:technical_title], :gender => params[:gender].to_i, :user_id => @user.id, :student_id => ) + ue.identity = params[:identity].to_i + ue.technical_title = params[:technical_title] + ue.gender = params[:gender].to_i + ue.user_id = @user.id + ue.student_id = params[:no] + ue.location = params[:province] if params[:province] != nil + ue.location_city = params[:city] if params[:city] != nil + ue.save end - #end end end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 28611e515..af6fbd632 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -233,7 +233,15 @@ class ApplicationController < ActionController::Base # Authorize the user for the requested action def authorize(ctrl = params[:controller], action = params[:action], global = false) - allowed = User.current.allowed_to?({:controller => ctrl, :action => action}, @project || @projects, :global => global) + #modify by NWB + if @project + allowed = User.current.allowed_to?({:controller => ctrl, :action => action}, @project || @projects, :global => global) + elsif @course + allowed = User.current.allowed_to?({:controller => ctrl, :action => action}, @course || @courses, :global => global) + else + allowed = User.current.allowed_to?({:controller => ctrl, :action => action}, @project || @projects, :global => global) + end + if allowed true else @@ -245,6 +253,24 @@ class ApplicationController < ActionController::Base end end + def authorize_course(ctrl = params[:controller], action = params[:action], global = false) + allowed = User.current.allowed_to?({:controller => ctrl, :action => action}, @course || @course, :global => global) + if allowed + true + else + if @course && @course.archived? + render_403 :message => :notice_not_authorized_archived_project + else + deny_access + end + end + end + + def authorize_course_global(ctrl = params[:controller], action = params[:action], global = true) + authorize_course(ctrl, action, global) + end + + # Authorize the user for the requested action outside a project def authorize_global(ctrl = params[:controller], action = params[:action], global = true) authorize(ctrl, action, global) @@ -259,9 +285,13 @@ class ApplicationController < ActionController::Base # Find project of id params[:project_id] def find_project_by_project_id - @project = Project.find(params[:project_id]) + if params[:project_id] + @project = Project.find(params[:project_id]) + elsif params[:course_id] + @course = Course.find(params[:course_id]) + end rescue ActiveRecord::RecordNotFound - render_404 + render_404 end def find_contest_by_contest_id @@ -301,6 +331,10 @@ class ApplicationController < ActionController::Base render_404 unless @object.present? @project = @object.project + if @project == nil && @object.has_attribute?('course_id') + @course = @object.course + end + end def find_contest_from_association @@ -319,6 +353,14 @@ class ApplicationController < ActionController::Base render_404 end + #added by nwb + #ȡγ + def find_course + @course= Course.find(params[:id]) + rescue ActiveRecord::RecordNotFound + render_404 + end + # def find_model_object_contest # model = self.class.model_object # if model diff --git a/app/controllers/attachments_controller.rb b/app/controllers/attachments_controller.rb index 99160b0c0..5dbb4f2bb 100644 --- a/app/controllers/attachments_controller.rb +++ b/app/controllers/attachments_controller.rb @@ -59,6 +59,8 @@ class AttachmentsController < ApplicationController :type => detect_content_type(@attachment), :disposition => (@attachment.image? ? 'inline' : 'attachment') end + rescue => e + redirect_to "http://forge.trustie.net/file_not_found.html" end #更新资源文件类型 @@ -124,10 +126,19 @@ class AttachmentsController < ApplicationController end respond_to do |format| - if @project.nil? - format.html { redirect_to_referer_or forum_memo_path(@attachment.container.forum,@attachment.container) } + # modify by nwb + if @attachment.container_type == 'Course' + if @course.nil? + format.html { redirect_to_referer_or forum_memo_path(@attachment.container.forum, @attachment.container) } + else + format.html { redirect_to_referer_or course_path(@course) } + end else - format.html { redirect_to_referer_or project_path(@project)} + if @project.nil? + format.html { redirect_to_referer_or forum_memo_path(@attachment.container.forum, @attachment.container) } + else + format.html { redirect_to_referer_or project_path(@project) } + end end format.js @@ -190,9 +201,14 @@ private def find_project @attachment = Attachment.find(params[:id]) # Show 404 if the filename in the url is wrong + # modify by nwb raise ActiveRecord::RecordNotFound if params[:filename] && params[:filename] != @attachment.filename - unless @attachment.container_type == 'Bid' || @attachment.container_type == 'HomeworkAttach' || @attachment.container_type == 'Memo' || @attachment.container_type == 'Softapplication' - @project = @attachment.project + if @attachment.container_type == 'Course' + @course = @attachment.course + else + unless @attachment.container_type == 'Bid' || @attachment.container_type == 'HomeworkAttach' || @attachment.container_type == 'Memo' || @attachment.container_type == 'Softapplication' + @project = @attachment.project + end end rescue ActiveRecord::RecordNotFound render_404 diff --git a/app/controllers/bids_controller.rb b/app/controllers/bids_controller.rb index 9c39c526b..a90ca1d12 100644 --- a/app/controllers/bids_controller.rb +++ b/app/controllers/bids_controller.rb @@ -3,12 +3,13 @@ class BidsController < ApplicationController #Added by young menu_item l(:label_homework), :only => [:edit, :udpate] menu_item :respond + menu_item :course, :only => :show_courseEx menu_item :project, :only => [:show_project,:show_results, :new_submit_homework] menu_item :homework_respond, :only => :homework_respond menu_item :homework_statistics, :only => :homework_statistics #Ended by young before_filter :find_bid, :only => [:show, :show_project, :create,:destroy,:more,:back,:add,:delete,:new,:show_results,:set_reward, :add_homework, :fork, :create_fork, - :show_course, :show_bid_project, :show_bid_user, :join_in_contest, :unjoin_in_contest, :new_join,:show_participator, :settings] + :show_course, :show_courseEx,:show_bid_project, :show_bid_user, :join_in_contest, :unjoin_in_contest, :new_join,:show_participator, :settings] # added by fq before_filter :require_login, :only => [:join_in_contest, :unjoin_in_contest] # end @@ -189,7 +190,7 @@ class BidsController < ApplicationController @homework.save_attachments(params[:attachments] || (params[:bid] && params[:bid][:uploads])) # @bid. if @homework.save - HomeworkForCourse.create(:project_id => params[:course], :bid_id => @homework.id) + HomeworkForCourse.create(:course_id => params[:course], :bid_id => @homework.id) unless @bid.watched_by?(User.current) if @bid.add_watcher(User.current) flash[:notice] = l(:label_bid_succeed) @@ -199,11 +200,9 @@ class BidsController < ApplicationController else @bid.safe_attributes = params[:bid] @courses = [] - @membership = User.current.memberships.all(:conditions => Project.visible_condition(User.current)) + @membership = User.current.coursememberships.all#(:conditions => Project.visible_condition(User.current)) @membership.each do |membership| - if membership.project.project_type == 1 - @courses << membership.project - end + @courses << membership.course end render :action => 'fork' end @@ -289,6 +288,7 @@ class BidsController < ApplicationController end #end + # 显示课程 def show_course bids = Bid.where('parent_id = ?', @bid.id) @courses = [] @@ -377,7 +377,7 @@ class BidsController < ApplicationController unless(membership.project.project_type==1) membership.member_roles.each{|role| if(role.role_id == 3) - @option << membership.project + @option << membership.project end } end @@ -399,18 +399,18 @@ class BidsController < ApplicationController end @bidding_project = @temp else - #added by nie - @temp = [] - @bidding_project.each do |pro| - if pro.project && pro.project.project_status - @temp << pro + #added by nie + @temp = [] + @bidding_project.each do |pro| + if pro.project && pro.project.project_status + @temp << pro + end + @temp end - @temp - end - if @temp.size > 0 + if @temp.size > 0 @bidding_project = @temp.sort {|a,b| b.project.project_status.grade <=> a.project.project_status.grade} - end - #ended + end + #ended end if @bid.homework_type == 1 @@ -421,9 +421,9 @@ class BidsController < ApplicationController if params[:student_id].present? @temp = [] @homework_list.each do |pro| - if /#{params[:student_id]}/ =~ pro.user.user_extensions.student_id - @temp << pro - end + if /#{params[:student_id]}/ =~ pro.user.user_extensions.student_id + @temp << pro + end @temp end @homework_list = @temp @@ -432,22 +432,104 @@ class BidsController < ApplicationController respond_to do |format| if @bid.reward_type == 3 - format.html { - render :layout => 'base_homework' - } + format.html { + render :layout => 'base_homework' + } elsif @bid.reward_type == 1 format.html { - render :layout => 'base_bids' - } + render :layout => 'base_bids' + } else - format.html { - render :layout => 'base_contest' - } + format.html { + render :layout => 'base_contest' + } end format.api end end + # 显示作业课程 + # add by nwb + def show_courseEx + if (User.current.logged? && User.current.member_of_course?(@bid.courses.first)) + # flash[:notice] = "" + @membership = User.current.coursememberships.all(:conditions => Course.visible_condition(User.current)) + @option = [] + @membership.each do |membership| + membership.member_roles.each{|role| + if(role.role_id == 3) + @option << membership.course + end + } + end + + @user = @bid.author + @bidding_project = @bid.biding_projects.all + + if params[:student_id].present? + @temp = [] + @bidding_project.each do |pro| + if pro.project && pro.project.project_status + if /#{params[:student_id]}/ =~ pro.user.user_extensions.student_id + @temp << pro + end + end + @temp + end + @bidding_project = @temp + else + #added by nie + @temp = [] + @bidding_project.each do |pro| + if pro.project && pro.project.project_status + @temp << pro + end + @temp + end + if @temp.size > 0 + @bidding_project = @temp.sort {|a,b| b.project.project_status.grade <=> a.project.project_status.grade} + end + #ended + end + + if @bid.homework_type == 1 + @homework = HomeworkAttach.new + #@homework_list = @bid.homeworks + #增加作业按评分排序, + @homework_list = @bid.homeworks.eager_load(:rate_averages, :user, :attachments).order('seems_rateable_cached_ratings.avg DESC').order("#{HomeworkAttach.table_name}.created_at ASC") + if params[:student_id].present? + @temp = [] + @homework_list.each do |pro| + if /#{params[:student_id]}/ =~ pro.user.user_extensions.student_id + @temp << pro + end + @temp + end + @homework_list = @temp + end + end + + respond_to do |format| + if @bid.reward_type == 3 + format.html { + render :layout => 'base_homework' + } + elsif @bid.reward_type == 1 + format.html { + render :layout => 'base_bids' + } + else + format.html { + render :layout => 'base_contest' + } + end + format.api + end + else + render_403 :message => :notice_not_authorized + end + end + ##### by huang def show_project_homework # flash[:notice] = "" @@ -711,7 +793,7 @@ class BidsController < ApplicationController @bid.save_attachments(params[:attachments] || (params[:bid] && params[:bid][:uploads])) # @bid. if @bid.save - HomeworkForCourse.create(:project_id => params[:course_id], :bid_id => @bid.id) + HomeworkForCourse.create(:course_id => params[:course_id], :bid_id => @bid.id) unless @bid.watched_by?(User.current) if @bid.add_watcher(User.current) flash[:notice] = l(:label_bid_succeed) @@ -721,19 +803,22 @@ class BidsController < ApplicationController else @bid.safe_attributes = params[:bid] @homework = @bid - @project = Project.find_by_id(params[:course_id]) - @project_id = @project.id - render file: 'projects/new_homework', layout: 'base_courses' + @course = Course.find_by_id(params[:course_id]) + @course_id = @course.id + + render file: 'courses/new_homework', layout: 'base_courses' end end - + + # modify by nwb\ + # 编辑作业 def edit @bid = Bid.find(params[:bid_id]) if (User.current.admin?||User.current.id==@bid.author_id) - @project_id = params[:project_id] + @course_id = params[:course_id] respond_to do |format| format.html { - @project = Project.find(params[:project_id]) + @course = Course.find(params[:course_id]) @user= User.find(User.current.id) render :layout => 'base_courses' } @@ -745,11 +830,11 @@ class BidsController < ApplicationController def update @bid = Bid.find(params[:id]) - @project = @bid.courses.first#Project.find(params[:course_id]) + @course = @bid.courses.first#Project.find(params[:course_id]) @bid.save_attachments(params[:attachments] || (params[:bid] && params[:bid][:uploads])) if @bid.update_attributes(params[:bid]) && @bid.save flash[:notice] = l(:label_update_homework_succeed) - redirect_to project_homework_path(@project) + redirect_to course_homework_path(@course) else @bid.safe_attributes = params[:bid] render :action => 'edit', :layout =>'base_courses' @@ -894,9 +979,9 @@ class BidsController < ApplicationController def memberAccess # 是课程,则判断当前用户是否参加了课程 return true if current_user.admin? - return 0 if @bid.courses.first.project_type == Project::ProjectType_project + #return 0 if @bid.courses.first.project_type == Project::ProjectType_project currentUser = User.current - render_403 unless currentUser.member_of?(@bid.courses.first) + render_403 unless currentUser.member_of_cousrse?(@bid.courses.first) end end diff --git a/app/controllers/boards_controller.rb b/app/controllers/boards_controller.rb index b5e0b2d85..e0bd9582d 100644 --- a/app/controllers/boards_controller.rb +++ b/app/controllers/boards_controller.rb @@ -28,17 +28,25 @@ class BoardsController < ApplicationController helper :watchers def index - @boards = @project.boards.includes(:last_message => :author).all - @boards = [] << @boards[0] if @boards.any? - if @boards.size == 1 - @board = @boards.first - show and return - end - if @project.project_type == 1 - render :layout => 'base_courses' - else - render :layout => false if request.xhr? + #modify by nwb + if @project + @boards = @project.boards.includes(:last_message => :author).all + @boards = [] << @boards[0] if @boards.any? + if @boards.size == 1 + @board = @boards.first + show and return + end + render :layout => false if request.xhr? + elsif @course + @boards = @course.boards.includes(:last_message => :author).all + @boards = [] << @boards[0] if @boards.any? + if @boards.size == 1 + @board = @boards.first + show and return + end + render :layout => 'base_courses' end + end def show @@ -60,10 +68,11 @@ class BoardsController < ApplicationController preload(:author, {:last_reply => :author}). all @message = Message.new(:board => @board) - if @project.project_type ==1 - render :action => 'show', :layout => 'base_courses' - else + #modify by nwb + if @project render :action => 'show', :layout => !request.xhr? + elsif @course + render :action => 'show', :layout => 'base_courses' end } format.atom { @@ -72,7 +81,12 @@ class BoardsController < ApplicationController includes(:author, :board). limit(Setting.feeds_limit.to_i). all - render_feed(@messages, :title => "#{@project}: #{@board}") + if @project + render_feed(@messages, :title => "#{@project}: #{@board}") + elsif @course + render_feed(@messages, :title => "#{@course}: #{@board}") + end + } end end diff --git a/app/controllers/contests_controller.rb b/app/controllers/contests_controller.rb index c1c817517..adadfbf44 100644 --- a/app/controllers/contests_controller.rb +++ b/app/controllers/contests_controller.rb @@ -74,6 +74,25 @@ class ContestsController < ApplicationController end end + def homework + @offset, @limit = api_offset_and_limit({:limit => 10}) + @bids = @course.homeworks.order('deadline DESC') + @bids = @bids.like(params[:name]) if params[:name].present? + @bid_count = @bids.count + @bid_pages = Paginator.new @bid_count, @limit, params['page'] + + @offset ||= @bid_pages.reverse_offset + unless @offset == 0 + @bids = @bids.offset(@offset).limit(@limit).all.reverse + else + limit = @bid_count % @limit + @bids = @bids.offset(@offset).limit(limit).all.reverse + end + render :layout => 'base_courses' + + end + + def show_contest @user = @contest.author @jours = @contest.journals_for_messages.where('m_parent_id IS NULL').order('created_on DESC') diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb index 215dd3a58..e0daa44f4 100644 --- a/app/controllers/courses_controller.rb +++ b/app/controllers/courses_controller.rb @@ -1,18 +1,35 @@ class CoursesController < ApplicationController + layout 'base_courses' include CoursesHelper - + helper :activities + helper :members + helper :words + + menu_item :overview + menu_item :feedback, :only => :feedback + menu_item :homework, :only => :homework + + menu_item l(:label_sort_by_time), :only => :index + menu_item l(:label_sort_by_active), :only => :index + menu_item l(:label_sort_by_influence), :only => :index + + before_filter :find_course, :except => [ :index, :search,:list, :new,:join,:unjoin, :create, :copy, :statistics, :new_join, :course, :enterprise_course, :course_enterprise,:view_homework_attaches] + before_filter :authorize_course, :only => [:show, :settings, :edit, :update, :modules, :close, :reopen, :view_homework_attaches, :course] + before_filter :authorize_course_global, :only => [:view_homework_attaches, :new,:create] + before_filter :require_admin, :only => [:copy, :archive, :unarchive, :destroy, :calendar] + before_filter :toggleCourse, only: [:finishcourse, :restartcourse] + before_filter :require_login, :only => [:join, :unjoin] before_filter :allow_join, :only => [:join] - + def join if User.current.logged? - course = Project.find(params[:object_id]) - course_prefs = Course.find_by_extra(course.identifier) - if params[:course_password] == course_prefs.password + course = Course.find(params[:object_id]) + if params[:course_password] == course.password members = [] members << Member.new(:role_ids => [10], :user_id => User.current.id) course.members << members - + StudentsForCourse.create(:student_id => User.current.id, :course_id => params[:object_id]) @state = 0 else @@ -21,16 +38,16 @@ class CoursesController < ApplicationController end respond_to do |format| # format.html { redirect_to_referer_or {render :text => (watching ? 'Watcher added.' : 'Watcher removed.'), :layout => true}} - format.js { render :partial => 'set_join', :locals => {:user => User.current, :course => Project.find(params[:object_id]), :object_id => params[:object_id]} } + format.js { render :partial => 'set_join', :locals => {:user => User.current, :course => Course.find(params[:object_id]), :object_id => params[:object_id]} } end end - + def unjoin if User.current.logged? - - @member = Member.where('project_id = ? and user_id = ?', params[:object_id], User.current.id) + + @member = Member.where('course_id = ? and user_id = ?', params[:object_id], User.current.id) @member.first.destroy - + joined = StudentsForCourse.where('student_id = ? and course_id = ?', User.current.id, params[:object_id]) joined.each do |join| join.delete @@ -38,25 +55,667 @@ class CoursesController < ApplicationController end respond_to do |format| # format.html { redirect_to_referer_or {render :text => (watching ? 'Watcher added.' : 'Watcher removed.'), :layout => true}} - format.js { render :partial => 'set_join', :locals => {:user => User.current, :course => Project.find(params[:object_id]), :object_id => params[:object_id]} } + format.js { render :partial => 'set_join', :locals => {:user => User.current, :course => Course.find(params[:object_id]), :object_id => params[:object_id]} } end end + #更新课程信息 + def update + @course.safe_attributes = params[:course] + @course.class_period = params[:class_period] + if @course.save + if params[:course][:is_public] == '0' + course_status = CourseStatus.find_by_course_id(@course.id) + course_status.destroy if course_status + elsif params[:course][:is_public] == '1' + course_status = CourseStatus.find_by_course_id(@course.id) + course_status.destroy if course_status + course_status = CourseStatus.create(:course_id => @course.id, :grade => 0) + end + + respond_to do |format| + format.html { + flash[:notice] = l(:notice_successful_update) + redirect_to settings_course_path(@course) + } + format.api { render_api_ok } + end + else + respond_to do |format| + format.html { + settings + render :action => 'settings' + } + format.api { render_validation_errors(@course) } + end + end + end + + def new_join + @course = Course.find(params[:object_id]) + end + + # 课程搜索 + # add by nwb + def search + courses_all = Course.all_course + + @courses = courses_all.visible + if params[:name].present? + @courses_all = @courses.like(params[:name]) + else + @courses_all = @courses; + end + @course_count = @courses_all.count + @course_pages = Paginator.new @course_count, per_page_option, params['page'] + + # 课程的动态数 + @course_activity_count=Hash.new + @courses_all.each do |course| + @course_activity_count[course.id]=0 + end + + case params[:course_sort_type] + when '0' + @courses = @courses_all.order("created_at desc") + @s_type = 0 + @courses = @courses.offset(@course_pages.offset).limit(@course_pages.per_page) + + @course_activity_count=get_course_activity @courses,@course_activity_count + + when '1' + @courses = @courses_all.order("course_ac_para desc") + @s_type = 1 + @courses = @courses.offset(@course_pages.offset).limit(@course_pages.per_page) + + @course_activity_count=get_course_activity @courses,@course_activity_count + + when '2' + @courses = @courses_all.order("watchers_count desc") + @s_type = 2 + @courses = @courses.offset(@course_pages.offset).limit(@course_pages.per_page) + + @course_activity_count=get_course_activity @courses,@course_activity_count + + when '3' + @course_activity_count=get_course_activity @courses_all,@course_activity_count_array + @courses=handle_course @courses_all,@course_activity_count + @s_type = 3 + @courses = @courses[@course_pages.offset, @course_pages.per_page] + + else + @s_type = 0 + @courses = @courses_all.order("created_at desc") + @courses = @courses.offset(@course_pages.offset).limit(@course_pages.per_page) + + @course_activity_count=get_course_activity @courses,@course_activity_count + + end + + respond_to do |format| + format.html { + render :layout => 'base' + scope = Course + unless params[:closed] + scope = scope.active + end + } + format.atom { + courses = Course.visible.order('created_on DESC').limit(Setting.feeds_limit.to_i).all + render_feed(courses, :title => "#{Setting.app_title}: #{l(:label_course_latest)}") + } + end + end + + def member + ## 有角色参数的才是课程,没有的就是项目 + @render_file = 'member_list' + @teachers= searchTeacherAndAssistant(@course) + @canShowCode = isCourseTeacher(User.current.id) + case params[:role] + when '1' + @subPage_title = l :label_teacher_list + @members = searchTeacherAndAssistant(@course) + when '2' + @subPage_title = l :label_student_list + @members = searchStudent(@course) + else + @subPage_title = '' + @members = @course.member_principals.includes(:roles, :principal).all.sort + end + @members = paginateHelper @members + render :layout => 'base_courses' + end + + #判断指定用户是否为课程教师 + def isCourseTeacher(id) + result = false + if @teachers.find_by_user_id(id) != nil + result = true + end + result + end + + def handle_course courses, activities + course_activity_count_array=activities.values() + + course_array=[] + i=0; + courses.each do |course| + course_array[i]=course + i=i+1 + end + + courses=desc_sort_course_by_avtivity(course_activity_count_array, course_array) + + return courses + end + + def settings + @issue_custom_fields = IssueCustomField.sorted.all + @issue_category ||= IssueCategory.new + @member ||= @course.members.new + @trackers = Tracker.sorted.all + end + + def create + if User.current.user_extensions.identity + @course = Course.new + @course.extra='course' + DateTime.parse(Time.now.to_s).strftime('%Y-%m-%d_%H-%M-%S').to_s + @course.safe_attributes = params[:course] + @course.tea_id = User.current.id + # added by bai + @course.term = params[:term] + @course.time = params[:time] + #@course.school_id = params[:occupation] + @course.school_id = User.current.user_extensions.school_id + @course.setup_time = params[:setup_time] + @course.endup_time = params[:endup_time] + @course.class_period = params[:class_period] + end + + @issue_custom_fields = IssueCustomField.sorted.all + @trackers = Tracker.sorted.all + + if User.current.user_extensions.identity == 0 + if @course.save + #unless User.current.admin? + r = Role.givable.find_by_id(Setting.new_project_user_role_id.to_i) || Role.givable.first + m = Member.new(:user => User.current, :roles => [r]) + m.project_id = -1 + course = CourseInfos.new(:user_id => User.current.id, :course_id => @course.id) + #user_grades = UserGrade.create(:user_id => User.current.id, :course_id => @course.id) + if params[:course][:is_public] == '1' + course_status = CourseStatus.create(:course_id => @course.id, :watchers_count => 0, :changesets_count => 0, :grade => 0, :course_type => @course_tag) + end + @course.members << m + @course.course_infos << course + #end + respond_to do |format| + format.html { + flash[:notice] = l(:notice_successful_create) + if params[:continue] + redirect_to new_course_path(attrs, :course => '0') + elsif params[:course_continue] + redirect_to new_course_path(:course => '1') + else + redirect_to settings_course_path(@course, :course_type => 1) + end + } + format.api { render :action => 'show', :status => :created, :location => url_for(:controller => 'courses', :action => 'show', :id => @course.id) } + end + else + @course.destroy + respond_to do |format| + format.html { render :action => 'new', :layout => 'base' } #Added by young + format.api { render_validation_errors(@course) } + end + end + end + + end + + def course + @school_id = params[:school_id] + per_page_option = 10 + if @school_id == "0" or @school_id.nil? + @courses_all = Course.active.visible. + joins("LEFT JOIN #{CourseStatus.table_name} ON #{Course.table_name}.id = #{CourseStatus.table_name}.course_id"). + where("#{Course.table_name}.course_type = ? ", Course::CourseType_course) + else + @courses_all = Course.active.visible. + joins("LEFT JOIN #{CourseStatus.table_name} ON #{Course.table_name}.id = #{CourseStatus.table_name}.course_id"). + joins(:course_extra). + where("#{Course.table_name}.course_type = ? AND #{Course.table_name}.school_id = ?", Course::CourseType_course, @school_id) + end + + @course_count = @courses_all.count + @course_pages = Paginator.new @course_count, per_page_option, params['page'] + + #gcm activity count + + @course_activity_count=Hash.new + #count initialize + @courses_all.each do |course| + @course_activity_count[course.id]=0 + end + + #@course_activity_count=get_course_activity @courses_all,@course_activity_count + #gcm end + + + case params[:course_sort_type] + when '0' + @courses = @courses_all.order("created_on desc") + @s_type = 0 + @courses = @courses.offset(@course_pages.offset).limit(@course_pages.per_page) + + #gcm + @course_activity_count=get_course_activity @courses,@course_activity_count + #gcmend + + when '1' + @courses = @courses_all.order("course_ac_para desc") + @s_type = 1 + @courses = @courses.offset(@course_pages.offset).limit(@course_pages.per_page) + + #gcm + @course_activity_count=get_course_activity @courses,@course_activity_count + #gcmend + + when '2' + @courses = @courses_all.order("watchers_count desc") + @s_type = 2 + @courses = @courses.offset(@course_pages.offset).limit(@course_pages.per_page) + + #gcm + @course_activity_count=get_course_activity @courses,@course_activity_count + #gcmend + + #gcm + when '3' + + #gcm + @course_activity_count=get_course_activity @courses_all,@course_activity_count + #gcmend + + @courses=handle_course @courses_all,@course_activity_count + @s_type = 3 + @courses = @courses[@course_pages.offset, @course_pages.per_page] + else + @s_type = 0 + @courses = @courses_all.order("created_on desc") + @courses = @courses.offset(@course_pages.offset).limit(@course_pages.per_page) + + #gcm + @course_activity_count=get_course_activity @courses,@course_activity_count + #gcmend + + end + + respond_to do |format| + format.html { + render :layout => 'base' + } + format.api { + # @offset, @limit = api_offset_and_limit + # @course_count = Course.visible.count + # @courses = Course.visible.offset(@offset).limit(@limit).order('lft').all + } + format.atom { + courses = Course.visible.order('created_on DESC').limit(Setting.feeds_limit.to_i).all + render_feed(courses, :title => "#{Setting.app_title}: #{l(:label_course_latest)}") + } + end + end + + + def new + @course_type = params[:course_type] ||= params[:course] + @issue_custom_fields = IssueCustomField.sorted.all + @trackers = Tracker.sorted.all + + @course = Course.new + @course.safe_attributes = params[:course] + + render :layout => 'base' + end + + + def desc_sort_course_by_avtivity(activity_count, courses) + return courses if activity_count.size<2 + (activity_count.size-2).downto(0) do |i| + (0..i).each do |j| + if activity_count[j] 'base' + } + format.atom { + courses = Course.visible.order('created_on DESC').limit(Setting.feeds_limit.to_i).all + render_feed(courses, :title => "#{Setting.app_title}: #{l(:label_course_latest)}") + } + end + end + + def homework + @offset, @limit = api_offset_and_limit({:limit => 10}) + @bids = @course.homeworks.order('deadline DESC') + @bids = @bids.like(params[:name]) if params[:name].present? + @bid_count = @bids.count + @bid_pages = Paginator.new @bid_count, @limit, params['page'] + + @offset ||= @bid_pages.reverse_offset + unless @offset == 0 + @bids = @bids.offset(@offset).limit(@limit).all.reverse + else + limit = @bid_count % @limit + if limit == 0 + limit = 10 + end + @bids = @bids.offset(@offset).limit(limit).all.reverse + end + render :layout => 'base_courses' + end + + # 新建作业 + def new_homework + if (User.current.logged? && + (User.current.admin? || + ( + !Member.where('user_id = ? and course_id = ?', User.current.id, @course.id).first.nil? && + ( + Member.where('user_id = ? and course_id = ?', User.current.id, @course.id).first.roles && + ( Role.where(id: [3, 4, 7, 9]).size > 0 ) + ) + ) + ) + ) + @homework = Bid.new + @homework.safe_attributes = params[:bid] + render :layout => 'base_courses' + else + render_404 + end + + end + + def get_course_activity courses, activities + @course_ids=activities.keys() + + days = Setting.activity_days_default.to_i + date_to ||= Date.today + 1 + date_from = date_to - days-1.years + + #file_count + Attachment.where(container_id: @course_ids, container_type: Course).where("created_on>?", date_from).each do |attachment| + activities[attachment.container_id]+=1 + end + + #message_count + Board.where(course_id: @course_ids).each do |board| +# activities[board.course_id]+=1 + activities[board.course_id]+=board.messages.where("updated_on>?", date_from).count + end + + #news + News.where(course_id: @course_ids).where("created_on>?",date_from).each do |news| + activities[news.course_id]+=1 + end + + #feedbackc_count + JournalsForMessage.where(jour_id: @course_ids, jour_type: Course).each do |jourformess| + activities[jourformess.jour_id]+=1 + end + + #activities!=0 + i=0; + courses.each do |course| + id=course.id + if activities[id]==0 + activities[id]=1 + end + end + + return activities + end + + def toggleCourse + @course_prefs = Course.find_by_extra(@course.extra) + unless (@course_prefs.teacher == User.current || User.current.admin?) + render_403 + end + end + + def get_courses + @user = User.current + membership = @user.coursememberships.all + membership.sort! {|older, newer| newer.created_on <=> older.created_on } + @memberships = [] + membership.collect { |e| + @memberships.push(e) + } + @memberships_doing = [] + @memberships_done = [] + now_time = Time.now.year + @memberships.map { |e| + end_time = e.course.get_time.year + isDone = course_endTime_timeout?(e.course) + if isDone + @memberships_done.push e + else + @memberships_doing.push e + end + } + end + + def finishcourse + yesterday = Date.today.prev_day.to_time + + @course_prefs.endup_time = yesterday + @save_flag = @course_prefs.save + get_courses + + respond_to do |format| + format.js + end + end + + + def restartcourse + day = Time.parse("3000-01-01") + + @course_prefs.endup_time = day + @save_flag = @course_prefs.save + get_courses + + respond_to do |format| + format.js { + render action:'finishcourse' + } + end + end + + def show + # try to redirect to the requested menu item + if params[:jump] && redirect_to_course_menu_item(@course, params[:jump]) + return + end + + @users_by_role = @course.users_by_role + if(User.find_by_id(CourseInfos.find_by_course_id(@course.id).try(:user_id))) + @user = User.find_by_id(CourseInfos.find_by_course_id(@course.id).user_id) + end + + + @key = User.current.rss_key + #新增内容 + @days = Setting.activity_days_default.to_i + + if params[:from] + begin; @date_to = params[:from].to_date + 1; rescue; end + end + + has = { + "show_course_files" => true, + "show_course_news" => true, + "show_course_messages" => true, + "show_bids" => true, + "show_course_journals_for_messages" => true + } + @date_to ||= Date.today + 1 + @date_from = @date_to - @days-1.years + @author = (params[:user_id].blank? ? nil : User.active.find(params[:user_id])) + # 决定显示所用用户或单个用户活动 + @activity = Redmine::Activity::Fetcher.new(User.current, :course => @course, + :with_subprojects => false, + :author => @author) + @activity.scope_select {|t| has["show_#{t}"]} + events = @activity.events(@date_from, @date_to) + + @offset, @limit = api_offset_and_limit({:limit => 10}) + @events_count = events.count + @events_pages = Paginator.new @events_count, @limit, params['page'] + @offset ||= @events_pages.offset + events = events.slice(@offset,@limit) + + @events_by_day = events.group_by {|event| User.current.time_to_date(event.event_datetime)} + # documents + @sort_by = %w(category date title author).include?(params[:sort_by]) ? params[:sort_by] : 'category' + # + @teachers= searchTeacherAndAssistant(@course) + @canShowRealName = isCourseTeacher(User.current.id) + + if(User.find_by_id(CourseInfos.find_by_course_id(@course.id).try(:user_id))) + @user = User.find_by_id(CourseInfos.find_by_course_id(@course.id).user_id) + end + + respond_to do |format| + format.html{render :layout => 'base_courses'} + format.api + end + end + + #判断指定用户是否为课程教师 + def isCourseTeacher(id) + result = false + if @teachers && @teachers.find_by_user_id(id) != nil + result = true + end + result + end + + def feedback + page = params[:page] + # Find the page of the requested reply + @jours = @course.journals_for_messages.where('m_parent_id IS NULL').order('created_on DESC') + @limit = 10 + if params[:r] && page.nil? + offset = @jours.count(:conditions => ["#{JournalsForMessage.table_name}.id > ?", params[:r].to_i]) + page = 1 + offset / @limit + end + + @feedback_count = @jours.count + @feedback_pages = Paginator.new @feedback_count, @limit, page + @offset ||= @feedback_pages.offset + @jour = @jours[@offset, @limit] + @state = false + respond_to do |format| + format.html{render :layout => 'base_courses'} + format.api + end + end + + + private def allow_join - if course_endTime_timeout? Project.find(params[:object_id]) + if course_endTime_timeout? Course.find(params[:object_id]) respond_to do |format| - format.js{ + format.js { @state = 2 - render :partial => 'set_join', - :locals => {:user => User.current, - :course => Project.find(params[:object_id]), - :object_id => params[:object_id] - } + render :partial => 'set_join', + :locals => {:user => User.current, + :course => Course.find(params[:object_id]), + :object_id => params[:object_id] + } } end end end + + + + end \ No newline at end of file diff --git a/app/controllers/files_controller.rb b/app/controllers/files_controller.rb index ed6f9937d..b5c67478c 100644 --- a/app/controllers/files_controller.rb +++ b/app/controllers/files_controller.rb @@ -32,14 +32,16 @@ class FilesController < ApplicationController 'filename' => "#{Attachment.table_name}.filename", 'size' => "#{Attachment.table_name}.filesize", 'downloads' => "#{Attachment.table_name}.downloads" - - @containers = [ Project.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").find(@project.id)] #modify by Long Jun - @containers += @project.versions.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").all.sort - - if @project.project_type == 1 + + if params[:project_id] + @isproject = true + @containers = [ Project.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").find(@project.id)] + @containers += @project.versions.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").all.sort + render :layout => !request.xhr? + elsif params[:course_id] + @isproject = false + @containers = [ Course.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").find(@course.id)] render :layout => 'base_courses' - else - render :layout => !request.xhr? end end @@ -60,37 +62,66 @@ class FilesController < ApplicationController respond_to do |format| format.js end - else - @addTag=false - container = (params[:version_id].blank? ? @project : @project.versions.find_by_id(params[:version_id])) - attachments = Attachment.attach_filesex(container, params[:attachments],params[:attachment_type]) - render_attachment_warning_if_needed(container) + else + #modify by nwb + if @project + @addTag=false + container = (params[:version_id].blank? ? @project : @project.versions.find_by_id(params[:version_id])) + attachments = Attachment.attach_filesex(container, params[:attachments], params[:attachment_type]) + render_attachment_warning_if_needed(container) - if !attachments.empty? && !attachments[:files].blank? && Setting.notified_events.include?('file_added') - Mailer.attachments_added(attachments[:files]).deliver - end + if !attachments.empty? && !attachments[:files].blank? && Setting.notified_events.include?('file_added') + Mailer.attachments_added(attachments[:files]).deliver + end - # TODO: 临时用 nyan - sort_init 'created_on', 'desc' - sort_update 'created_on' => "#{Attachment.table_name}.created_on", - 'filename' => "#{Attachment.table_name}.filename", - 'size' => "#{Attachment.table_name}.filesize", - 'downloads' => "#{Attachment.table_name}.downloads" + # TODO: 临时用 nyan + sort_init 'created_on', 'desc' + sort_update 'created_on' => "#{Attachment.table_name}.created_on", + 'filename' => "#{Attachment.table_name}.filename", + 'size' => "#{Attachment.table_name}.filesize", + 'downloads' => "#{Attachment.table_name}.downloads" - @containers = [ Project.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").find(@project.id)] #modify by Long Jun - @containers += @project.versions.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").all.sort + @containers = [Project.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").find(@project.id)] #modify by Long Jun + @containers += @project.versions.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").all.sort - @attachtype = 0 - @contenttype = 0 + @attachtype = 0 + @contenttype = 0 - respond_to do |format| - format.js - format.html { - redirect_to project_files_path(@project) - } - end + respond_to do |format| + format.js + format.html { + redirect_to project_files_path(@project) + } + end + elsif @course + @addTag=false + attachments = Attachment.attach_filesex(@course, params[:attachments], params[:attachment_type]) - end + if !attachments.empty? && !attachments[:files].blank? && Setting.notified_events.include?('file_added') + Mailer.attachments_added(attachments[:files]).deliver + end + + # TODO: 临时用 nyan + sort_init 'created_on', 'desc' + sort_update 'created_on' => "#{Attachment.table_name}.created_on", + 'filename' => "#{Attachment.table_name}.filename", + 'size' => "#{Attachment.table_name}.filesize", + 'downloads' => "#{Attachment.table_name}.downloads" + + @containers = [Course.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").find(@course.id)] + + @attachtype = 0 + @contenttype = 0 + + respond_to do |format| + format.js + format.html { + redirect_to course_files_path(@course) + } + end + end + + end end def tag_saveEx @@ -115,6 +146,8 @@ class FilesController < ApplicationController @obj = Contest.find_by_id(@obj_id) when '8' @obj = OpenSourceProject.find_by_id(@obj_id) + when '9' + @obj = Course.find_by_id(@obj_id) else @obj = nil end @@ -131,16 +164,21 @@ class FilesController < ApplicationController end # 返回制定资源类型的资源列表 + # added by nwb def getattachtype sort_init 'created_on', 'desc' sort_update 'created_on' => "#{Attachment.table_name}.created_on", 'filename' => "#{Attachment.table_name}.filename", 'size' => "#{Attachment.table_name}.filesize", 'downloads' => "#{Attachment.table_name}.downloads" - - @containers = [ Project.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").find(@project.id)] #modify by Long Jun - @containers += @project.versions.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").all.sort - + + if @project + @containers = [ Project.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").find(@project.id)] + @containers += @project.versions.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").all.sort + elsif @course + @containers = [ Course.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").find(@course.id)] + end + @attachtype = params[:type].to_i @contenttype = params[:contentType].to_s diff --git a/app/controllers/homework_attach_controller.rb b/app/controllers/homework_attach_controller.rb index d10f09ffa..83a6aa05f 100644 --- a/app/controllers/homework_attach_controller.rb +++ b/app/controllers/homework_attach_controller.rb @@ -1,21 +1,22 @@ class HomeworkAttachController < ApplicationController + include CoursesHelper ############################### #判断当前角色权限时需先找到当前操作的project - before_filter :find_project_by_bid_id, :only => [:new] - before_filter :find_project_by_hoemwork_id, :only => [:edit,:update,:destroy,:show,:add_homework_users,:destory_homework_users] + before_filter :find_course_by_bid_id, :only => [:new] + before_filter :find_course_by_hoemwork_id, :only => [:edit,:update,:destroy,:show,:add_homework_users,:destory_homework_users] #判断当前角色是否有操作权限 #勿删 before_filter :authorize, :only => [:new,:edit,:update,:destroy] - def find_project_by_bid_id + def find_course_by_bid_id @bid = Bid.find(params[:id]) - @project = @bid.courses[0] + @course = @bid.courses[0] rescue ActiveRecord::RecordNotFound render_404 end - def find_project_by_hoemwork_id + def find_course_by_hoemwork_id @homework = HomeworkAttach.find(params[:id]) - @project = @homework.bid.courses[0] + @course = @homework.bid.courses[0] end #获取作业的成员 @@ -35,7 +36,7 @@ class HomeworkAttachController < ApplicationController #作业添加成员(参与人员) def add_homework_users - if User.current.admin? || User.current.member_of?(@homework.bid.courses.first) + if User.current.admin? || User.current.member_of_course?(@homework.bid.courses.first) #@homework = HomeworkAttach.find(params[:id]) if params[:membership] if params[:membership][:user_ids] @@ -59,7 +60,7 @@ class HomeworkAttachController < ApplicationController #作业删除成员(参与人员) def destory_homework_users #@homework = HomeworkAttach.find(params[:id]) - if User.current.admin? || User.current.member_of?(@homework.bid.courses.first) + if User.current.admin? || User.current.member_of_course?(@homework.bid.courses.first) homework_user = @homework.homework_users.where("user_id = #{params[:user_id]}").first homework_user.destroy get_homework_member @homework @@ -73,10 +74,19 @@ class HomeworkAttachController < ApplicationController def create bid = Bid.find params[:bid_id] - if User.current.admin? || User.current.member_of?(bid.courses.first) + if User.current.admin? || User.current.member_of_course?(bid.courses.first) # modify by nwb if bid.homeworks.where("user_id = ?",User.current).count == 0 user_id = params[:user_id] bid_id = params[:bid_id] + if params[:homework_attach] + if params[:homework_attach][:project_id] + project_id = params[:homework_attach][:project_id] + else + project_id = 0 + end + else + project_id = 0 + end sta = 0 name = params[:new_form][:name] description = params[:new_form][:description] @@ -85,7 +95,8 @@ class HomeworkAttachController < ApplicationController :state => sta, :name => name, :description => description, - :bid_id => bid_id + :bid_id => bid_id, + :project_id => project_id } @@ -97,7 +108,7 @@ class HomeworkAttachController < ApplicationController if @homework.save respond_to do |format| - format.html { redirect_to project_for_bid_path @homework.bid } + format.html { redirect_to course_for_bid_path @homework.bid } format.json { head :no_content } end else @@ -113,7 +124,7 @@ class HomeworkAttachController < ApplicationController def new @bid = Bid.find(params[:id]) - if User.current.admin? || User.current.member_of?(@bid.courses.first) + if User.current.admin? || User.current.member_of_course?(@bid.courses.first) #nwb #该课程的学生的集合(新建不实现功能:添加成员) #@members = @bid.courses.first.members.joins(:member_roles).where("member_roles.role_id IN (:role_id) and user_id <> #{User.current.id}", {:role_id => [5, 10]}) @@ -138,7 +149,7 @@ class HomeworkAttachController < ApplicationController def get_homework_member_list @homework = HomeworkAttach.find(params[:bid_id]) course = @homework.bid.courses.first - if User.current.admin? || User.current.member_of?(course) + if User.current.admin? || User.current.member_of_course?(course) get_homework_member @homework else raise "error" @@ -163,7 +174,7 @@ class HomeworkAttachController < ApplicationController def edit #@homework = HomeworkAttach.find(params[:id]) - if User.current.admin? || User.current.member_of?(@homework.bid.courses.first) + if User.current.admin? || User.current.member_of_course?(@homework.bid.courses.first) #@members = @homework.bid.courses.first.members.joins(:member_roles).where("member_roles.role_id IN (:role_id)", {:role_id => [5, 10]}) get_homework_member @homework else @@ -174,17 +185,27 @@ class HomeworkAttachController < ApplicationController def update #@homework = HomeworkAttach.find(params[:id]) course = @homework.bid.courses.first - if User.current.admin? || User.current.member_of?(course) + if User.current.admin? || User.current.member_of_course?(course) name = params[:homework_name] description = params[:homework_description] + if params[:homework_attach] + if params[:homework_attach][:project_id] + project_id = params[:homework_attach][:project_id] + else + project_id = 0 + end + else + project_id = 0 + end @homework.name = name @homework.description = description + @homework.project_id = project_id if params[:attachments] @homework.save_attachments(params[:attachments]) end if @homework.save respond_to do |format| - format.html { redirect_to project_for_bid_path @homework.bid } + format.html { redirect_to course_for_bid_path @homework.bid } format.json { head :no_content } end else @@ -196,10 +217,10 @@ class HomeworkAttachController < ApplicationController def destroy #@homework = HomeworkAttach.find(params[:id]) - if User.current.admin? || User.current == @homework + if User.current.admin? || User.current == @homework.user if @homework.destroy respond_to do |format| - format.html { redirect_to project_for_bid_path @homework.bid } + format.html { redirect_to course_for_bid_path @homework.bid } format.json { head :no_content } end else @@ -212,7 +233,7 @@ class HomeworkAttachController < ApplicationController #显示作业信息 def show #@homework = HomeworkAttach.find(params[:id]) - if User.current.admin? || User.current.member_of?(@homework.bid.courses.first) + if User.current.admin? || User.current.member_of_course?(@homework.bid.courses.first) # 打分统计 stars_reates = @homework. rates(:quality) @@ -237,6 +258,9 @@ class HomeworkAttachController < ApplicationController @offset ||= @feedback_pages.offset @jour = @jours[@offset, @limit] @comprehensive_evaluation = @homework.journals_for_messages.where("is_comprehensive_evaluation is not null").order("created_on DESC") + + @totle_score = score_for_homework @homework + @teaher_score = teacher_score_for_homework @homework else render_403 :message => :notice_not_authorized end @@ -268,11 +292,24 @@ class HomeworkAttachController < ApplicationController @offset ||= @feedback_pages.offset @jour = @jours[@offset, @limit] @comprehensive_evaluation = @homework.journals_for_messages.where("is_comprehensive_evaluation is not null").order("created_on DESC") + + @totle_score = score_for_homework @homework + @teaher_score = teacher_score_for_homework @homework respond_to do |format| format.js end end + #教师综评 + def comprehensive_evaluation_jour + @homework = HomeworkAttach.find(params[:jour_id]) + @add_jour = @homework.addjours User.current.id, params[:new_form][:user_message],0,params[:is_comprehensive_evaluation] + respond_to do |format| + format.html { redirect_to homework_attach_path @homework } + format.json { head :no_content } + end + end + #获取指定作业的平均得分 def score #stars_reates = @homework.rates(:quality) diff --git a/app/controllers/members_controller.rb b/app/controllers/members_controller.rb index 5a2f6027e..76be02409 100644 --- a/app/controllers/members_controller.rb +++ b/app/controllers/members_controller.rb @@ -22,15 +22,16 @@ class MembersController < ApplicationController before_filter :find_project_by_project_id, :only => [:index, :create, :autocomplete] before_filter :authorize accept_api_auth :index, :show, :create, :update, :destroy + def index @offset, @limit = api_offset_and_limit @member_count = @project.member_principals.count @member_pages = Paginator.new @member_count, @limit, params['page'] @offset ||= @member_pages.offset - @members = @project.member_principals.all( - :order => "#{Member.table_name}.id", - :limit => @limit, - :offset => @offset + @members = @project.member_principals.all( + :order => "#{Member.table_name}.id", + :limit => @limit, + :offset => @offset ) respond_to do |format| @@ -60,121 +61,217 @@ class MembersController < ApplicationController end end else + #modify by nwb + #更改课程成员逻辑 applied_members = false members = [] - project_info = [] user_grades = [] - if params[:membership] - if params[:membership][:user_ids] - attrs = params[:membership].dup - user_ids = attrs.delete(:user_ids) - user_ids.each do |user_id| - members << Member.new(:role_ids => params[:membership][:role_ids], :user_id => user_id) - user_grades << UserGrade.new(:user_id => user_id, :project_id => @project.id) + if @project + project_info = [] + if params[:membership] + if params[:membership][:user_ids] + attrs = params[:membership].dup + user_ids = attrs.delete(:user_ids) + user_ids.each do |user_id| + members << Member.new(:role_ids => params[:membership][:role_ids], :user_id => user_id) + user_grades << UserGrade.new(:user_id => user_id, :project_id => @project.id) + ## added by nie + if (params[:membership][:role_ids] && params[:membership][:role_ids][0] == "3") + project_info << ProjectInfo.new(:user_id => user_id, :project_id => @project.id) + # ProjectInfo.create(:name => "test", :user_id => 123) + end + ## end + end + else + members << Member.new(:role_ids => params[:membership][:role_ids], :user_id => params[:membership][:user_id]) + user_grades << UserGrade.new(:user_id => params[:membership][:user_id], :project_id => @project.id) ## added by nie if (params[:membership][:role_ids] && params[:membership][:role_ids][0] == "3") - project_info << ProjectInfo.new(:user_id => user_id, :project_id => @project.id) - # ProjectInfo.create(:name => "test", :user_id => 123) + project_info << ProjectInfo.new(:project_id => @project.id, :user_id => params[:membership][:user_id]) end ## end - end - else - members << Member.new(:role_ids => params[:membership][:role_ids], :user_id => params[:membership][:user_id]) - user_grades << UserGrade.new(:user_id => params[:membership][:user_id], :project_id => @project.id) - ## added by nie - if (params[:membership][:role_ids] && params[:membership][:role_ids][0] == "3") - project_info << ProjectInfo.new(:project_id => @project.id, :user_id => params[:membership][:user_id]) end - ## end + @project.members << members + # added by nie + @project.project_infos << project_info + @project.user_grades << user_grades + # end end - @project.members << members - # added by nie - @project.project_infos << project_info - @project.user_grades << user_grades - # end - end - end - - if members.present? && members.all? {|m| m.valid? } - members.each do |member| - AppliedProject.deleteappiled(member.user_id, @project.id) - end - - end - - respond_to do |format| - format.html { redirect_to_settings_in_projects } - format.js { @members = members;@applied_members = applied_members; } - format.api { - @member = members.first - if @member.valid? - render :action => 'show', :status => :created, :location => membership_url(@member) - else - render_validation_errors(@member) + if members.present? && members.all? { |m| m.valid? } + members.each do |member| + AppliedProject.deleteappiled(member.user_id, @project.id) + end end - } - end + respond_to do |format| + format.html { redirect_to_settings_in_projects } + format.js { @members = members; @applied_members = applied_members; } + format.api { + @member = members.first + if @member.valid? + render :action => 'show', :status => :created, :location => membership_url(@member) + else + render_validation_errors(@member) + end + } + end + elsif @course + course_info = [] + if params[:membership] + if params[:membership][:user_ids] + attrs = params[:membership].dup + user_ids = attrs.delete(:user_ids) + user_ids.each do |user_id| + members << Member.new(:role_ids => params[:membership][:role_ids], :user_id => user_id) + user_grades << UserGrade.new(:user_id => user_id, :course_id => @course.id) + if (params[:membership][:role_ids] && params[:membership][:role_ids][0] == "3") + course_info << CourseInfo.new(:user_id => user_id, :course_id => @course.id) + end + end + else + members << Member.new(:role_ids => params[:membership][:role_ids], :user_id => params[:membership][:user_id]) + if (params[:membership][:role_ids] && params[:membership][:role_ids][0] == "3") + course_info << CourseInfo.new(:course_id => @course.id, :user_id => params[:membership][:user_id]) + end + end + @course.members << members + @course.course_infos << course_info + end + respond_to do |format| + format.html { redirect_to_settings_in_courses } + format.js { @members = members; @applied_members = applied_members; } + format.api { + @member = members.first + if @member.valid? + render :action => 'show', :status => :created, :location => membership_url(@member) + else + render_validation_errors(@member) + end + } + end + end # end of if @project + + end # end of params[:refusal_button] + end def update - if params[:membership] - @member.role_ids = params[:membership][:role_ids] + #modify by nwb + #增加对课程成员修改的支持 + if @project + if params[:membership] + @member.role_ids = params[:membership][:role_ids] - #added by nie - if(params[:membership][:role_ids] && params[:membership][:role_ids][0] == "3") - @projectInfo = ProjectInfo.new(:user_id => @member.user_id, :project_id => @project.id) - @projectInfo.save - else + #added by nie + if (params[:membership][:role_ids] && params[:membership][:role_ids][0] == "3") + @projectInfo = ProjectInfo.new(:user_id => @member.user_id, :project_id => @project.id) + @projectInfo.save + else + user_admin = ProjectInfo.where("user_id = ? and project_id = ?", @member.user_id, @project.id) + if user_admin.size > 0 + user_admin.each do |user| + user.destroy + end + end + end + end + + saved = @member.save + respond_to do |format| + format.html { redirect_to_settings_in_projects } + format.js + format.api { + if saved + render_api_ok + else + render_validation_errors(@member) + end + } + end + elsif @course + if params[:membership] + @member.role_ids = params[:membership][:role_ids] + + if (params[:membership][:role_ids] && params[:membership][:role_ids][0] == "3") + @courseInfo = CourseInfos.new(:user_id => @member.user_id, :course_id => @course.id) + @courseInfo.save + else + user_admin = CourseInfos.where("user_id = ? and course_id = ?", @member.user_id, @course.id) + if user_admin.size > 0 + user_admin.each do |user| + user.destroy + end + end + end + end + + saved = @member.save + respond_to do |format| + format.html { redirect_to_settings_in_courses } + format.js + format.api { + if saved + render_api_ok + else + render_validation_errors(@member) + end + } + end + end + + end + + def destroy + #modify by nwb + #课程成员删除修改 + if @project + if request.delete? && @member.deletable? + @member.destroy + # end user_admin = ProjectInfo.where("user_id = ? and project_id = ?", @member.user_id, @project.id) if user_admin.size > 0 user_admin.each do |user| user.destroy end end - end - end - - saved = @member.save - respond_to do |format| - format.html { redirect_to_settings_in_projects } - format.js - format.api { - if saved - render_api_ok - else - render_validation_errors(@member) - end - } - end - end - - def destroy - if request.delete? && @member.deletable? - @member.destroy - # end - user_admin = ProjectInfo.where("user_id = ? and project_id = ?", @member.user_id, @project.id) - if user_admin.size > 0 - user_admin.each do |user| - user.destroy + user_grade = UserGrade.where("user_id = ? and project_id = ?", @member.user_id, @project.id) + if user_grade.size > 0 + user_grade.each do |grade| + grade.destroy + end end end - user_grade = UserGrade.where("user_id = ? and project_id = ?", @member.user_id, @project.id) - if user_grade.size > 0 - user_grade.each do |grade| - grade.destroy + respond_to do |format| + format.html { redirect_to_settings_in_projects } + format.js + format.api { + if @member.destroyed? + render_api_ok + else + head :unprocessable_entity + end + } + end + elsif @course + if request.delete? && @member.deletable? + @member.destroy + user_admin = CourseInfos.where("user_id = ? and course_id = ?", @member.user_id, @course.id) + if user_admin.size > 0 + user_admin.each do |user| + user.destroy + end end end - end - respond_to do |format| - format.html { redirect_to_settings_in_projects } - format.js - format.api { - if @member.destroyed? - render_api_ok - else - head :unprocessable_entity - end - } + respond_to do |format| + format.html { redirect_to_settings_in_courses } + format.js + format.api { + if @member.destroyed? + render_api_ok + else + head :unprocessable_entity + end + } + end end end @@ -189,4 +286,8 @@ class MembersController < ApplicationController def redirect_to_settings_in_projects redirect_to settings_project_path(@project, :tab => 'members') end + + def redirect_to_settings_in_courses + redirect_to settings_course_path(@course, :tab => 'members') + end end diff --git a/app/controllers/messages_controller.rb b/app/controllers/messages_controller.rb index 150071b41..2a408788e 100644 --- a/app/controllers/messages_controller.rb +++ b/app/controllers/messages_controller.rb @@ -49,7 +49,7 @@ class MessagesController < ApplicationController all @reply = Message.new(:subject => "RE: #{@message.subject}") - if @message.board.project.project_type ==1 + if @course render :action => "show", :layout => "base_courses"#by young else render :action => "show", :layout => "base_projects"#by young @@ -68,6 +68,9 @@ class MessagesController < ApplicationController call_hook(:controller_messages_new_after_save, { :params => params, :message => @message}) render_attachment_warning_if_needed(@message) redirect_to board_message_path(@board, @message) + else + layout_file = @project ? 'base_projects' : 'base_courses' + render :action => 'new', :layout => layout_file end end end @@ -138,8 +141,14 @@ private end def find_board - @board = Board.find(params[:board_id], :include => :project) - @project = @board.project + #modify by nwb + @board = Board.find(params[:board_id]) + if @board.project_id != -1 && @board.project_id != nil + @project = @board.project + elsif @board.course_id + @course = @board.course + end + rescue ActiveRecord::RecordNotFound render_404 nil diff --git a/app/controllers/my_controller.rb b/app/controllers/my_controller.rb index a87df4fef..9b169cb81 100644 --- a/app/controllers/my_controller.rb +++ b/app/controllers/my_controller.rb @@ -61,7 +61,7 @@ class MyController < ApplicationController end end - @se = @user.user_extensions ||= UserExtensions.new + @se = @user.extensions @se.school_id = params[:occupation] if params[:occupation] @se.gender = params[:gender] @se.location = params[:province] if params[:province] diff --git a/app/controllers/news_controller.rb b/app/controllers/news_controller.rb index ee3db741d..8bce84f90 100644 --- a/app/controllers/news_controller.rb +++ b/app/controllers/news_controller.rb @@ -38,37 +38,62 @@ class NewsController < ApplicationController @limit = 10 end - scope = @project ? @project.news.visible : News.visible - - @news_count = scope.count - @news_pages = Paginator.new @news_count, @limit, params['page'] - @offset ||= @news_pages.offset - @newss = scope.all(:include => [:author, :project], - :order => "#{News.table_name}.created_on DESC", - :offset => @offset, - :limit => @limit) - - respond_to do |format| - format.html { - @news = News.new # for adding news inline - # huang - - if @project.project_type == 1 - render :layout => 'base_courses' - else - render :layout => false if request.xhr? - end - } - format.api - format.atom { render_feed(@newss, :title => (@project ? @project.name : Setting.app_title) + ": #{l(:label_news_plural)}") } + # modify by nwb + if params[:course_id] && @course==nil + @course = Course.find(params[:course_id]) end - end + if @project + scope = @project ? @project.news.visible : News.visible + + @news_count = scope.count + @news_pages = Paginator.new @news_count, @limit, params['page'] + @offset ||= @news_pages.offset + @newss = scope.all(:include => [:author, :project], + :order => "#{News.table_name}.created_on DESC", + :offset => @offset, + :limit => @limit) + + respond_to do |format| + format.html { + @news = News.new # for adding news inline + # huang + + render :layout => false if request.xhr? + } + format.api + format.atom { render_feed(@newss, :title => (@project ? @project.name : Setting.app_title) + ": #{l(:label_news_plural)}") } + end + elsif @course + scope = @course ? @course.news.course_visible : News.course_visible + + @news_count = scope.count + @news_pages = Paginator.new @news_count, @limit, params['page'] + @offset ||= @news_pages.offset + @newss = scope.all(:include => [:author, :course], + :order => "#{News.table_name}.created_on DESC", + :offset => @offset, + :limit => @limit) + + respond_to do |format| + format.html { + @news = News.new + render :layout => 'base_courses' + } + format.api + format.atom { render_feed(@newss, :title => (@course ? @course.name : Setting.app_title) + ": #{l(:label_news_plural)}") } + end + end + end def show @comments = @news.comments - @comments.reverse! if User.current.wants_comments_in_reverse_order? - if @project.project_type == 1 - render :layout => 'base_courses' + @comments.reverse! if User.current.wants_comments_in_reverse_order? + #modify by nwb + if @news.course_id + @course = Course.find(@news.course_id) + if @course + render :layout => 'base_courses' + end end end @@ -81,16 +106,31 @@ class NewsController < ApplicationController end def create - @news = News.new(:project => @project, :author => User.current) - @news.safe_attributes = params[:news] - @news.save_attachments(params[:attachments]) - if @news.save - render_attachment_warning_if_needed(@news) - flash[:notice] = l(:notice_successful_create) - redirect_to project_news_index_path(@project) - else - layout_file = (@project.project_type == 1) ? 'base_courses' : 'base_projects' - render :action => 'new', :layout => layout_file + #modify by nwb + if @project + @news = News.new(:project => @project, :author => User.current) + @news.safe_attributes = params[:news] + @news.save_attachments(params[:attachments]) + if @news.save + render_attachment_warning_if_needed(@news) + flash[:notice] = l(:notice_successful_create) + redirect_to project_news_index_path(@project) + else + layout_file = @project ? 'base_projects' : 'base_courses' + render :action => 'new', :layout => layout_file + end + elsif @course + @news = News.new(:course => @course, :author => User.current) + @news.safe_attributes = params[:news] + @news.save_attachments(params[:attachments]) + if @news.save + render_attachment_warning_if_needed(@news) + flash[:notice] = l(:notice_successful_create) + redirect_to course_news_index_path(@course) + else + layout_file = 'base_courses' + render :action => 'new', :layout => layout_file + end end end @@ -111,7 +151,13 @@ class NewsController < ApplicationController def destroy @news.destroy - redirect_to project_news_index_path(@project) + # modify by nwb + if @project + redirect_to project_news_index_path(@project) + elsif @course + redirect_to course_news_index_path(@course) + end + end private diff --git a/app/controllers/praise_tread_controller.rb b/app/controllers/praise_tread_controller.rb index 53c74519b..acfd785d9 100644 --- a/app/controllers/praise_tread_controller.rb +++ b/app/controllers/praise_tread_controller.rb @@ -9,8 +9,12 @@ class PraiseTreadController < ApplicationController if request.get? @obj_id = params[:obj_id] @obj_type = params[:obj_type] + @horizontal = params[:horizontal].downcase == "false" ? false:true @obj = find_object_by_type_and_id(@obj_type,@obj_id) - praise_tread_plus(@obj_type,@obj_id,1) + unless @obj.author_id == User.current.id + praise_tread_plus(@obj_type,@obj_id,1) + end + end end @@ -44,8 +48,12 @@ class PraiseTreadController < ApplicationController if request.get? @obj_id = params[:obj_id] @obj_type = params[:obj_type] + @horizontal = params[:horizontal].downcase == "false" ? false:true @obj = find_object_by_type_and_id(@obj_type,@obj_id) - praise_tread_plus(@obj_type,@obj_id,0) + unless @obj.author_id == User.current.id + praise_tread_plus(@obj_type,@obj_id,0) + end + end end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index ad3dc3dca..792a18e59 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -353,27 +353,13 @@ class ProjectsController < ApplicationController #gcmend - # added by fq - def new_join - @course = Project.find(params[:object_id]) - end - #Added by young def homework @offset, @limit = api_offset_and_limit({:limit => 10}) - @bids = @project.homeworks.order('deadline DESC') + @bids = @project.homeworks.order('deadline') @bids = @bids.like(params[:name]) if params[:name].present? - @bid_count = @bids.count - @bid_pages = Paginator.new @bid_count, @limit, params['page'] - @offset ||= @bid_pages.reverse_offset - #@bids = @bids.offset(@offset).limit(@limit).all.reverse - unless @offset == 0 - @bids = @bids.offset(@offset).limit(@limit).all.reverse - else - limit = @bid_count % @limit - @bids = @bids.offset(@offset).limit(limit).all.reverse - end + @bids = paginateHelper @bids render :layout => 'base_courses' end @@ -920,11 +906,13 @@ class ProjectsController < ApplicationController # added by bai def show_projects_score - + render :layout => false end def issue_score_index - + respond_to do |format| + format.js + end end def news_score_index diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index 70f7572a8..3b97802f5 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -568,7 +568,7 @@ class RepositoriesController < ApplicationController project = Project.find(params[:id]) if !User.current.member_of?(project) if project.hidden_repo - render_403 + #render_403 end end rescue ActiveRecord::RecordNotFound diff --git a/app/views/roles/roles_controller.rb b/app/controllers/roles_controller.rb similarity index 100% rename from app/views/roles/roles_controller.rb rename to app/controllers/roles_controller.rb diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index 84c3aff0f..4c0d91884 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -4,7 +4,8 @@ class TagsController < ApplicationController layout "base_tags" before_filter :require_admin,:only => :show - + + include CoursesHelper include ProjectsHelper include IssuesHelper include UsersHelper @@ -14,6 +15,7 @@ class TagsController < ApplicationController include ContestsHelper include ActsAsTaggableOn::TagsHelper helper :projects + helper :courses include TagsHelper helper :tags include OpenSourceProjectsHelper @@ -64,6 +66,7 @@ class TagsController < ApplicationController # 获取搜索结果 @obj,@obj_pages,@results_count,@users_results, @projects_results, + @@courses_results, @issues_results, @bids_results, @forums_results, @@ -96,6 +99,7 @@ class TagsController < ApplicationController # 获取搜索结果 @obj,@obj_pages,@results_count,@users_results, @projects_results, + @@courses_results, @issues_results, @bids_results, @forums_results, @@ -114,6 +118,7 @@ class TagsController < ApplicationController # 获取搜索结果 @obj,@obj_pages,@results_count,@users_results, @projects_results, + @@courses_results, @issues_results, @bids_results, @forums_results, @@ -188,6 +193,7 @@ class TagsController < ApplicationController @obj_pages = nil @obj = nil @result = nil + @courses_results = nil # 这里为了提高系统的响应速度 把搜索结果放到case中去了 case obj_flag @@ -219,6 +225,9 @@ class TagsController < ApplicationController when '8' @obj = OpenSourceProject.find_by_id(obj_id) @obj_pages, @open_source_projects_results, @results_count = for_pagination(get_open_source_projects_by_tag(selected_tags)) + when '9' then + @obj = Course.find_by_id(obj_id) + @obj_pages, @courses_results, @results_count = for_pagination(get_courses_by_tag(selected_tags)) else @obj = nil end @@ -232,6 +241,7 @@ class TagsController < ApplicationController @forums_results, attachments_results, @contests_results, + @courses_results, @open_source_projects_results] end @@ -279,6 +289,8 @@ class TagsController < ApplicationController return 'Contest' when '8' return 'OpenSourceProject' + when '9' + return 'Course' else render_error :message => e.message return diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 6452bcc81..f78112c21 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -32,12 +32,14 @@ class UsersController < ApplicationController before_filter :require_admin, :except => [:show, :index, :search, :tag_save, :tag_saveEx,:user_projects, :user_newfeedback, :user_comments, :watch_bids, :watch_contests, :info, :user_watchlist, :user_fanslist,:update, :user_courses, :user_homeworks, :watch_projects, :show_score, :topic_score_index, :project_score_index, - :activity_score_index, :influence_score_index, :score_index] + :activity_score_index, :influence_score_index, :score_index,:show_new_score, :topic_new_score_index, :project_new_score_index, + :activity_new_score_index, :influence_new_score_index, :score_new_index,:update_score] #edit has been deleted by huang, 2013-9-23 before_filter :find_user, :only => [:user_fanslist, :user_watchlist, :show, :edit, :update, :destroy, :edit_membership, :user_courses, :user_homeworks, :destroy_membership, :user_activities, :user_projects, :user_newfeedback, :user_comments, :watch_bids, :watch_contests, :info, :watch_projects, :show_score, :topic_score_index, :project_score_index, - :activity_score_index, :influence_score_index, :score_index] + :activity_score_index, :influence_score_index, :score_index,:show_new_score, :topic_new_score_index, :project_new_score_index, + :activity_new_score_index, :influence_new_score_index, :score_new_index] before_filter :auth_user_extension, only: :show accept_api_auth :index, :show, :create, :update, :destroy,:tag_save , :tag_saveEx @@ -92,7 +94,11 @@ class UsersController < ApplicationController # added by bai def show_score - + + end + + def show_new_score + render :layout => false end # end @@ -200,19 +206,19 @@ class UsersController < ApplicationController end end - membership = @user.memberships.all(:conditions => Project.visible_condition(User.current)) + membership = @user.coursememberships.all#@user.coursememberships.all(:conditions => Course.visible_condition(User.current)) membership.sort! {|older, newer| newer.created_on <=> older.created_on } @memberships = [] membership.collect { |e| - @memberships.push(e) if(e.project.project_type == 1) + @memberships.push(e) } ## 判断课程是否过期 [需封装] @memberships_doing = [] @memberships_done = [] now_time = Time.now.year @memberships.map { |e| - end_time = e.project.course_extra.get_time.year - isDone = course_endTime_timeout?(e.project) + end_time = e.course.get_time.year + isDone = course_endTime_timeout?(e.course) if isDone @memberships_done.push e else @@ -669,6 +675,8 @@ class UsersController < ApplicationController @obj = Contest.find_by_id(@obj_id) when '8' @obj = OpenSourceProject.find_by_id(@obj_id) + when '9' + @obj = Course.find_by_id(@obj_id) else @obj = nil end @@ -710,6 +718,8 @@ class UsersController < ApplicationController @obj = Contest.find_by_id(@obj_id) when '8' @obj = OpenSourceProject.find_by_id(@obj_id) + when '9' + @obj = Course.find_by_id(@obj_id) else @obj = nil end @@ -767,7 +777,30 @@ class UsersController < ApplicationController end # end - + def topic_new_score_index + + end + + def project_new_score_index + + end + + def activity_new_score_index + + end + + def influence_new_score_index + + end + + def score_new_index + + end + + def update_score + @user = User.find(params[:id]) + end + private def find_user diff --git a/app/controllers/words_controller.rb b/app/controllers/words_controller.rb index bfc1eacb4..52a7f585a 100644 --- a/app/controllers/words_controller.rb +++ b/app/controllers/words_controller.rb @@ -163,6 +163,20 @@ class WordsController < ApplicationController end end + + # add by nwb + def leave_course_message + user = User.current + message = params[:new_form][:course_message] + feedback = Course.add_new_jour(user, message, params[:id]) + if(feedback.errors.empty?) + redirect_to course_feedback_path(params[:id]), notice: l(:label_feedback_success) + else + flash[:error] = feedback.errors.full_messages[0] + redirect_to course_feedback_path(params[:id]) + end + + end def add_brief_introdution user = User.current @@ -182,10 +196,14 @@ class WordsController < ApplicationController end def obj_distinguish_url_origin + #modify by nwb + #添加对课程留言的支持 referer = request.headers["Referer"] obj_id = referer.match(%r(/([0-9]{1,})(/|$)))[1] if referer.match(/project/) obj = Project.find_by_id(obj_id) + elsif referer.match(/course/) + obj = Course.find_by_id(obj_id) elsif referer.match(/user/) obj = User.find_by_id(obj_id) elsif ( referer.match(/bids/) || referer.match(/calls/) ) @@ -203,11 +221,15 @@ class WordsController < ApplicationController end def add_reply_adapter options + #modify by nwb + #添加对课程留言的支持 obj = obj_distinguish_url_origin if obj.kind_of? User obj.add_jour(nil, nil, nil, options) elsif obj.kind_of? Project Project.add_new_jour(nil, nil, obj.id, options) + elsif obj.kind_of? Course + Course.add_new_jour(nil, nil, obj.id, options) elsif obj.kind_of? Bid obj.add_jour(nil, nil, nil, options) elsif obj.kind_of? Contest diff --git a/app/controllers/zipdown_controller.rb b/app/controllers/zipdown_controller.rb index 808df65dc..33a569f5d 100644 --- a/app/controllers/zipdown_controller.rb +++ b/app/controllers/zipdown_controller.rb @@ -27,7 +27,7 @@ class ZipdownController < ApplicationController else logger.error "[ZipDown#assort] ===> #{obj.class.to_s.to_sym} unKown !!" end - send_file zipfile, :filename => obj.name, :type => detect_content_type(zipfile) if zipfile + send_file zipfile, :filename => obj.name+".zip", :type => detect_content_type(zipfile) if zipfile #rescue NameError, ActiveRecord::RecordNotFound => e #logger.error "[ZipDown] ===> #{e}" @@ -37,9 +37,9 @@ class ZipdownController < ApplicationController #下载某一学生的作业的所有文件 def download_user_homework homework = HomeworkAttach.find params[:homework] - if homework != nil && (User.current.admin? || User.current.member_of?(homework.bid.courses.first)) + if homework != nil && (User.current.admin? || User.current.member_of_course?(homework.bid.courses.first)) zipfile = zip_homework_by_user homework - send_file zipfile, :filename => homework.name, :type => detect_content_type(zipfile) if zipfile + send_file zipfile, :filename => homework.name+".zip", :type => detect_content_type(zipfile) if zipfile else render_403 :message => :notice_not_authorized end @@ -88,7 +88,7 @@ class ZipdownController < ApplicationController #length = attach.storage_path.length homeworks_attach_path << attach.diskfile#.to_s.slice((length+1)..-1) end - zipping "#{homeattach.user.name.to_s}.zip", homeworks_attach_path, OUTPUT_FOLDER, true + zipping "#{homeattach.user.name.to_s}_#{Time.now.to_i}.zip", homeworks_attach_path, OUTPUT_FOLDER, true #user_attaches_paths end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index e62339249..7660c0509 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -39,13 +39,20 @@ module ApplicationHelper # REVIEW: 目测menu的机制,貌似不是很需要转换,再说 def link_class(label) labels = label.is_a?(Array) ? label : ([] << label) + #a = current_menu_item labels.include?(current_menu_item) ? 'selected' : '' + end #Ended by young # Return true if user is authorized for controller/action, otherwise false def authorize_for(controller, action) User.current.allowed_to?({:controller => controller, :action => action}, @project) end + + # add by nwb + def authorize_for_course(controller, action) + User.current.allowed_to?({:controller => controller, :action => action}, @course) + end def authorize_for_contest(controller, action) User.current.allowed_to?({:controller => controller, :action => action}, @contest) @@ -177,6 +184,18 @@ module ApplicationHelper end end + def link_to_course(course, options={}, html_options = nil) + if course.archived? + h(course.name) + elsif options.key?(:action) + ActiveSupport::Deprecation.warn "#link_to_course with :action option is deprecated and will be removed in Redmine 3.0." + url = {:controller => 'courses', :action => 'show', :id => project}.merge(options) + link_to course.name, url, html_options + else + link_to course.name, course_path(course, options), html_options + end + end + # Generates a link to a project settings if active def link_to_project_settings(project, options={}, html_options=nil) if project.active? @@ -303,7 +322,41 @@ module ApplicationHelper @project = original_project end s.html_safe + end + + def render_course_nested_lists(courses) + s = '' + if courses.any? + ancestors = [] + original_course = @course + #modified by nie + courses.each do |course| + # set the project environment to please macros. + @course = course + if (ancestors.empty? )#|| course.is_descendant_of?(ancestors.last)) + s << "\n" + end + end + classes = (ancestors.empty? ? 'root' : 'child') + s << "
  • " + + s << (render :partial => 'courses/course', :locals => {:course => course}).to_s + s << "
    \n" + ancestors << course + end + s << ("
  • \n" * ancestors.size) + @course = original_course + end + s.html_safe end + + #added by young def render_project_nested_lists_new(projects) s = '' @@ -1645,9 +1698,9 @@ module ApplicationHelper main_project_link = link_to l(:label_project_deposit), {:controller => 'welcome', :action => 'index', :host => Setting.project_domain} main_contest_link = link_to l(:label_contest_innovate), {:controller => 'welcome', :action => 'index', :host => Setting.contest_domain} - course_all_course_link = link_to l(:label_course_all), {:controller => 'projects', :action => 'course', :project_type => 1, :host => Setting.course_domain} + course_all_course_link = link_to l(:label_course_all), {:controller => 'courses', :action => 'index'} course_teacher_all_link = link_to l(:label_teacher_all), {:controller => 'users', :action => 'index', :role => 'teacher', :host => Setting.course_domain} - courses_link = link_to l(:label_course_practice), {:controller => 'projects', :action => 'course', :project_type => 1, :host => Setting.course_domain} + courses_link = link_to l(:label_course_practice), {:controller => 'courses', :action => 'index'} projects_link = link_to l(:label_project_deposit), {:controller => 'projects', :action => 'index', :project_type => 0, :host => Setting.project_domain} users_link = link_to l(:label_software_user), {:controller => 'users', :action => 'index', :host => Setting.user_domain} contest_link = link_to l(:label_contest_innovate), {:controller => 'contests', :action => 'index'} diff --git a/app/helpers/avatar_helper.rb b/app/helpers/avatar_helper.rb index abaa79504..2ebdae0c8 100644 --- a/app/helpers/avatar_helper.rb +++ b/app/helpers/avatar_helper.rb @@ -42,7 +42,7 @@ module AvatarHelper end def get_avatar?(source) - if File.exist?(disk_filename(source.class,source.id)) + if source && File.exist?(disk_filename(source.class,source.id)) return true else return false diff --git a/app/helpers/boards_helper.rb b/app/helpers/boards_helper.rb index 84b979c44..341de8932 100644 --- a/app/helpers/boards_helper.rb +++ b/app/helpers/boards_helper.rb @@ -29,6 +29,19 @@ module BoardsHelper breadcrumb links end + # add by nwb + def course_board_breadcrumb(item) + board = item.is_a?(Message) ? item.board : item + links = [link_to(l(:label_board_plural), course_boards_path(item.course))] + boards = board.ancestors.reverse + if item.is_a?(Message) + boards << board + end + links += boards.map {|ancestor| link_to(h(ancestor.name), course_board_path(ancestor.course, ancestor))} + breadcrumb links + end + + def boards_options_for_select(boards) options = [] Board.board_tree(boards) do |board, level| diff --git a/app/helpers/contests_helper.rb b/app/helpers/contests_helper.rb index 8206a8ff0..184fc7c40 100644 --- a/app/helpers/contests_helper.rb +++ b/app/helpers/contests_helper.rb @@ -55,8 +55,9 @@ module ContestsHelper content_tag('div', content, :class => "tabs_enterprise") end #end - - + + + #huang def sort_contest(state) content = ''.html_safe diff --git a/app/helpers/courses_helper.rb b/app/helpers/courses_helper.rb index 0602e52d2..b1ec023c8 100644 --- a/app/helpers/courses_helper.rb +++ b/app/helpers/courses_helper.rb @@ -31,6 +31,39 @@ module CoursesHelper # searchStudent(project).count end + # 判断用户是否是课程的管理员 + # add by nwb + def is_course_manager?(user_id,course_id) + @result = false + @user_id = CourseInfo.find_by_course_id(course_id) + if @user_id == user.id + @result = true + end + return @result + end + + # 返回课程设置界面 + def course_settings_tabs + tabs = [{:name => 'info', :action => :edit_course, :partial => 'courses/edit', :label => :label_information_plural}, + {:name => 'members', :action => :manage_members, :partial => 'courses/settings/members', :label => :label_member_plural} + ] + tabs.select { |tab| User.current.allowed_to?(tab[:action], @course) } + + end + + #是否启动互评下拉框 + def is_evaluation_option + type = [] + option1 = [] + option2 = [] + option1 << l(:lable_start_mutual_evaluation) + option1 << 1 + option2 << l(:lable_close_mutual_evaluation) + option2 << 2 + type << option1 + type << option2 + end + # garble count 混淆数量 # alias projectCountOrigin projectCount # def projectCount project @@ -38,6 +71,19 @@ module CoursesHelper # garble count # end + def homework_type_option + type = [] + option1 = [] + option2 = [] + option1 << l(:label_task_submit_form_accessory) + option1 << 1 + option2 << l(:label_task_submit_form_project) + option2 << 2 + type << option1 + type << option2 + end + + alias teacherCountOrigin teacherCount def teacherCount project count = teacherCountOrigin project @@ -45,11 +91,26 @@ module CoursesHelper end alias studentCountOrigin studentCount - def studentCount project - count = studentCountOrigin project + def studentCount course + count = studentCountOrigin course garble count end + def eventToLanguageCourse event_type, course + case event_type + when "issue-note" + l :label_issue + when "issue" + l :label_issue + when "attachment" + l :label_attachment + when "news" + l :label_notification + else + "" + end + end + def garble count count = count.round( 1-count.to_s.size ).to_i return count.to_s if count.to_s.size.eql?(1) @@ -82,6 +143,35 @@ module CoursesHelper members end + def sort_courses(state) + content = ''.html_safe + case state + when 0 + + content << content_tag('li', link_to(l(:label_sort_by_active), courses_path(:courses_sort_type => '1'))) + content << content_tag('li', link_to(l(:label_sort_by_influence), courses_path(:courses_sort_type => '2'))) + content << content_tag('li', link_to(l(:label_sort_by_time), courses_path(:courses_sort_type => '0'), :class=>"selected"), :class=>"selected") + when 1 + + content << content_tag('li', link_to(l(:label_sort_by_active), courses_path(:courses_sort_type => '1'), :class=>"selected"), :class=>"selected") + content << content_tag('li', link_to(l(:label_sort_by_influence), courses_path(:courses_sort_type => '2'))) + content << content_tag('li', link_to(l(:label_sort_by_time), courses_path(:courses_sort_type => '0'))) + when 2 + content << content_tag('li', link_to(l(:label_sort_by_active), courses_path(:courses_sort_type => '1'))) + content << content_tag('li', link_to(l(:label_sort_by_influence), courses_path(:courses_sort_type => '2'), :class=>"selected"), :class=>"selected") + content << content_tag('li', link_to(l(:label_sort_by_time), courses_path(:courses_sort_type => '0'))) + end + content = content_tag('ul', content) + content_tag('div', content, :class => "tabs") + end + + def render_course_hierarchy(courses) + render_course_nested_lists(courses) do |course| + s = link_to_course(course, {}, :class => "#{course.css_classes} #{User.current.member_of?(course) ? 'my-course' : nil}").html_safe + s + end + end + #useless def searchMembersByRole project, role_id members = [] @@ -93,6 +183,36 @@ module CoursesHelper members end + def sort_course(state, school_id) + content = ''.html_safe + case state + when 0 + content << content_tag('li', link_to(l(:label_sort_by_time), courses_path(:course_sort_type => '0'), :school_id => school_id, :class=>"selected"), :class=>"selected") + content << content_tag('li', link_to(l(:label_sort_by_active), courses_path(:course_sort_type => '1', :school_id => school_id))) + content << content_tag('li', link_to(l(:label_sort_by_activity), courses_path(:course_sort_type => '3', :school_id => school_id))) + + when 1 + content << content_tag('li', link_to(l(:label_sort_by_time), courses_path(:course_sort_type => '0', :school_id => school_id))) + content << content_tag('li', link_to(l(:label_sort_by_active), courses_path(:course_sort_type => '1', :school_id => school_id), :class=>"selected"), :class=>"selected") + content << content_tag('li', link_to(l(:label_sort_by_activity), courses_path(:course_sort_type => '3', :school_id => school_id))) + + when 2 + content << content_tag('li', link_to(l(:label_sort_by_time), courses_path(:course_sort_type => '0', :school_id => school_id))) + content << content_tag('li', link_to(l(:label_sort_by_active), courses_path(:course_sort_type => '1', :school_id => school_id))) + content << content_tag('li', link_to(l(:label_sort_by_activity), courses_path(:course_sort_type => '3', :school_id => school_id))) + + #gcm + when 3 + content << content_tag('li', link_to(l(:label_sort_by_time), courses_path(:course_sort_type => '0', :school_id => school_id))) + content << content_tag('li', link_to(l(:label_sort_by_active), courses_path(:course_sort_type => '1', :school_id => school_id))) + content << content_tag('li', link_to(l(:label_sort_by_activity), courses_path(:course_sort_type => '3', :school_id => school_id), :class=>"selected"), :class=>"selected") + end + #gcmend + + content = content_tag('ul', content) + content_tag('div', content, :class => "tabs") + end + def findCourseTime project str = "" begin @@ -109,8 +229,9 @@ module CoursesHelper str end - def get_course_term project - str = ( project.try(:course_extra).try(:time).to_s << '.' << project.try(:course_extra).try(:term).to_s ) + # added by nwb + def get_course_term course + str = ( course.try(:time).to_s << '.' << course.try(:term).to_s ) str[0..-4] end @@ -123,7 +244,7 @@ module CoursesHelper end # 截至到2014-03-17 这个是最终的判断课程是否过期的方法 def course_endTime_timeout? project - end_time_str = Course.find_by_extra(project.try(:identifier)).try(:endup_time) + end_time_str = Course.find_by_extra(project.try(:extra)).try(:endup_time) begin cTime = Time.parse(end_time_str.to_s) rescue TypeError,ArgumentError @@ -182,4 +303,71 @@ module CoursesHelper def users_for_homework homework homework.nil? ? [] : (homework.users + [homework.user]) end + + #获取指定作业的最终评分 + #最终评分 = 学生评分的平均分 * 0.4 +教师评分 * 0.6 + def score_for_homework homework + if homework.bid.is_evaluation == 1 || homework.bid.is_evaluation == nil + return format("%.2f",(teacher_score_for_homework(homework).to_f * 0.6 + student_score_for_homework(homework).to_f * 0.4)) + else + return teacher_score_for_homework homework + end + end + + #获取作业的互评得分 + def student_score_for_homework homework + member = searchPeopleByRoles(homework.bid.courses.first,TeacherRoles).first + student_stars = homework.rates(:quality).where("rater_id <> #{member.user_id}").select("stars") + student_stars_count = 0 + student_stars.each do |star| + student_stars_count = student_stars_count + star.stars + end + return format("%.2f",student_stars_count / (student_stars.count == 0 ? 1 : student_stars.count)) + end + + #获取作业的教师评分 + def teacher_score_for_homework homework + member = searchPeopleByRoles(homework.bid.courses.first,TeacherRoles).first + teacher_stars = homework.rates(:quality).where("rater_id = #{member.user_id}").select("stars").first + return format("%.2f",teacher_stars == nil ? 0 : teacher_stars.stars) + end + + #获取指定作业的得分 + def project_score project + issue_count = project.issues.count + issue_journal_count = project.issue_changes.count + issue_score = issue_count * 0.2 + issue_journal_score = issue_journal_count * 0.1 + finall_issue_score = issue_score + issue_journal_score + new_count = project.news.count + new_score = new_count * 0.1 + finall_new_score = new_score + document_count = project.documents.count + file_score = document_count * 0.1 + finall_file_score = file_score + changeset_count = project.changesets.count + code_submit_score = changeset_count * 0.3 + finall_code_submit_score = code_submit_score + board_message_count = 0 + project.boards.each do |board| + board_message_count += board.messages_count + end + topic_score = board_message_count * 0.1 + #finall_topic_score = topic_score + finall_project_score = finall_issue_score + finall_new_score + finall_file_score + finall_code_submit_score + topic_score + format("%.2f",finall_project_score) + end + + #获取指定作业的参与人员 + #返回结果:张三、李四、王五 + def homework_user_of_homework homework,is_teacher + homework_users = "" + homework.users.each do |user| + homework_users = homework_users + (is_teacher ? user.realname : user.name) + if user != homework.users.last + homework_users = homework_users + "、" + end + end + return homework_users + end end diff --git a/app/helpers/homework_attach_helper.rb b/app/helpers/homework_attach_helper.rb index 28bb48d3c..3510dc783 100644 --- a/app/helpers/homework_attach_helper.rb +++ b/app/helpers/homework_attach_helper.rb @@ -54,4 +54,24 @@ module HomeworkAttachHelper raise RuntimeError, 'unknow type, Please input you type into this helper.' end end + + def user_projects_option + cond = Project.visible_condition(User.current) + " AND projects.project_type <> 1" + memberships = User.current.memberships.all(:conditions => cond) + projects = memberships.map(&:project) + not_have_project = [] + not_have_project << "<>" + not_have_project << 0 + type = [] + type << not_have_project + projects.each do |project| + if project != nil + option = [] + option << project.name + option << project.id + type << option + end + end + type + end end \ No newline at end of file diff --git a/app/helpers/journals_helper.rb b/app/helpers/journals_helper.rb index 26b4c13b9..cfebb4d30 100644 --- a/app/helpers/journals_helper.rb +++ b/app/helpers/journals_helper.rb @@ -70,7 +70,7 @@ module JournalsHelper content << textilizable(journal, :notes) css_classes = "wiki" css_classes << " editable" if editable - content_tag('div', content.html_safe, :id => "journal-#{journal.id}-notes", :class => css_classes) + content_tag('div', content.html_safe, :id => "journal-#{journal.id}-notes", :class => css_classes ,:style => "width:580px") end def link_to_in_place_notes_editor(text, field_id, url, options={}) diff --git a/app/helpers/members_helper.rb b/app/helpers/members_helper.rb index 797483868..134b7c007 100644 --- a/app/helpers/members_helper.rb +++ b/app/helpers/members_helper.rb @@ -33,6 +33,24 @@ module MembersHelper s + content_tag('div', content_tag('ul', links), :class => 'pagination_new') end + # add by nwb + # 课程可添加的成员列表 + def render_principals_for_new_course_members(course) + scope = Principal.active.sorted.not_member_of_course(course).like(params[:q]) + principal_count = scope.count + principal_pages = Redmine::Pagination::Paginator.new principal_count, 10, params['page'] + principals = scope.offset(principal_pages.offset).limit(principal_pages.per_page).all + + s = content_tag('div', principals_check_box_tags_ex('membership[user_ids][]', principals), :id => 'principals') + + links = pagination_links_full(principal_pages, principal_count, :per_page_links => false) {|text, parameters, options| + link_to text, autocomplete_course_memberships_path(course, parameters.merge(:q => params[:q], :format => 'js')), :remote => true + } + + s + content_tag('div', content_tag('ul', links), :class => 'pagination_new') + end + + # 当前申请加入的成员名单 def render_principals_for_applied_members(project) scope = Principal.active.sorted.applied_members(project).like(params[:q]) diff --git a/app/helpers/tags_helper.rb b/app/helpers/tags_helper.rb index 201a582f2..8e9e6bbb9 100644 --- a/app/helpers/tags_helper.rb +++ b/app/helpers/tags_helper.rb @@ -16,6 +16,8 @@ module TagsHelper @obj = Attachment.find_by_id(obj_id) when '7' @obj= Contest.find_by_id(obj_id) + when '9' + @obj= Course.find_by_id(obj_id) else raise Exception, '[TagsHelper] ===> tag type unknow.' end @@ -46,6 +48,8 @@ module TagsHelper if user.id == obj_id @result = true end + when '9' + @result = is_course_manager?(user.id,obj_id) end return @result end diff --git a/app/helpers/watchers_helper.rb b/app/helpers/watchers_helper.rb index 50170ee9e..00867d9f8 100644 --- a/app/helpers/watchers_helper.rb +++ b/app/helpers/watchers_helper.rb @@ -71,7 +71,10 @@ module WatchersHelper # Somebody may use option params def join_in_course(course, user, options=[]) return '' unless user && user.logged? - joined = user.member_of?(course) + # modify by nwb + # 主讲教师不允许退出课程 + return '' if user.id == course.tea_id + joined = user.member_of_course?(course) text = joined ? l(:label_exit_course) : l(:label_join_course) url_t = join_path(:object_id => course.id) url_f = try_join_path(:object_id => course.id) @@ -82,10 +85,15 @@ module WatchersHelper link_to text, url_f, :remote => true, :method => method, :id => "#{course.id}", :class => []+options end end - + + # 用户是否允许加入课程判断 + # add by nwb def join_in_course_for_list(course, user, options=[]) return '' unless user && user.logged? - joined = user.member_of?(course) + # modify by nwb + # 主讲教师不允许退出课程 + return '' if user.id == course.tea_id + joined = user.member_of_course?(course) text = joined ? l(:label_exit_course) : l(:label_join_course) url_t = join_path(:object_id => course.id) url_f = try_join_path(:object_id => course.id) diff --git a/app/helpers/welcome_helper.rb b/app/helpers/welcome_helper.rb index d35fd8275..35fd6ee08 100644 --- a/app/helpers/welcome_helper.rb +++ b/app/helpers/welcome_helper.rb @@ -22,6 +22,33 @@ module WelcomeHelper include CoursesHelper include ProjectsHelper + def get_timestamp(obj) + if obj.respond_to? :updated_on + :updated_on + elsif obj.respond_to? :updated_at + :updated_at + elsif obj.respond_to? :created_on + :created_on + elsif obj.respond_to? :created_at + :created_at + else + Time.now.to_i.to_s.to_sym + end + end + + def cache_key_for_project(obj) + timestamp = get_timestamp(obj) + "welcome_index_project_ul_#{obj.class}_li_#{obj.id}_#{obj.__send__ timestamp}" + end + def cache_key_for_event(obj) + timestamp = get_timestamp(obj) + "welcome_index_event_ul_#{obj.class}_li_#{obj.id}_#{obj.__send__ timestamp}" + end + def cache_key_for_topic(obj) + timestamp = get_timestamp(obj) + "welcome_index_topic_ul_#{obj.class}_li_#{obj.id}_#{obj.__send__ timestamp}" + end + def welcome_join_in_course(project, user) if(user.logged? && !(course_endTime_timeout? project) && @@ -131,10 +158,11 @@ module WelcomeHelper end def find_miracle_project(sum, max_rate) - max = sum*(max_rate.to_f/10) - c1 = find_new_project(sum).to_a.dup - c2 = find_all_hot_project(sum).to_a.dup - (c2.take(sum-max)+c1.take(max)).take(sum) + #max = sum*(max_rate.to_f/10) + #c1 = find_new_project(sum).to_a.dup + #c2 = find_all_hot_project(sum).to_a.dup + #(c2.take(sum-max)+c1.take(max)).take(sum) + find_all_hot_project(sum).to_a.dup end def find_new_course limit=15 @@ -305,7 +333,7 @@ module WelcomeHelper end #取得所有活动 - def find_all_activities limit=6 + def find_all_activities limit=6 # users = [] # activities = Activity.find_by_sql("select distinct user_id from activities order by id DESC limit #{limit}" ) # activities.each { |activity| diff --git a/app/models/attachment.rb b/app/models/attachment.rb index b2a7cfb08..94f8f7c95 100644 --- a/app/models/attachment.rb +++ b/app/models/attachment.rb @@ -21,6 +21,7 @@ require "fileutils" class Attachment < ActiveRecord::Base belongs_to :container, :polymorphic => true belongs_to :project, foreign_key: 'container_id', conditions: "attachments.container_type = 'Project'" + belongs_to :course, foreign_key: 'container_id', conditions: "attachments.container_type = 'Course'" belongs_to :softapplication, foreign_key: 'container_id', conditions: "attachments.container_type = 'Softapplication'" belongs_to :author, :class_name => "User", :foreign_key => "author_id" belongs_to :attachmentstype, :foreign_key => "attachtype",:primary_key => "id" @@ -30,12 +31,20 @@ class Attachment < ActiveRecord::Base validates_length_of :disk_filename, :maximum => 255 validates_length_of :description, :maximum => 255 validate :validate_max_file_size - acts_as_taggable + + acts_as_taggable acts_as_event :title => :filename, :url => Proc.new {|o| {:controller => 'attachments', :action => 'download', :id => o.id, :filename => o.filename}} - acts_as_activity_provider :type => 'files', + #课程资源文件 + acts_as_activity_provider :type => 'course_files', + :permission => :view_files, + :author_key => :author_id, + :find_options => {:select => "#{Attachment.table_name}.*", + :joins => "LEFT JOIN #{Course.table_name} ON ( #{Attachment.table_name}.container_type='Course' AND #{Attachment.table_name}.container_id = #{Course.table_name}.id )"} + + acts_as_activity_provider :type => 'files', :permission => :view_files, :author_key => :author_id, :find_options => {:select => "#{Attachment.table_name}.*", @@ -120,7 +129,7 @@ class Attachment < ActiveRecord::Base nil end - def filename=(arg) + def filename=(arg) write_attribute :filename, sanitize_filename(arg.to_s) filename end @@ -186,6 +195,10 @@ class Attachment < ActiveRecord::Base container.try(:project) end + def course + container + end + def visible?(user=User.current) if container_id container && container.attachments_visible?(user) @@ -370,7 +383,7 @@ class Attachment < ActiveRecord::Base type = self.container_type types = %w|Document News Version Project Issue Message WikiPage| if types.include?(type) - UserScore.project(:push_file, User.current, { attachment_id: self.id }) + UserScore.project(:push_file, User.current,self, { attachment_id: self.id }) end end end diff --git a/app/models/bid.rb b/app/models/bid.rb index e58e640a0..f65d71fa8 100644 --- a/app/models/bid.rb +++ b/app/models/bid.rb @@ -22,11 +22,11 @@ class Bid < ActiveRecord::Base belongs_to :course has_many :biding_projects, :dependent => :destroy has_many :projects, :through => :biding_projects - has_many :projects_member, :class_name => 'User', :through => :projects + has_many :courses_member, :class_name => 'User', :through => :courses has_many :journals_for_messages, :as => :jour, :dependent => :destroy has_many :acts, :class_name => 'Activity', :as => :act, :dependent => :destroy has_many :homework_for_courses, :dependent => :destroy - has_many :courses, :through => :homework_for_courses, :source => :project + has_many :courses, :through => :homework_for_courses, :source => :course has_many :homeworks, :class_name => 'HomeworkAttach', :dependent => :destroy has_many :join_in_contests, :dependent => :destroy has_many :praise_tread, as: :praise_tread_object, dependent: :destroy diff --git a/app/models/board.rb b/app/models/board.rb index cb81e0a5a..b51790e19 100644 --- a/app/models/board.rb +++ b/app/models/board.rb @@ -18,6 +18,7 @@ class Board < ActiveRecord::Base include Redmine::SafeAttributes belongs_to :project + belongs_to :course has_many :topics, :class_name => 'Message', :conditions => "#{Message.table_name}.parent_id IS NULL", :order => "#{Message.table_name}.created_on DESC" has_many :messages, :dependent => :destroy, :order => "#{Message.table_name}.created_on DESC" belongs_to :last_message, :class_name => 'Message', :foreign_key => :last_message_id diff --git a/app/models/changeset.rb b/app/models/changeset.rb index 93248850b..a56dee691 100644 --- a/app/models/changeset.rb +++ b/app/models/changeset.rb @@ -19,7 +19,7 @@ class Changeset < ActiveRecord::Base belongs_to :repository belongs_to :user - after_save :be_user_score # user_score + #after_save :be_user_score # user_score has_many :filechanges, :class_name => 'Change', :dependent => :delete_all # fq @@ -63,7 +63,7 @@ class Changeset < ActiveRecord::Base includes(:repository => :project).where(Project.allowed_to_condition(args.shift || User.current, :view_changesets, *args)) } - after_create :scan_for_issues + after_create :scan_for_issues,:be_user_score # user_score before_create :before_create_cs # fq @@ -98,7 +98,9 @@ class Changeset < ActiveRecord::Base end def project - repository.project + unless repository.nil? + repository.project + end end def author @@ -300,9 +302,9 @@ class Changeset < ActiveRecord::Base # update user score def be_user_score - if self.new_record? - UserScore.project(:push_code, self.user, { changeset_id: self.id }) - end + UserScore.project(:push_code, self.user,self, { changeset_id: self.id }) + #更新用户等级 + UserLevels.update_user_level(self.user) end end diff --git a/app/models/course.rb b/app/models/course.rb index de383a1f5..51b118679 100644 --- a/app/models/course.rb +++ b/app/models/course.rb @@ -1,13 +1,45 @@ class Course < ActiveRecord::Base include Redmine::SafeAttributes + + STATUS_ACTIVE = 1 + STATUS_CLOSED = 5 + STATUS_ARCHIVED = 9 - attr_accessible :code, :extra, :name, :state, :tea_id, :time , :location, :state, :term, :password - belongs_to :project, :class_name => 'Project', :foreign_key => :extra, primary_key: :identifier + attr_accessible :code, :extra, :name, :state, :tea_id, :time , :location, :state, :term, :password,:is_public,:description,:class_period + belongs_to :project, :class_name => 'Course', :foreign_key => :extra, primary_key: :identifier belongs_to :teacher, :class_name => 'User', :foreign_key => :tea_id # 定义一个方法teacher,该方法通过tea_id来调用User表 belongs_to :school, :class_name => 'School', :foreign_key => :school_id #定义一个方法school,该方法通过school_id来调用School表 has_many :bid - validates_presence_of :password, :term - validates_format_of :class_period, :message => "class period can only digital!", :with =>/^[1-9]\d*$/ + + has_many :members, :include => [:principal, :roles], :conditions => "#{Principal.table_name}.type='User' AND #{Principal.table_name}.status=#{Principal::STATUS_ACTIVE}" + has_many :memberships, :class_name => 'Member' + has_many :member_principals, :class_name => 'Member', + :include => :principal, + :conditions => "#{Principal.table_name}.type='Group' OR (#{Principal.table_name}.type='User' AND #{Principal.table_name}.status=#{Principal::STATUS_ACTIVE})" + has_many :principals, :through => :member_principals, :source => :principal + has_many :users, :through => :members + has_many :homeworks, :through => :homework_for_courses, :source => :bid, :dependent => :destroy + has_many :journals_for_messages, :as => :jour, :dependent => :destroy + has_many :homework_for_courses, :dependent => :destroy + has_many :student, :through => :students_for_courses, :source => :user + has_many :course_infos, :class_name => 'CourseInfos',:dependent => :destroy + has_many :enabled_modules, :dependent => :delete_all + has_many :boards, :dependent => :destroy, :order => "position ASC" + #has_many :course_journals_for_messages, :class_name => 'CourseJournalsForMessage', :as => :jour, :dependent => :destroy + has_many :news, :dependent => :destroy, :include => :author + + acts_as_taggable + acts_as_nested_set :order => 'name', :dependent => :destroy + acts_as_attachable :view_permission => :view_files, + :delete_permission => :manage_files + + validates_presence_of :password, :term,:name + validates_format_of :class_period, :with =>/^[1-9]\d*$/ + validates_format_of :name,:with =>/^[a-zA-Z0-9_\u4e00-\u9fa5]+$/ + + after_save :create_board_sync + before_destroy :delete_all_members + safe_attributes 'extra', 'time', 'name', @@ -17,15 +49,164 @@ class Course < ActiveRecord::Base 'tea_id', 'password', 'term', - 'password' + 'is_public', + 'description', + 'class_period' - #自定义验证 + acts_as_customizable + + scope :all_course + scope :active, lambda { where(:status => STATUS_ACTIVE) } + scope :status, lambda {|arg| where(arg.blank? ? nil : {:status => arg.to_i}) } + scope :all_public, lambda { where(:is_public => true) } + scope :visible, lambda {|*args| where(Course.visible_condition(args.shift || User.current, *args)) } + scope :allowed_to, lambda {|*args| + user = User.current + permission = nil + if args.first.is_a?(Symbol) + permission = args.shift + else + user = args.shift + permission = args.shift + end + where(Course.allowed_to_condition(user, permission, *args)) + } + scope :like, lambda {|arg| + if arg.blank? + where(nil) + else + pattern = "%#{arg.to_s.strip.downcase}%" + where("LOWER(extra) LIKE :p OR LOWER(name) LIKE :p ", :p => pattern) + end + } + + def visible?(user=User.current) + user.allowed_to?(:view_course, self) + end + + def parent_id_changed? + false + end + + # 课程的短描述信息 + def short_description(length = 255) + description.gsub(/^(.{#{length}}[^\n\r]*).*$/m, '\1...').strip if description + end + + def extra_frozen? + errors[:extra].blank? && !(new_record? || extra.blank?) + end + + def archived? + self.status == STATUS_ARCHIVED + end + + def self.visible_condition(user, options={}) + allowed_to_condition(user, :view_course, options) + end + + # 获取课程的资源类型列表 + def attachmenttypes + @attachmenttypes = Attachmentstype.find(:all, :conditions => ["#{Attachmentstype.table_name}.typeId= ?",self.attachmenttype ]) + end + + # 获取资源后缀名列表 + def contenttypes + attachmenttypes + if @attachmenttypes.length >0 + @attachmenttypes.last().suffixArr + end + end + + def active? + self.status == STATUS_ACTIVE + end + + #课程权限判断 + def allows_to?(action) + if archived? + # No action allowed on archived projects + return false + end + unless active? || Redmine::AccessControl.read_action?(action) + # No write action allowed on closed projects + return false + end + # No action allowed on disabled modules + if action.is_a? Hash + allowed_actions.include? "#{action[:controller]}/#{action[:action]}" + else + allowed_permissions.include? action + end + end + + # 课程允许的权限集合 + def allowed_permissions + @allowed_permissions ||= begin + module_names = enabled_modules.all(:select => :name).collect {|m| m.name} + Redmine::AccessControl.modules_permissions(module_names).collect {|p| p.name} + end + end + + # 课程允许的动作集合 + def allowed_actions + @actions_allowed ||= allowed_permissions.inject([]) { |actions, permission| actions += Redmine::AccessControl.allowed_actions(permission) }.flatten + end + + # 返回用户组可以访问的课程 + def users_by_role + members.includes(:user, :roles).all.inject({}) do |h, m| + m.roles.each do |r| + h[r] ||= [] + h[r] << m.user + end + h + end + end + + #自定义验证 def validate if !class_period.match([0-9]) errors.add_to_base("class period can only digital") end end + # 创建课程讨论区 + def create_board_sync + @board = self.boards.build + self.name=" #{l(:label_borad_course) }" + @board.name = self.name + @board.description = self.name.to_s + @board.project_id = -1 + if @board.save + logger.debug "[Course Model] ===> #{@board.to_json}" + else + logger.error "[Course Model] ===> Auto create board when course saved, because #{@board.full_messages}" + end + end + + # 新增课程留言 + # add by nwb + def self.add_new_jour(user, notes, id, options={}) + course = Course.find(id) + if options.count == 0 + pjfm = course.journals_for_messages.build(:user_id => user.id, :notes => notes, :reply_id => 0) + else + pjfm = course.journals_for_messages.build(options) + end + pjfm.save + pjfm + end + + # 删除课程所有成员 + def delete_all_members + if self.members && self.members.count > 0 + me, mr = Member.table_name, MemberRole.table_name + connection.delete("DELETE FROM #{mr} WHERE #{mr}.member_id IN (SELECT #{me}.id FROM #{me} WHERE #{me}.course_id = #{id})") + Member.delete_all(['course_id = ?', id]) + end + end + def get_endup_time begin end_time = Time.parse(self.endup_time) @@ -47,4 +228,50 @@ class Course < ActiveRecord::Base return time end end + + def self.allowed_to_condition(user, permission, options={}) + perm = Redmine::AccessControl.permission(permission) + base_statement = (perm && perm.read? ? "#{Course.table_name}.status <> #{Course::STATUS_ARCHIVED}" : "#{Course.table_name}.status = #{Course::STATUS_ACTIVE}") + if perm && perm.course_module + base_statement << " AND #{Course.table_name}.id IN (SELECT em.course_id FROM #{EnabledModule.table_name} em WHERE em.name='#{perm.course_module}')" + end + + if options[:course] + course_statement = "#{Course.table_name}.id = #{options[:course].id}" + course_statement << " OR (#{Course.table_name}.lft > #{options[:course].lft} AND #{Course.table_name}.rgt < #{options[:course].rgt})" if options[:with_subcourses] + base_statement = "(#{course_statement}) AND (#{base_statement})" + end + + if user.admin? + base_statement + else + statement_by_role = {} + unless options[:member] + role = user.logged? ? Role.non_member : Role.anonymous + if role.allowed_to?(permission) + statement_by_role[role] = "#{Course.table_name}.is_public = #{connection.quoted_true}" + end + end + if user.logged? + user.courses_by_role.each do |role, courses| + if role.allowed_to?(permission) && courses.any? + statement_by_role[role] = "#{Course.table_name}.id IN (#{courses.collect(&:id).join(',')})" + end + end + end + if statement_by_role.empty? + "1=0" + else + if block_given? + statement_by_role.each do |role, statement| + if s = yield(role, user) + statement_by_role[role] = "(#{statement} AND (#{s}))" + end + end + end + "((#{base_statement}) AND (#{statement_by_role.values.join(' OR ')}))" + end + end + end + end diff --git a/app/models/course_infos.rb b/app/models/course_infos.rb new file mode 100644 index 000000000..6478b383a --- /dev/null +++ b/app/models/course_infos.rb @@ -0,0 +1,5 @@ +class CourseInfos < ActiveRecord::Base + attr_accessible :user_id, :course_id + belongs_to :user + belongs_to :course +end diff --git a/app/models/course_status.rb b/app/models/course_status.rb new file mode 100644 index 000000000..d5a01ac4b --- /dev/null +++ b/app/models/course_status.rb @@ -0,0 +1,3 @@ +class CourseStatus < ActiveRecord::Base + attr_accessible :changesets_count, :course_ac_para, :course_id, :grade, :watchers_count +end diff --git a/app/models/document.rb b/app/models/document.rb index 3710e6ebc..7c2730682 100644 --- a/app/models/document.rb +++ b/app/models/document.rb @@ -21,7 +21,7 @@ class Document < ActiveRecord::Base belongs_to :user belongs_to :category, :class_name => "DocumentCategory", :foreign_key => "category_id" - before_save :be_user_score # user_score + after_create :be_user_score # user_score acts_as_attachable :delete_permission => :delete_documents @@ -62,8 +62,6 @@ class Document < ActiveRecord::Base # update user score def be_user_score - if self.new_record? - UserScore.project(:push_document, self.user, { document_id: self.id }) - end + UserScore.project(:push_document, self.user,self,{ document_id: self.id }) end end diff --git a/app/models/homework_attach.rb b/app/models/homework_attach.rb index e60d4230b..99d540bd1 100644 --- a/app/models/homework_attach.rb +++ b/app/models/homework_attach.rb @@ -9,6 +9,7 @@ class HomeworkAttach < ActiveRecord::Base has_many :homework_users, :dependent => :destroy has_many :users, :through => :homework_users seems_rateable :allow_update => true, :dimensions => :quality + belongs_to :project safe_attributes "bid_id", "user_id" @@ -30,7 +31,7 @@ class HomeworkAttach < ActiveRecord::Base result end - def project + def project_for_homework work = HomeworkForCourse.find_by_bid_id(self.bid_id) if work work.project diff --git a/app/models/homework_for_course.rb b/app/models/homework_for_course.rb index 7a440449a..59fd7ba1e 100644 --- a/app/models/homework_for_course.rb +++ b/app/models/homework_for_course.rb @@ -1,8 +1,8 @@ class HomeworkForCourse < ActiveRecord::Base - attr_accessible :bid_id, :project_id + attr_accessible :bid_id, :course_id belongs_to :bid - belongs_to :project + belongs_to :course end diff --git a/app/models/issue.rb b/app/models/issue.rb index 6cfa9b7e5..3cd67d017 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -76,8 +76,8 @@ class Issue < ActiveRecord::Base attr_reader :current_journal # fq - after_create :act_as_activity - before_save :be_user_score + after_create :act_as_activity,:be_user_score_new_issue + after_update :be_user_score # after_create :be_user_score # end @@ -1489,14 +1489,19 @@ class Issue < ActiveRecord::Base # update user score def be_user_score - if self.new_record? - UserScore.project(:post_issue, User.current, { issue_id: self.id }) - elsif self.done_ratio_changed? - UserScore.project(:update_issue_ratio, User.current, { issue_id: self.id }) + #缺陷完成度更新 + if self.done_ratio_changed? + UserScore.project(:update_issue_ratio, User.current,self,{ issue_id: self.id }) + end #缺陷状态更改 - elsif self.status_id_changed? - #协同得分 - UserScore.joint(:change_issue_status, User.current,nil, {issue_id: self.id}) + if self.status_id_changed? + #协同得分 + UserScore.joint(:change_issue_status, User.current,nil,self, {issue_id: self.id}) end end + + #发布缺陷 + def be_user_score_new_issue + UserScore.project(:post_issue, User.current,self, { issue_id: self.id }) + end end diff --git a/app/models/journal.rb b/app/models/journal.rb index c82db5a1f..8027f18a5 100644 --- a/app/models/journal.rb +++ b/app/models/journal.rb @@ -45,10 +45,10 @@ class Journal < ActiveRecord::Base before_create :split_private_notes # fq - after_create :act_as_activity + after_create :act_as_activity,:be_user_score # end - before_save :be_user_score + #before_save :be_user_score #before_destroy :down_user_score scope :visible, lambda {|*args| @@ -158,9 +158,9 @@ class Journal < ActiveRecord::Base # 更新用户分数 -by zjc def be_user_score #新建了缺陷留言且留言不为空,不为空白 - if self.new_record? && !self.notes.nil? && self.notes.gsub(' ','') != '' + if !self.notes.nil? && self.notes.gsub(' ','') != '' #协同得分加分 - UserScore.joint(:post_issue, User.current,self.issue.author, { message_id: self.id }) + UserScore.joint(:post_issue_message, User.current,self.issue.author,self, { message_id: self.id }) end end # 减少用户分数 -by zjc @@ -168,7 +168,7 @@ class Journal < ActiveRecord::Base #删除有效缺陷留言 if !self.notes.nil? && self.notes.gsub(' ','') != '' #协同得分减分 - UserScore.joint(:delete_issue, User.current,self.issue.author, { message_id: self.id }) + UserScore.joint(:delete_issue_message, User.current,self.issue.author, { message_id: self.id }) end end end diff --git a/app/models/journals_for_message.rb b/app/models/journals_for_message.rb index cba605afc..58880919e 100644 --- a/app/models/journals_for_message.rb +++ b/app/models/journals_for_message.rb @@ -18,6 +18,9 @@ class JournalsForMessage < ActiveRecord::Base belongs_to :project, :foreign_key => 'jour_id', :conditions => "#{self.table_name}.jour_type = 'Project' " + belongs_to :course, + :foreign_key => 'jour_id', + :conditions => "#{self.table_name}.jour_type = 'Course' " belongs_to :jour, :polymorphic => true belongs_to :user @@ -30,19 +33,29 @@ class JournalsForMessage < ActiveRecord::Base :description => Proc.new{|o| o.notes }, :type => Proc.new {|o| o.jour_type }, :url => Proc.new {|o| - (o.jour.kind_of? Project) ? {:controller => 'projects', :action => 'feedback', :id => o.jour, :r => o.id, :anchor => "word_li_#{o.id}"} : {} - }#{:controller => 'documents', :action => 'show', :id => o.id}} - acts_as_activity_provider :author_key => :user_id, + if o.jour.kind_of? Project + {:controller => 'projects', :action => 'feedback', :id => o.jour, :r => o.id, :anchor => "word_li_#{o.id}"} + elsif o.jour.kind_of? Course + {:controller => 'courses', :action => 'feedback', :id => o.jour, :r => o.id, :anchor => "word_li_#{o.id}"} + end + } + acts_as_activity_provider :author_key => :user_id, :timestamp => "#{self.table_name}.updated_on", :find_options => {:include => :project } + acts_as_activity_provider :type => 'course_journals_for_messages', + :author_key => :user_id, + :timestamp => "#{self.table_name}.updated_on", + :find_options => {:include => :course } + + has_many :acts, :class_name => 'Activity', :as => :act, :dependent => :destroy validates :notes, presence: true after_create :act_as_activity #huang - after_create :reset_counters! + after_create :reset_counters!,:be_user_score after_destroy :reset_counters! - before_save :be_user_score + #before_save :be_user_score #before_destroy :down_user_score # default_scope { where('m_parent_id IS NULL') } @@ -89,6 +102,8 @@ class JournalsForMessage < ActiveRecord::Base end elsif self.jour_type == 'Project' self.acts << Activity.new(:user_id => self.reply_id) + elsif self.jour_type == 'Course' + self.acts << Activity.new(:user_id => self.reply_id) else end end @@ -105,9 +120,9 @@ class JournalsForMessage < ActiveRecord::Base # 更新用户分数 -by zjc def be_user_score #新建了留言回复 - if self.new_record? && self.reply_id != 0 + if self.reply_id != 0 #协同得分加分 - UserScore.joint(:reply_message, User.current,User.find(self.reply_id), { journals_for_messages_id: self.id }) + UserScore.joint(:reply_message, User.current,User.find(self.reply_id),self, { journals_for_messages_id: self.id }) end end # 更新用户分数 -by zjc diff --git a/app/models/mailer.rb b/app/models/mailer.rb index e954f03c8..81ef95c85 100644 --- a/app/models/mailer.rb +++ b/app/models/mailer.rb @@ -75,7 +75,12 @@ class Mailer < ActionMailer::Base return -1 end mail :to => journals_for_message.jour.author.mail, :subject => @title - else + elsif journals_for_message.jour.class.to_s.to_sym == :Contest + if !journals_for_message.jour.author.notify_about? journals_for_message + return -1 + end + mail :to => journals_for_message.jour.author.mail, :subject => @title + else mail :to => @mail.mail, :subject => @title end diff --git a/app/models/member.rb b/app/models/member.rb index de4d67687..46aefbd09 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -22,9 +22,10 @@ class Member < ActiveRecord::Base has_many :roles, :through => :member_roles belongs_to :project + belongs_to :course - validates_presence_of :principal, :project - validates_uniqueness_of :user_id, :scope => :project_id + validates_presence_of :principal + validates_uniqueness_of :user_id, :scope => [:project_id,:course_id] validate :validate_role before_destroy :set_issue_category_nil @@ -85,7 +86,13 @@ class Member < ActiveRecord::Base def set_issue_category_nil if user # remove category based auto assignments for this member - IssueCategory.update_all "assigned_to_id = NULL", ["project_id = ? AND assigned_to_id = ?", project.id, user.id] + #modify by nwb + if project + IssueCategory.update_all "assigned_to_id = NULL", ["project_id = ? AND assigned_to_id = ?", project.id, user.id] + elsif course + #IssueCategory.update_all "assigned_to_id = NULL", ["course_id = ? AND assigned_to_id = ?", course.id, user.id] + end + end end diff --git a/app/models/member_role.rb b/app/models/member_role.rb index 29ad6563d..67122a636 100644 --- a/app/models/member_role.rb +++ b/app/models/member_role.rb @@ -54,14 +54,16 @@ class MemberRole < ActiveRecord::Base end def add_role_to_subprojects - member.project.children.each do |subproject| - if subproject.inherit_members? - child_member = Member.find_or_new(subproject.id, member.user_id) - child_member.member_roles << MemberRole.new(:role => role, :inherited_from => id) - child_member.save! + if member.project + member.project.children.each do |subproject| + if subproject.inherit_members? + child_member = Member.find_or_new(subproject.id, member.user_id) + child_member.member_roles << MemberRole.new(:role => role, :inherited_from => id) + child_member.save! + end end end - end + end def remove_inherited_roles MemberRole.where(:inherited_from => id).all.group_by(&:member).each do |member, member_roles| diff --git a/app/models/memo.rb b/app/models/memo.rb index d706f814b..1e857a223 100644 --- a/app/models/memo.rb +++ b/app/models/memo.rb @@ -12,6 +12,7 @@ class Memo < ActiveRecord::Base acts_as_tree :counter_cache => :replies_count, :order => "#{Memo.table_name}.created_at ASC" acts_as_attachable + has_many :user_score_details, :class_name => 'UserScoreDetails',:as => :score_changeable_obj belongs_to :last_reply, :class_name => 'Memo', :foreign_key => 'last_reply_id' # acts_as_searchable :column => ['subject', 'content'], # #:include => { :forum => :p} @@ -40,13 +41,13 @@ class Memo < ActiveRecord::Base "parent_id", "replies_count" - after_create :add_author_as_watcher, :reset_counters! + after_create :add_author_as_watcher, :reset_counters!,:be_user_score # after_update :update_memos_forum after_destroy :reset_counters! # after_create :send_notification # after_save :plusParentAndForum # after_destroy :minusParentAndForum - before_save :be_user_score + #before_save :be_user_score # scope :visible, lambda { |*args| # includes(:forum => ).where() # } @@ -145,11 +146,11 @@ class Memo < ActiveRecord::Base #更新用户分数 -by zjc def be_user_score #新建memo且无parent的为发帖 - if self.new_record? && self.parent_id.nil? - UserScore.joint(:post_message, User.current,nil, { memo_id: self.id }) + if self.parent_id.nil? + UserScore.joint(:post_message, User.current,nil,self ,{ memo_id: self.id }) #新建memo且有parent的为回帖 - elsif self.new_record? && !self.parent_id.nil? - UserScore.joint(:reply_posting, User.current,self.parent.author, { memo_id: self.id }) + elsif !self.parent_id.nil? + UserScore.joint(:reply_posting, User.current,self.parent.author,self, { memo_id: self.id }) end end diff --git a/app/models/message.rb b/app/models/message.rb index e778977fe..faf7e5bdf 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -31,6 +31,10 @@ class Message < ActiveRecord::Base :include => {:board => :project}, :project_key => "#{Board.table_name}.project_id", :date_column => "#{table_name}.created_on" + acts_as_searchable :columns => ['subject', 'content'], + :include => {:board => :course}, + :course_key => "#{Board.table_name}.course_id", + :date_column => "#{table_name}.created_at" acts_as_event :title => Proc.new {|o| "#{o.board.name}: #{o.subject}"}, :description => :content, :datetime => :updated_on, @@ -42,6 +46,9 @@ class Message < ActiveRecord::Base acts_as_activity_provider :find_options => {:include => [{:board => :project}, :author]}, :author_key => :author_id + acts_as_activity_provider :find_options => {:include => [{:board => :course}, :author]}, + :type => 'course_messages', + :author_key => :author_id acts_as_watchable validates_presence_of :board, :subject, :content @@ -53,8 +60,8 @@ class Message < ActiveRecord::Base after_destroy :reset_counters! # fq - after_create :act_as_activity - before_save :be_user_score + after_create :act_as_activity,:be_user_score + #before_save :be_user_score #before_destroy :down_user_score # end @@ -62,6 +69,11 @@ class Message < ActiveRecord::Base includes(:board => :project).where(Project.allowed_to_condition(args.shift || User.current, :view_messages, *args)) } + scope :course_visible, lambda {|*args| + includes(:board => :course).where(Course.allowed_to_condition(args.shift || User.current, :view_course_messages, *args)) + } + + safe_attributes 'subject', 'content' safe_attributes 'locked', 'sticky', 'board_id', :if => lambda {|message, user| @@ -69,7 +81,11 @@ class Message < ActiveRecord::Base } def visible?(user=User.current) - !user.nil? && user.allowed_to?(:view_messages, project) + if project + !user.nil? && user.allowed_to?(:view_messages, project) + elsif course + !user.nil? && user.allowed_to?(:view_messages, course) + end end def cannot_reply_to_locked_topic @@ -104,6 +120,10 @@ class Message < ActiveRecord::Base board.project end + def course + board.course + end + def editable_by?(usr) usr && usr.logged? && (usr.allowed_to?(:edit_messages, project) || (self.author == usr && usr.allowed_to?(:edit_own_messages, project))) end @@ -127,11 +147,11 @@ class Message < ActiveRecord::Base #更新用户分数 -by zjc def be_user_score #新建message且无parent的为发帖 - if self.new_record? && self.parent_id.nil? - UserScore.joint(:post_message, User.current,nil, { message_id: self.id }) + if self.parent_id.nil? + UserScore.joint(:post_message, User.current,nil,self, { message_id: self.id }) #新建message且有parent的为回帖 - elsif self.new_record? && !self.parent_id.nil? - UserScore.joint(:reply_posting, User.current,self.parent.author, { message_id: self.id }) + elsif !self.parent_id.nil? + UserScore.joint(:reply_posting, User.current,self.parent.author,self, { message_id: self.id }) end end #减少用户分数 diff --git a/app/models/news.rb b/app/models/news.rb index f2dba2f8e..9a0f8b75c 100644 --- a/app/models/news.rb +++ b/app/models/news.rb @@ -18,6 +18,8 @@ class News < ActiveRecord::Base include Redmine::SafeAttributes belongs_to :project + #added by nwb + belongs_to :course belongs_to :author, :class_name => 'User', :foreign_key => 'author_id' has_many :comments, :as => :commented, :dependent => :delete_all, :order => "created_on" # fq @@ -33,6 +35,11 @@ class News < ActiveRecord::Base acts_as_event :url => Proc.new {|o| {:controller => 'news', :action => 'show', :id => o.id}} acts_as_activity_provider :find_options => {:include => [:project, :author]}, :author_key => :author_id + #added by nwb + #课程新闻独立于项目 + acts_as_activity_provider :type => 'course_news', + :find_options => {:include => [:course, :author]}, + :author_key => :author_id acts_as_watchable after_create :add_author_as_watcher @@ -44,6 +51,9 @@ class News < ActiveRecord::Base includes(:project).where(Project.allowed_to_condition(args.shift || User.current, :view_news, *args)) } + scope :course_visible, lambda {|*args| + includes(:course).where(Course.allowed_to_condition(args.shift || User.current, :view_course_news, *args)) + } safe_attributes 'title', 'summary', 'description' def visible?(user=User.current) diff --git a/app/models/praise_tread.rb b/app/models/praise_tread.rb index 8fc604671..98253d837 100644 --- a/app/models/praise_tread.rb +++ b/app/models/praise_tread.rb @@ -2,9 +2,9 @@ class PraiseTread < ActiveRecord::Base attr_accessible :user_id,:praise_tread_object_id,:praise_tread_object_type,:praise_or_tread belongs_to :user belongs_to :praise_tread_object, polymorphic: true - before_save :be_user_score + after_create :be_user_score - def find_object_by_type_and_id(type,id) + def self.find_object_by_type_and_id(type,id) @obj = nil case type when 'User' @@ -25,18 +25,30 @@ class PraiseTread < ActiveRecord::Base return @obj end + # 获取裁定对象为Message时Message所属的项目或课程 + def project + project = nil + if self.praise_tread_object_type == 'Message' + obj = PraiseTread.find_object_by_type_and_id(self.praise_tread_object_type,praise_tread_object_id) + project = obj.project + end + project + end + #更新用户分数 - by zjc def be_user_score #踩贴吧或讨论区帖子 - if self.new_record? && self.praise_or_tread == 0 && (self.praise_tread_object_type == 'Memo' || self.praise_tread_object_type == 'Message') - obj = find_object_by_type_and_id(self.praise_tread_object_type,praise_tread_object_id) + if self.praise_or_tread == 0 && (self.praise_tread_object_type == 'Memo' || self.praise_tread_object_type == 'Message') + obj = PraiseTread.find_object_by_type_and_id(self.praise_tread_object_type,praise_tread_object_id) target_user = obj.author - UserScore.skill(:treaded_by_user, User.current,target_user, { praise_tread_id: self.id }) + UserScore.skill(:treaded_by_user, User.current,target_user,self, { praise_tread_id: self.id }) #顶贴吧或讨论区帖子 - elsif self.new_record? && self.praise_or_tread == 1 && (self.praise_tread_object_id == 'Memo' || self.praise_tread_object_type == 'Message') - obj = find_object_by_type_and_id(self.praise_tread_object_type,praise_tread_object_id) + elsif self.praise_or_tread == 1 && (self.praise_tread_object_type == 'Memo' || self.praise_tread_object_type == 'Message') + obj = PraiseTread.find_object_by_type_and_id(self.praise_tread_object_type,praise_tread_object_id) target_user = obj.author - UserScore.skill(:praised_by_user, User.current,target_user,{ praise_tread_id: self.id }) + UserScore.skill(:praised_by_user, User.current,target_user,self,{ praise_tread_id: self.id }) + #更新用户等级 + UserLevels.update_user_level(target_user) end end end diff --git a/app/models/principal.rb b/app/models/principal.rb index 15cebdf53..024480635 100644 --- a/app/models/principal.rb +++ b/app/models/principal.rb @@ -26,7 +26,10 @@ class Principal < ActiveRecord::Base has_many :members, :foreign_key => 'user_id', :dependent => :destroy has_many :memberships, :class_name => 'Member', :foreign_key => 'user_id', :include => [ :project, :roles ], :conditions => "#{Project.table_name}.status<>#{Project::STATUS_ARCHIVED}", :order => "#{Project.table_name}.name" + has_many :coursememberships, :class_name => 'Member', :foreign_key => 'user_id', :include => [ :course, :roles ], :conditions => "#{Course.table_name}.status<>#{Course::STATUS_ARCHIVED}", :order => "#{Course.table_name}.name" has_many :projects, :through => :memberships + #add by nwb + has_many :courses, :through => :coursememberships has_many :issue_categories, :foreign_key => 'assigned_to_id', :dependent => :nullify # Groups and active users @@ -70,6 +73,17 @@ class Principal < ActiveRecord::Base where("#{Principal.table_name}.id NOT IN (SELECT DISTINCT user_id FROM #{Member.table_name} WHERE project_id IN (?))", ids) end } + + scope :not_member_of_course, lambda {|courses| + courses = [courses] unless courses.is_a?(Array) + if courses.empty? + where("1=0") + else + ids = courses.map(&:id) + where("#{Principal.table_name}.id NOT IN (SELECT DISTINCT user_id FROM #{Member.table_name} WHERE course_id IN (?))", ids) + end + } + scope :sorted, lambda { order(*Principal.fields_for_order_statement)} scope :applied_members, lambda {|project| diff --git a/app/models/project.rb b/app/models/project.rb index b8e11d99e..492ca86b7 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -30,6 +30,7 @@ class Project < ActiveRecord::Base # Specific overidden Activities + belongs_to :homework_attach has_many :time_entry_activities has_many :members, :include => [:principal, :roles], :conditions => "#{Principal.table_name}.type='User' AND #{Principal.table_name}.status=#{Principal::STATUS_ACTIVE}" has_many :memberships, :class_name => 'Member' @@ -38,7 +39,7 @@ class Project < ActiveRecord::Base :conditions => "#{Principal.table_name}.type='Group' OR (#{Principal.table_name}.type='User' AND #{Principal.table_name}.status=#{Principal::STATUS_ACTIVE})" has_many :users, :through => :members has_many :principals, :through => :member_principals, :source => :principal - has_many :enabled_modules, :dependent => :delete_all + has_many :enabled_modules, :dependent => :delete_all has_and_belongs_to_many :trackers, :order => "#{Tracker.table_name}.position" has_many :issues, :dependent => :destroy, :include => [:status, :tracker] has_many :issue_changes, :through => :issues, :source => :journals @@ -1129,17 +1130,13 @@ class Project < ActiveRecord::Base # 创建项目后在项目下同步创建一个讨论区 def create_board_sync @board = self.boards.build - if project_type == 1 - self.name=" #{l(:label_borad_course) }" - else - self.name =" #{l(:label_borad_project) }" - end + self.name=" #{l(:label_borad_course) }" @board.name = self.name @board.description = self.name.to_s if @board.save - logger.debug "[Project Model] ===> #{@board.to_json}" + logger.debug "[Course Model] ===> #{@board.to_json}" else - logger.error "[Project Model] ===> Auto create board when project saved, because #{@board.full_messages}" + logger.error "[Course Model] ===> Auto create board when Course saved, because #{@board.full_messages}" end end diff --git a/app/models/project_info.rb b/app/models/project_info.rb index c6edab81c..d22bf7cfd 100644 --- a/app/models/project_info.rb +++ b/app/models/project_info.rb @@ -5,7 +5,7 @@ class ProjectInfo < ActiveRecord::Base belongs_to :user validates_presence_of :project_id, :user_id validates_uniqueness_of :project_id, :scope => :user_id - + after_save :update_user_level def self.manager? (user_id, project) for project_info in project.project_infos if project_info.user_id == user_id @@ -14,4 +14,9 @@ class ProjectInfo < ActiveRecord::Base end return false end + + #更新用户等级 + def update_user_level + UserLevels.update_user_level(self.user) + end end diff --git a/app/models/role.rb b/app/models/role.rb index 2902325d3..cba219d0d 100644 --- a/app/models/role.rb +++ b/app/models/role.rb @@ -151,7 +151,7 @@ class Role < ActiveRecord::Base if action.is_a? Hash allowed_actions.include? "#{action[:controller]}/#{action[:action]}" else - allowed_permissions.include? action + allowed_permissions.include? action end end diff --git a/app/models/students_for_course.rb b/app/models/students_for_course.rb index 597d74da6..6958cfe73 100644 --- a/app/models/students_for_course.rb +++ b/app/models/students_for_course.rb @@ -1,7 +1,8 @@ class StudentsForCourse < ActiveRecord::Base attr_accessible :course_id, :student_id - belongs_to :course, :class_name => 'Project', :foreign_key => :course_id + belongs_to :course, :class_name => 'Course', :foreign_key => :course_id + belongs_to :student, :class_name => 'User', :foreign_key => :student_id validates_presence_of :course_id, :student_id diff --git a/app/models/user.rb b/app/models/user.rb index 0308dd606..30d86f5df 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -101,7 +101,7 @@ class User < Principal has_many :journal_replies, :dependent => :destroy has_many :activities, :dependent => :destroy has_many :students_for_courses - has_many :courses, :through => :students_for_courses, :source => :project + #has_many :courses, :through => :students_for_courses, :source => :project has_many :acts, :class_name => 'Activity', :as => :act, :dependent => :destroy has_many :file_commit, :class_name => 'Attachment', :foreign_key => 'author_id', :conditions => "container_type = 'Project' or container_type = 'Version'" #### @@ -343,6 +343,7 @@ class User < Principal def reload(*args) @name = nil @projects_by_role = nil + @courses_by_role = nil @membership_by_project_id = nil base_reload(*args) end @@ -658,6 +659,15 @@ class User < Principal @membership_by_project_id[project_id] end + def coursemembership(course) + course_id = course.is_a?(Course) ? course.id : course + + @membership_by_course_id ||= Hash.new {|h, course_id| + h[course_id] = coursememberships.where(:course_id => course_id).first + } + @membership_by_course_id[course_id] + end + # Return user's roles for project def roles_for_project(project) roles = [] @@ -679,11 +689,36 @@ class User < Principal roles end + # 用户课程权限判断 + def roles_for_course(course) + roles = [] + # No role on archived courses + return roles if course.nil? || course.archived? + if logged? + # Find course membership + membership = coursemembership(course) + if membership + roles = membership.roles + else + @role_non_member ||= Role.non_member + roles << @role_non_member + end + else + @role_anonymous ||= Role.anonymous + roles << @role_anonymous + end + roles + end + # Return true if the user is a member of project def member_of?(project) projects.to_a.include?(project) end + def member_of_course?(course) + courses.to_a.include?(course) + end + # Returns a hash of user's projects grouped by roles def projects_by_role return @projects_by_role if @projects_by_role @@ -704,6 +739,25 @@ class User < Principal @projects_by_role end + # 课程的角色权限 + def courses_by_role + return @courses_by_role if @courses_by_role + + @courses_by_role = Hash.new([]) + coursememberships.each do |membership| + if membership.course + membership.roles.each do |role| + @courses_by_role[role] = [] unless @courses_by_role.key?(role) + @courses_by_role[role] << membership.course + end + end + end + @courses_by_role.each do |role, courses| + courses.uniq! + end + + @courses_by_role + end # Returns true if user is arg or belongs to arg def is_or_belongs_to?(arg) if arg.is_a?(User) @@ -738,7 +792,20 @@ class User < Principal role.allowed_to?(action) && (block_given? ? yield(role, self) : true) } - elsif context && context.is_a?(Array) + #添加课程相关的权限判断 + elsif context && context.is_a?(Course) + return false unless context.allows_to?(action) + # Admin users are authorized for anything else + return true if admin? + + roles = roles_for_course(context) + return false unless roles + roles.any? {|role| + (context.is_public? || role.member?) && + role.allowed_to?(action) && + (block_given? ? yield(role, self) : true) + } + elsif context && context.is_a?(Array) if context.empty? false else @@ -751,6 +818,9 @@ class User < Principal # authorize if user has at least one role that has this permission roles = memberships.collect {|m| m.roles}.flatten.uniq + if roles.count == 0 + roles = coursememberships.collect {|m| m.roles}.flatten.uniq + end roles << (self.logged? ? Role.non_member : Role.anonymous) roles.any? {|role| role.allowed_to?(action) && @@ -885,63 +955,6 @@ class User < Principal end end - #获取user的等级 -by zjc - def get_level - if self.level.nil? - update_user_level - end - self.level.level - end - - #更新用户等级 - by zjc - def update_user_level - user_level = UserLevels.new - user_level.user = self - - #判断user的等级 - pis = self.project_infos #ProjectInfo.find_all_by_user_id(self.id) - isManager = false; - pis.each do |pi| - #判断是否为项目管理员 - if self.allowed_to?({:controller => "projects", :action => "edit"}, pi.project) - isManager = true; - end - end - has_effective_praise_count = false; - self.messages.each do |message| - if message.parent_id.nil? - ptcs = PraiseTreadCache.find_all_by_object_id(message.id) - ptcs.each do |ptc| - if ptc.object_type == 'Message' && ptc.praise_num.to_i > 5 - has_effective_praise_count = true - end - end - end - end - if !has_effective_praise_count - self.memos do |memo| - if memo.parent_id.nil? - ptcs = PraiseTreadCache.find_all_by_object_id(memo.id) - ptcs.each do |ptc| - if ptc.object_type == 'Memo' && ptc.praise_num > 5 - has_effective_praise_count = true - end - end - end - end - end - - if isManager || self.changesets.count > 100 - user_level.level = 3 - elsif (self.changesets.count > 1 && self.changesets.count <= 100) || has_effective_praise_count - user_level.level = 2 - else - user_level.level = 1 - end - user_level.save - self.reload - end - protected def validate_password_length diff --git a/app/models/user_levels.rb b/app/models/user_levels.rb index eb8dd37ed..a24738a2f 100644 --- a/app/models/user_levels.rb +++ b/app/models/user_levels.rb @@ -2,4 +2,67 @@ class UserLevels < ActiveRecord::Base attr_accessible :user_id, :level belongs_to :user + + #获取user的等级 -by zjc + def self.get_level(user) + unless user.nil? + if user.level.nil? + UserLevels.update_user_level(user) + end + user.level.level + end + + end + + #更新用户的等级 -by zjc + def self.update_user_level(user) + unless user.nil? + user_level = user.level.nil? ? UserLevels.new : user.level + user_level.user = user + + #判断user的等级 + pis = user.project_infos #ProjectInfo.find_all_by_user_id(self.id) + isManager = false; + pis.each do |pi| + #判断是否为项目管理员 + if user.allowed_to?({:controller => "projects", :action => "edit"}, pi.project) + isManager = true; + end + end + has_effective_praise_count = false; + user.messages.each do |message| + if message.parent_id.nil? + ptcs = PraiseTreadCache.find_all_by_object_id(message.id) + ptcs.each do |ptc| + if ptc.object_type == 'Message' && ptc.praise_num.to_i > 5 + has_effective_praise_count = true + end + end + end + end + if !has_effective_praise_count + user.memos do |memo| + if memo.parent_id.nil? + ptcs = PraiseTreadCache.find_all_by_object_id(memo.id) + ptcs.each do |ptc| + if ptc.object_type == 'Memo' && ptc.praise_num > 5 + has_effective_praise_count = true + end + end + end + end + end + + if isManager || user.changesets.count > 100 + user_level.level = 3 + elsif (user.changesets.count > 1 && user.changesets.count <= 100) || has_effective_praise_count + user_level.level = 2 + else + user_level.level = 1 + end + user_level.save + user.reload + end + + end end \ No newline at end of file diff --git a/app/models/user_score.rb b/app/models/user_score.rb index ceb0cd95f..6371fc12d 100644 --- a/app/models/user_score.rb +++ b/app/models/user_score.rb @@ -48,46 +48,79 @@ class UserScore < ActiveRecord::Base # # => true #当前用户发帖计分操作成功 # # Returns boolean. 返回积分保存结果 - def self.joint(operate, current_user, target_user, options={}) + def self.joint(operate, current_user, target_user,obj, options={}) current_user, target_user = get_users(current_user, target_user) user_score = current_user.user_score_attr + user_grade = nil #项目个人得分 + project = obj.project + unless project.nil? + user_grade = UserGrade.find_by_user_id_and_project_id(current_user.id, project.id) + if user_grade.nil? + user_grade = UserGrade.create(:user_id => current_user.id,:project_id => project.id) + end + end case operate when :post_message # current_user 发帖了 Add Message user_score.collaboration = user_score.collaboration.to_i + 2 user_score.save + unless user_grade.nil? + user_grade.grade = user_grade.grade.to_i + 2 + user_grade.save + end + create_score_changed_details({:current_user_id => current_user.id ,:score_type => "collaboration",:score_action => "post_message",:user_id => current_user.id,:old_score => user_score.collaboration - 2,:new_score => user_score.collaboration,:current_user_level => UserLevels.get_level(current_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) Rails.logger.info "[UserScore#joint] ===> User: #{current_user} posting a message. options => (#{options.to_s})" - when :delete_message # current_user 发帖了 Delete Message - user_score.collaboration = user_score.collaboration.to_i - 2 - user_score.save - Rails.logger.info "[UserScore#joint] ===> User: #{current_user} deleting a message. options => (#{options.to_s})" - when :post_issue # current_user 对 target_user 的缺陷留言了 Add Journal + #when :delete_message # current_user 删帖了 Delete Message + # user_score.collaboration = user_score.collaboration.to_i - 2 + # user_score.save + # Rails.logger.info "[UserScore#joint] ===> User: #{current_user} deleting a message. options => (#{options.to_s})" + when :post_issue_message # current_user 对 target_user 的缺陷留言了 Add Journal user_score.collaboration = user_score.collaboration.to_i + 1 user_score.save + unless user_grade.nil? + user_grade.grade = user_grade.grade.to_i + 1 + user_grade.save + end + create_score_changed_details({:current_user_id => current_user.id ,:target_user_id =>target_user.id, :score_type => "collaboration",:score_action => "post_issue_message",:user_id => current_user.id,:old_score => user_score.collaboration - 1,:new_score => user_score.collaboration,:current_user_level => UserLevels.get_level(current_user),:target_user_level => UserLevels.get_level(target_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) Rails.logger.info "[UserScore#joint] ===> User: #{current_user} posting a issue. options => (#{options.to_s})" - when :delete_issue # current_user 删除了 对 target_user 的缺陷留言了 Delete Journal - user_score.collaboration = user_score.collaboration.to_i - 1 - user_score.save - Rails.logger.info "[UserScore#joint] ===> User: #{current_user} deleting a issue. options => (#{options.to_s})" + #when :delete_issue_message # current_user 删除了 对 target_user 的缺陷留言了 Delete Journal + # user_score.collaboration = user_score.collaboration.to_i - 1 + # user_score.save + # Rails.logger.info "[UserScore#joint] ===> User: #{current_user} deleting a issue. options => (#{options.to_s})" when :change_issue_status # current_user 更改了缺陷的状态 Changed Issue user_score.collaboration = user_score.collaboration.to_i + 1 user_score.save + unless user_grade.nil? + user_grade.grade = user_grade.grade.to_i + 1 + user_grade.save + end + create_score_changed_details({:current_user_id => current_user.id , :score_type => "collaboration",:score_action => "change_issue_status",:user_id => current_user.id,:old_score => user_score.collaboration - 1,:new_score => user_score.collaboration,:current_user_level => UserLevels.get_level(current_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) Rails.logger.info "[UserScore#joint] ===> User: #{current_user} change issue status. options => (#{options.to_s})" when :reply_message # current_user 对 target_user 留言的回复 Add Journals_for_messages user_score.collaboration = user_score.collaboration.to_i + 1 user_score.save + unless user_grade.nil? + user_grade.grade = user_grade.grade.to_i + 1 + user_grade.save + end + create_score_changed_details({:current_user_id => current_user.id ,:target_user_id =>target_user.id, :score_type => "collaboration",:score_action => "reply_message",:user_id => current_user.id,:old_score => user_score.collaboration - 1,:new_score => user_score.collaboration,:current_user_level => UserLevels.get_level(current_user),:target_user_level => UserLevels.get_level(target_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) Rails.logger.info "[UserScore#joint] ===> User: #{current_user} reply message. options => (#{options.to_s})" - when :reply_message_delete # current_user 删除了对 target_user 留言的回复 delete Journals_for_messages - user_score.collaboration = user_score.collaboration.to_i - 1 - user_score.save - Rails.logger.info "[UserScore#joint] ===> User: #{current_user} delete reply message. options => (#{options.to_s})" + #when :reply_message_delete # current_user 删除了对 target_user 留言的回复 delete Journals_for_messages + # user_score.collaboration = user_score.collaboration.to_i - 1 + # user_score.save + # Rails.logger.info "[UserScore#joint] ===> User: #{current_user} delete reply message. options => (#{options.to_s})" when :reply_posting # current_user 对 target_user 帖子的回复 Add Message user_score.collaboration = user_score.collaboration.to_i + 1 user_score.save + unless user_grade.nil? + user_grade.grade = user_grade.grade.to_i + 1 + user_grade.save + end + create_score_changed_details({:current_user_id => current_user.id ,:target_user_id =>target_user.id, :score_type => "collaboration",:score_action => "reply_posting",:user_id => current_user.id,:old_score => user_score.collaboration - 1,:new_score => user_score.collaboration,:current_user_level => UserLevels.get_level(current_user),:target_user_level => UserLevels.get_level(target_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) Rails.logger.info "[UserScore#joint] ===> User: #{current_user} reply posting. options => (#{options.to_s})" - when :reply_deleting # current_user 删除了 对 target_user 帖子的回复 Delete Message - user_score.collaboration = user_score.collaboration.to_i - 1 - user_score.save - Rails.logger.info "[UserScore#joint] ===> User: #{current_user} reply deleting. options => (#{options.to_s})" + #when :reply_deleting # current_user 删除了 对 target_user 帖子的回复 Delete Message + # user_score.collaboration = user_score.collaboration.to_i - 1 + # user_score.save + # Rails.logger.info "[UserScore#joint] ===> User: #{current_user} reply deleting. options => (#{options.to_s})" else Rails.logger.error "[UserScore#joint] ===> #{operate} is not define." return false @@ -106,17 +139,19 @@ class UserScore < ActiveRecord::Base # # => true #当前被关注用户记分成功 # # Returns boolean. 返回积分保存结果 - def self.influence(operate, current_user, target_user, options={}) + def self.influence(operate, current_user, target_user,obj, options={}) current_user, target_user = get_users(current_user, target_user) user_score = target_user.user_score_attr case operate - when :followed_by # current_user 关注了target_user + when :followed_by # current_user 关注了target_user Add watcher user_score.influence = user_score.influence.to_i + 2 user_score.save + create_score_changed_details({:current_user_id => current_user.id ,:target_user_id =>target_user.id, :score_type => "influence",:score_action => "followed_by",:user_id => target_user.id,:old_score => user_score.influence - 2,:new_score => user_score.influence,:current_user_level => UserLevels.get_level(current_user),:target_user_level => UserLevels.get_level(target_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) Rails.logger.info "[UserScore#influence] ===> User: #{current_user} be followed. options => (#{options.to_s})" - when :cancel_followed # current_uer 取消了对 target_user的关注 + when :cancel_followed # current_uer 取消了对 target_user的关注 delete watcher user_score.influence = user_score.influence.to_i - 2 user_score.save + create_score_changed_details({:current_user_id => current_user.id ,:target_user_id =>target_user.id, :score_type => "influence",:score_action => "cancel_followed",:user_id => target_user.id,:old_score => user_score.influence + 2,:new_score => user_score.influence,:current_user_level => UserLevels.get_level(current_user),:target_user_level => UserLevels.get_level(target_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) Rails.logger.info "[UserScore#influence] ===> User: #{current_user} canceled followed. options => (#{options.to_s})" else Rails.logger.error "[UserScore#influence] ===> #{operate} is not define." @@ -136,46 +171,96 @@ class UserScore < ActiveRecord::Base # # => true #当前current_user对target_user用户帖子的记分成功 # # Returns boolean. 返回积分保存结果 - def self.skill(operate, current_user, target_user, options={}) + def self.skill(operate, current_user, target_user,obj, options={}) current_user, target_user = get_users(current_user, target_user) current_user_score = current_user.user_score_attr target_user_score = target_user.user_score_attr + current_user_grade = nil #项目个人得分 + target_user_grade = nil + project = obj.project + unless project.nil? + current_user_grade = UserGrade.find_by_user_id_and_project_id(current_user.id, project.id) + target_user_grade = UserGrade.find_by_user_id_and_project_id(target_user.id, project.id) + if current_user_grade.nil? + current_user_grade = UserGrade.create(:user_id => current_user.id,:project_id => project.id) + end + if target_user_grade.nil? + target_user_grade = UserGrade.create(:user_id => target_user.id,:project_id => project.id) + end + end case operate # when :treading # current_user 踩了 target_user 的帖子 # Rails.logger.info "[UserScore#skill] ===> User: #{current_user} treading #{target_user}'s posting. options => (#{options.to_s})" when :treaded_by_user # current_user 踩了 target_user 的帖子 - current_user_score.skill = current_user_score.skill.to_i - 2 #踩别人的帖子减2分 + current_user_score.skill = current_user_score.skill.to_i - 2 #踩别人的帖子减2分 add praise_tread current_user_score.save + unless current_user_grade.nil? + current_user_grade.grade = current_user_grade.grade - 2 + current_user_grade.save + end + create_score_changed_details({:current_user_id => current_user.id ,:target_user_id =>target_user.id, :score_type => "skill",:score_action => "treaded_by_user",:user_id => current_user.id,:old_score => current_user_score.skill + 2,:new_score => current_user_score.skill,:current_user_level => UserLevels.get_level(current_user),:target_user_level => UserLevels.get_level(target_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) if current_user.id == target_user.id target_user.reload target_user_score = target_user.user_score_attr + unless target_user_grade.nil? + target_user_grade.reload + end end - level = current_user.get_level + level = UserLevels.get_level(current_user) if level == 1 - target_user_score.skill = target_user_score.skill.to_i - 2 #帖子被一级会员踩-2分 + target_user_score.skill = target_user_score.skill.to_i - 2 #帖子被一级会员踩-2分 add praise_tread target_user_score.save + unless target_user_grade.nil? + target_user_grade.grade = target_user_grade.grade - 2 + target_user_grade.save + end + create_score_changed_details({:current_user_id => current_user.id ,:target_user_id =>target_user.id, :score_type => "skill",:score_action => "treaded_by_user",:user_id => target_user.id,:old_score => target_user_score.skill + 2,:new_score => target_user_score.skill,:current_user_level => UserLevels.get_level(current_user),:target_user_level => UserLevels.get_level(target_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) elsif level == 2 - target_user_score.skill = target_user_score.skill.to_i - 4 #帖子被二级会员踩-4分 + target_user_score.skill = target_user_score.skill.to_i - 4 #帖子被二级会员踩-4分 add praise_tread target_user_score.save + unless target_user_grade.nil? + target_user_grade.grade = target_user_grade.grade - 4 + target_user_grade.save + end + create_score_changed_details({:current_user_id => current_user.id ,:target_user_id =>target_user.id, :score_type => "skill",:score_action => "treaded_by_user",:user_id => target_user.id,:old_score => target_user_score.skill + 4,:new_score => target_user_score.skill,:current_user_level => UserLevels.get_level(current_user),:target_user_level => UserLevels.get_level(target_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) elsif level == 3 - target_user_score.skill = target_user_score.skill.to_i - 6 #帖子被三级会员踩-6分 + target_user_score.skill = target_user_score.skill.to_i - 6 #帖子被三级会员踩-6分 add praise_tread target_user_score.save + unless target_user_grade.nil? + target_user_grade.grade = target_user_grade.grade - 6 + target_user_grade.save + end + create_score_changed_details({:current_user_id => current_user.id ,:target_user_id =>target_user.id, :score_type => "skill",:score_action => "treaded_by_user",:user_id => target_user.id,:old_score => target_user_score.skill + 6,:new_score => target_user_score.skill,:current_user_level => UserLevels.get_level(current_user),:target_user_level => UserLevels.get_level(target_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) end Rails.logger.info "[UserScore#skill] ===> User: #{current_user} treaded_by #{target_user}. options => (#{options.to_s})" when :praised_by_user # current_user 顶了 target_user 的帖子 - level = current_user.get_level + level = UserLevels.get_level(current_user) if level == 1 - target_user_score.skill = target_user_score.skill.to_i + 4 #帖子被一级会员顶+4分 + target_user_score.skill = target_user_score.skill.to_i + 4 #帖子被一级会员顶+4分 add praise_tread target_user_score.save + unless target_user_grade.nil? + target_user_grade.grade = target_user_grade.grade + 4 + target_user_grade.save + end + create_score_changed_details({:current_user_id => current_user.id ,:target_user_id =>target_user.id, :score_type => "skill",:score_action => "praised_by_user",:user_id => target_user.id,:old_score => target_user_score.skill - 4,:new_score => target_user_score.skill,:current_user_level => UserLevels.get_level(current_user),:target_user_level => UserLevels.get_level(target_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) elsif level == 2 - target_user_score.skill = target_user_score.skill.to_i + 6 #帖子被二级会员顶+6分 + target_user_score.skill = target_user_score.skill.to_i + 6 #帖子被二级会员顶+6分 add praise_tread target_user_score.save + unless target_user_grade.nil? + target_user_grade.grade = target_user_grade.grade + 6 + target_user_grade.save + end + create_score_changed_details({:current_user_id => current_user.id ,:target_user_id =>target_user.id, :score_type => "skill",:score_action => "praised_by_user",:user_id => target_user.id,:old_score => target_user_score.skill - 6,:new_score => target_user_score.skill,:current_user_level => UserLevels.get_level(current_user),:target_user_level => UserLevels.get_level(target_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) elsif level == 3 - target_user_score.skill = target_user_score.skill.to_i + 8 #帖子被三级会员顶+8分 + target_user_score.skill = target_user_score.skill.to_i + 8 #帖子被三级会员顶+8分 add praise_tread target_user_score.save + unless target_user_grade.nil? + target_user_grade.grade = target_user_grade.grade + 8 + target_user_grade.save + end + create_score_changed_details({:current_user_id => current_user.id ,:target_user_id =>target_user.id, :score_type => "skill",:score_action => "praised_by_user",:user_id => target_user.id,:old_score => target_user_score.skill - 8,:new_score => target_user_score.skill,:current_user_level => UserLevels.get_level(current_user),:target_user_level => UserLevels.get_level(target_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) end - Rails.logger.info "[UserScore#skill] ===> User: #{current_user} praised_by #{target_user}. options => (#{options.to_s})" else Rails.logger.error "[UserScore#skill] ===> #{operate} is not define." @@ -195,30 +280,63 @@ class UserScore < ActiveRecord::Base # # => true #当前current_user对项目贡献积分成功 # # Returns boolean. 返回积分保存结果 - def self.project(operate, current_user, options={}) + def self.project(operate, current_user,obj, options={}) current_user, target_user = get_users(current_user, nil) user_score = current_user.try(:user_score_attr) + user_grade = nil #项目个人得分 + project = obj.project + unless project.nil? + user_grade = UserGrade.find_by_user_id_and_project_id(current_user.id, project.id) + if user_grade.nil? + user_grade = UserGrade.create(:user_id => current_user.id,:project_id => project.id) + end + end return false if current_user.nil? case operate - when :push_code # current_user 提交了代码 + when :push_code # current_user 提交了代码 changeset user_score = user_score.active.to_i + 4 user_score.save + unless user_grade.nil? + user_grade.grade = user_grade.grade + 4 + user_grade.save + end + create_score_changed_details({:current_user_id => current_user.id , :score_type => "active",:score_action => "push_code",:user_id => current_user.id,:old_score => user_score.active - 4,:new_score => user_score.active,:current_user_level => UserLevels.get_level(current_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) Rails.logger.debug "[UserScore#project] ===> User: [#{current_user.id},#{current_user.name}] pushed code one time. options => (#{options.to_s})" - when :push_document # current_user + when :push_document # current_user 提交了文档 document user_score.active = user_score.active.to_i + 4 user_score.save + unless user_grade.nil? + user_grade.grade = user_grade.grade + 4 + user_grade.save + end + create_score_changed_details({:current_user_id => current_user.id , :score_type => "active",:score_action => "push_document",:user_id => current_user.id,:old_score => user_score.active - 4,:new_score => user_score.active,:current_user_level => UserLevels.get_level(current_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) Rails.logger.debug "[UserScore#project] ===> User: [#{current_user.id},#{current_user.name}] pushed a document. options => (#{options.to_s})" - when :push_file # current_user + when :push_file # current_user 提交了附件 attachment user_score.active = user_score.active.to_i + 4 user_score.save + unless user_grade.nil? + user_grade.grade = user_grade.grade + 4 + user_grade.save + end + create_score_changed_details({:current_user_id => current_user.id , :score_type => "active",:score_action => "push_file",:user_id => current_user.id,:old_score => user_score.active - 4,:new_score => user_score.active,:current_user_level => UserLevels.get_level(current_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) Rails.logger.debug "[UserScore#project] ===> User: [#{current_user.id},#{current_user.name}] pushed a file. options => (#{options.to_s})" - when :update_issue_ratio # current_user + when :update_issue_ratio # current_user 更新了缺陷完成度 issue user_score.active = user_score.active.to_i + 2 user_score.save + unless user_grade.nil? + user_grade.grade = user_grade.grade + 2 + user_grade.save + end + create_score_changed_details({:current_user_id => current_user.id , :score_type => "active",:score_action => "update_issue_ratio",:user_id => current_user.id,:old_score => user_score.active - 2,:new_score => user_score.active,:current_user_level => UserLevels.get_level(current_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) Rails.logger.debug "[UserScore#project] ===> User: [#{current_user.id},#{current_user.name}] updated issue ratio. options => (#{options.to_s})" - when :post_issue # current_user + when :post_issue # current_user 发布了缺陷 issue user_score.active = user_score.active.to_i + 4 user_score.save + unless user_grade.nil? + user_grade.grade = user_grade.grade + 4 + user_grade.save + end + create_score_changed_details({:current_user_id => current_user.id , :score_type => "active",:score_action => "post_issue",:user_id => current_user.id,:old_score => user_score.active - 4,:new_score => user_score.active,:current_user_level => UserLevels.get_level(current_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) Rails.logger.debug "[UserScore#project] ===> User: [#{current_user.id},#{current_user.name}] posting issue. options => (#{options.to_s})" else Rails.logger.error "[UserScore#project] ===> #{operate} is not define." @@ -228,6 +346,44 @@ class UserScore < ActiveRecord::Base Rails.logger.error "[UserScore#project] ===> Exception: #{e}." end + #获取用户的user_score + def self.score(user) + if user.user_score.nil? + us = UserScore.new + us.user_id = user.id + us.save + us + else + user.user_score + end + end + + #计算总得分 + def total_score + score = self.influence.to_i + self.skill.to_i + self.collaboration.to_i + self.active.to_i + score + end + + #创建分数改变记录 -by zjc + def self.create_score_changed_details(attributes) + if attributes.is_a? Hash + usd = UserScoreDetails.new + usd.current_user_id =attributes[:current_user_id] + usd.target_user_id = attributes[:target_user_id] + usd.score_type = attributes[:score_type] + usd.score_action = attributes[:score_action] + usd.user_id = attributes[:user_id] + usd.old_score = attributes[:old_score] + usd.new_score = attributes[:new_score] + usd.current_user_level = attributes[:current_user_level] + usd.target_user_level = attributes[:target_user_level] + #usd.score_changeable_obj = attributes[:score_changeable_obj] + usd.score_changeable_obj_id = attributes[:score_changeable_obj_id] + usd.score_changeable_obj_type = attributes[:score_changeable_obj_type] + usd.save + end + end + private def self.get_users(current_user, target_user) diff --git a/app/models/user_score_details.rb b/app/models/user_score_details.rb new file mode 100644 index 000000000..61d5d098e --- /dev/null +++ b/app/models/user_score_details.rb @@ -0,0 +1,4 @@ +class UserScoreDetails < ActiveRecord::Base + attr_accessible :current_user_id, :current_user_level, :new_score, :old_score, :score_action, :score_changeable_obj_id, :score_changeable_obj_type, :score_type, :target_user_id, :target_user_level, :user_id + belongs_to :score_changeable_obj,:polymorphic => true +end diff --git a/app/models/watcher.rb b/app/models/watcher.rb index 88f23900c..e2e255a1e 100644 --- a/app/models/watcher.rb +++ b/app/models/watcher.rb @@ -22,7 +22,7 @@ class Watcher < ActiveRecord::Base has_one :project_status has_one :users_status #end - before_save :be_user_score + after_create :be_user_score before_destroy :down_user_score validates_presence_of :user @@ -76,9 +76,9 @@ class Watcher < ActiveRecord::Base # 更新用户分数 -by zjc def be_user_score #添加了关注 - if self.new_record? && self.watchable_type == 'Principal' + if self.watchable_type == 'Principal' #影响力得分 - UserScore.influence(:followed_by, self.user,self.watchable, { watcher_id: self.id }) + UserScore.influence(:followed_by, self.user,self.watchable,self, { watcher_id: self.id }) end end @@ -86,7 +86,7 @@ class Watcher < ActiveRecord::Base def down_user_score #取消关注 if self.watchable_type == 'Principal' - UserScore.influence(:cancel_followed, self.user,self.watchable, { watcher_id: self.id }) + UserScore.influence(:cancel_followed, self.user,self.watchable,self, { watcher_id: self.id }) end end diff --git a/app/views/attachments/_course_type_edit.html.erb b/app/views/attachments/_course_type_edit.html.erb new file mode 100644 index 000000000..f0bebaf89 --- /dev/null +++ b/app/views/attachments/_course_type_edit.html.erb @@ -0,0 +1,14 @@ +<% edit_allowed = User.current.allowed_to?(:manage_files, @course) %> +<% if attachmenttypes.any? %> + + <%= link_to(image_tag('edit/edit.png'), 'javascript:void(0);',:style=>"white-space:nowrap;", :id=>"edit_box"+attachment.id.to_s , + :onclick =>"$('#put-tag-form-" +attachment.id.to_s+ "').show(); + $('#attach_type_id_label" +attachment.id.to_s+ "').hide(); + $('#edit_box" +attachment.id.to_s+ "').hide();") if edit_allowed %> + +<% end %> + diff --git a/app/views/attachments/_links.html.erb b/app/views/attachments/_links.html.erb index c135ee214..52b090bd8 100644 --- a/app/views/attachments/_links.html.erb +++ b/app/views/attachments/_links.html.erb @@ -24,7 +24,8 @@ <% end %> <% end %> <% if options[:author] %> - <%= h(attachment.author) %>, <%= format_time(attachment.created_on) %> + + <%= link_to h(attachment.author),user_path(attachment.author) %>, <%= format_time(attachment.created_on) %> <% end %>

    <% end %> diff --git a/app/views/attachments/_temp.html.erb b/app/views/attachments/_temp.html.erb new file mode 100644 index 000000000..c5a3661da --- /dev/null +++ b/app/views/attachments/_temp.html.erb @@ -0,0 +1,3 @@ +
    + <%= render :partial => 'tags/tagEx', :locals => {:obj => file, :object_flag => "6"} %> +
    \ No newline at end of file diff --git a/app/views/attachments/upload.js.erb b/app/views/attachments/upload.js.erb index 63600619b..24256ccab 100644 --- a/app/views/attachments/upload.js.erb +++ b/app/views/attachments/upload.js.erb @@ -11,6 +11,6 @@ fileSpan.find('a.remove-upload') "href": '<%= j attachment_path(@attachment, :attachment_id => params[:attachment_id], :format => 'js') %>' }) .off('click'); -var divattach = fileSpan.find('div.div_attachments'); -divattach.html('<%= j(render :partial => 'tags/tagEx', :locals => {:obj => @attachment, :object_flag => "6"})%>'); +//var divattach = fileSpan.find('div.div_attachments'); +//divattach.html('<%= j(render :partial => 'tags/tagEx', :locals => {:obj => @attachment, :object_flag => "6"})%>'); <% end %> diff --git a/app/views/bids/_app_link.html.erb b/app/views/bids/_app_link.html.erb new file mode 100644 index 000000000..d61f4ef87 --- /dev/null +++ b/app/views/bids/_app_link.html.erb @@ -0,0 +1,24 @@ + + + <% count = 0 %> + <% for attachment in attachments %> + <% if attachments.count == 1 %> + + <% elsif attachments.count == 2 %> + + <% else %> + + <% end %> + <% end %> + +
    + <%= render :partial => 'attachment', :locals => {:attachment => attachment} %> + + <%= render :partial => 'attachment', :locals => {:attachment => attachment} %> + + <% if count == 3 %> + <% break %> + <% end %> + <%= render :partial => 'attachment', :locals => {:attachment => attachment} %> + <% count = count +1 %> +
    \ No newline at end of file diff --git a/app/views/bids/_attachment.html.erb b/app/views/bids/_attachment.html.erb new file mode 100644 index 000000000..6bccc08f5 --- /dev/null +++ b/app/views/bids/_attachment.html.erb @@ -0,0 +1,6 @@ +<%= link_to_attachment attachment, :class => 'icon icon-attachment', :download => true -%> +<% if attachment.is_text? %> + <%= link_to image_tag('magnifier.png'), + :controller => 'attachments', :action => 'show', + :id => attachment, :filename => attachment.filename,:style => "width:50px"%> +<% end %> \ No newline at end of file diff --git a/app/views/bids/_bid_homework_show.html.erb b/app/views/bids/_bid_homework_show.html.erb index c4eb875a1..0f12b8476 100644 --- a/app/views/bids/_bid_homework_show.html.erb +++ b/app/views/bids/_bid_homework_show.html.erb @@ -13,9 +13,9 @@ <%= l(:label_user_create_project_homework) %> <%= link_to(bid.name, respond_path(bid), :class => 'bid_path') %> - <% if(User.current.logged? && (!Member.where('user_id = ? and project_id = ?', User.current.id, bid.courses.first.id).first.nil? && (Member.where('user_id = ? and project_id = ?', User.current.id, bid.courses.first.id).first.roles&Role.where('id = ? or id = ? or id =?',5, 10, 7)).size >0)) %> + <% if(User.current.logged? && (!Member.where('user_id = ? and course_id = ?', User.current.id, bid.courses.first.id).first.nil? && (Member.where('user_id = ? and course_id = ?', User.current.id, bid.courses.first.id).first.roles&Role.where('id = ? or id = ? or id =?',5, 10, 7)).size >0)) %> <%# 提交作业按钮 %> - + <% cur_user_homework = cur_user_homework_for_bid(bid) %> <% if cur_user_homework!= nil && cur_user_homework.count == 0 %> <%= link_to l(:label_commit_homework),new_homework_attach_path(bid) %> @@ -26,7 +26,7 @@ <% if (User.current.admin?||User.current.id==bid.author_id) %> <%= link_to( l(:button_edit), - {:action => 'edit', :controller=>'bids', :project_id =>@project.id, :bid_id => bid.id}, + {:action => 'edit', :controller=>'bids', :course_id =>@course.id, :bid_id => bid.id}, :class => 'icon icon-edit' ) %> <%= link_to( @@ -51,9 +51,9 @@ end %> <% if bid.homework_type == 1%> - <%= l(:label_x_homework_project, :count => bid.homeworks.count) %>(<%= link_to bid.homeworks.count, project_for_bid_path(bid.id) %>) + <%= l(:label_x_homework_project, :count => bid.homeworks.count) %>(<%= link_to bid.homeworks.count, course_for_bid_path(bid.id) %>) <% else %> - <%= l(:label_x_homework_project, :count => @temp.count) %>(<%= link_to @temp.count, project_for_bid_path(bid.id) %>) + <%= l(:label_x_homework_project, :count => @temp.count) %>(<%= link_to @temp.count, course_for_bid_path(bid.id) %>) <% end %> <%= l(:label_x_responses, :count => bid.commit) %>(<%= link_to bid.commit, respond_path(bid) %>) @@ -92,9 +92,6 @@ <% end %> <% end %> - \ No newline at end of file diff --git a/app/views/bids/_homework.html.erb b/app/views/bids/_homework.html.erb index 4e2681ba6..a013facbc 100644 --- a/app/views/bids/_homework.html.erb +++ b/app/views/bids/_homework.html.erb @@ -21,22 +21,48 @@ $.globalEval(submit_homework()); return false; } + + function show() + { + $("#what_is_project_div").slideToggle(); + } -<% if User.current.logged? && (!Member.where('user_id = ? and project_id = ?', User.current.id, @bid.courses.first.id).first.nil? && - (Member.where('user_id = ? and project_id = ?', User.current.id, - @bid.courses.first.id).first.roles&Role.where('id = ? or id = ? or id =?',5, 10, 7)).size >0) && cur_user_homework_for_bid(@bid).count == 0 %> +<% if User.current.logged? && User.current.member_of_course?(@bid.courses.first) && cur_user_homework_for_bid(@bid).count == 0 && is_cur_course_student(@bid.courses.first) %>
    - - <%= link_to l(:label_course_new_homework),new_homework_attach_path %> + <%#= link_to l(:label_commit_homework), new_submit_homework_path, :onclick => "$('#put-bid-form').slideToggle(); this.blur(); return false;" %> + <%= link_to l(:label_course_new_homework),new_homework_attach_path %>  (每一个作业都可以是一个精美的作品)
    <% end %> -<% if @homework_list.empty? %> -
    - 暂无学生提交作业! -
    -<% end %> + + + + + + + + + +
    + <% if @homework_list.empty? %> +
    + 暂无学生提交作业! +
    + <% end %> +
    + +
    + + + +
    <%= render :partial => 'homework_list', :locals => {:homework => @homework_list} %> diff --git a/app/views/bids/_homework_list.html.erb b/app/views/bids/_homework_list.html.erb index 18778f5e9..705040579 100644 --- a/app/views/bids/_homework_list.html.erb +++ b/app/views/bids/_homework_list.html.erb @@ -3,23 +3,25 @@ <% is_teacher = is_course_teacher User.current,@bid.courses.first %> <% is_evaluation = @bid.is_evaluation == 1 || @bid.is_evaluation == nil %> -<%= form_tag(:controller => 'bids', :action => "show_project", :method => :get) do %> +<%= form_tag(:controller => 'bids', :action => "show_courseEx", :method => :get) do %>
    + + + +
    <%= l(:label_task_plural)%>(<%= @homework_list.count%>) - <%= link_to "作业打包下载", zipdown_assort_path(obj_class: @bid.class, obj_id: @bid), remote: false, class: "button_submit button_submit_font_white", style: "margin: 5px 10px;line-height: 20px;height: 20px;display: inline-block;" if( + <%#= link_to "作业打包下载", zipdown_assort_path(obj_class: @bid.class, obj_id: @bid), remote: false, class: "button_submit button_submit_font_white", style: "margin: 5px 10px;line-height: 20px;height: 20px;display: inline-block;" if( User.current.admin? || !(User.current.roles_for_project(@bid.courses.first).map(&:id) & ([7,9])).empty? ) || (Rails.env.development?) %> - -
    @@ -28,76 +30,121 @@ <% @homework_list.each do |homework|%> - - - - +
    <%= image_tag(url_to_avatar(homework.user), :class => "avatar")%> - - - + diff --git a/app/views/bids/show.html.erb b/app/views/bids/show.html.erb index 8b7e0d8ea..96ed4ea75 100644 --- a/app/views/bids/show.html.erb +++ b/app/views/bids/show.html.erb @@ -2,7 +2,7 @@
    <%= image_tag(url_to_avatar(@bid.author), :class => "avatar")%> -

    <%= link_to(@bid.author.lastname+@bid.author.firstname, user_path(@bid.author))%>:<%= @bid.name %>

    +

    <%= link_to(@bid.author.lastname+@bid.author.firstname, user_path(@bid.author))%>:<%= link_to(@bid.name,respond_path(@bid)) %>

    <% if @bid.reward_type.nil? or @bid.reward_type == 1%>

    <%= l(:label_bids_reward_method) %><%= l(:label_call_bonus) %>  <%= l(:label_RMB_sign) %><%= @bid.budget %> diff --git a/app/views/bids/show_course.html.erb b/app/views/bids/show_course.html.erb index 574bd117c..aacc011e8 100644 --- a/app/views/bids/show_course.html.erb +++ b/app/views/bids/show_course.html.erb @@ -8,10 +8,10 @@

    diff --git a/app/views/bids/show_courseEx.html.erb b/app/views/bids/show_courseEx.html.erb new file mode 100644 index 000000000..039de6b7a --- /dev/null +++ b/app/views/bids/show_courseEx.html.erb @@ -0,0 +1,72 @@ +<% if @bid.homework_type == Bid::HomeworkFile %> + + <%= render :partial => 'homework' %> + +<% else %> + + + <% if User.current.logged? %> + + +
    -   作业   :  - <% if homework.name == nil || homework.name == "" %> - <% attachments = homework.attachments.map %> - <% for attachment in attachments %> - <% if attachments.count > 1 %> - <% homework_filename = attachment.filename + "等" + attachments.count.to_s + "个文件" %> - <% else %> - <% homework_filename = attachment.filename %> - <% end %> - <% end %> - <% else %> - <% homework_filename = homework.name %> + + + + + + + + + + - - - - - + +
    <%= image_tag(url_to_avatar(homework.user), :class => "avatar")%>
    +

    + <%= link_to (is_teacher ? homework.user.realname : homework.user ), user_path(homework.user),{:style => "color:#727272"} %> +

    +
    + <% if (users_for_homework(homework).include?(User.current) || is_teacher) %> + <%= link_to l(:button_edit), edit_homework_attach_path(homework) %> + <% if homework.user == User.current || is_teacher %> + <%= link_to(l(:label_bid_respond_delete), homework, + method: :delete, :confirm => l(:text_are_you_sure)) %> <% end %> - - <% if is_evaluation || is_teacher%> - <%= link_to homework_filename, :controller => "zipdown", :action => "download_user_homework",:homework => homework%> - <% else %> - <%= homework_filename %> - <% end %> - - - <% if is_student %> - <% if is_evaluation %> - <%= link_to "互评>>" , homework_attach_path(homework)%> - <% else %> - <%= link_to "查看详细" , homework_attach_path(homework)%> - <% end %> - <% else %> - <% if is_teacher %> - <%= link_to "综评>>" , homework_attach_path(homework)%> - <% end %> - <% end %> -
      - 发布人:  <%= link_to ( is_teacher ? homework.user.realname : homework.user ), user_path(homework.user)%> - - 作业评分: + <% end %> +
    + +
    + + + + + + - <%= format("%.2f", homework.rate_averages.first.try(:avg).to_f ) %> - - - + + + + + + + + + - - + +
    + 作品名称:  + <% if homework.name == nil || homework.name == "" %> + <% homework_filename = homework.user.name + "提交的作业" %> + <% else %> + <% homework_filename = homework.name %> + <% end %> + + <%= link_to homework_filename , homework_attach_path(homework)%> + + + 合作成员:  + <% homework_users = homework_user_of_homework(homework,is_teacher) %> + <% if homework.users.count == 0 %> + 无 + <% else %> + <%= homework_users %> + <% end %> + + <% if Time.parse(@bid.deadline.to_s) < Time.parse(homework.created_at.to_s) %> + 迟交 + <% end %> +
    - <% if Time.parse(@bid.deadline.to_s) < Time.parse(homework.created_at.to_s) %> - 迟交 - <% end %> -
    + 开发项目:  + <% if homework.project != nil %> + <%= link_to homework.project.name,project_path(homework.project.id)%> + <% else %> + 暂无 + <% end %> + + 项目得分:  + ;"> + <%= homework.project.nil? ? "N/A" : project_score(homework.project) %> + + +
    + 提交文件:  + <% if is_evaluation || is_teacher%> + <%= link_to "打包下载", :controller => "zipdown", :action => "download_user_homework",:homework => homework%> + <% else %> + 未开启互评功能作业不允许下载 + <% end %> + + + 互评得分:  + <% student_homework_score = student_score_for_homework(homework) %> + ;"> + <% score = student_homework_score == "0.00"? "N/A" : student_homework_score %> + <%= score %> +    + <% if is_evaluation && is_student && (!users_for_homework(homework).include? User.current)%> + <%= link_to "学生互评>>",homework_attach_path(homework) %> + <% end %> + +
      - <% if User.current.member_of?(@bid.courses.first) %> - <%= l(:label_bidding_user_studentcode) %>  : <%= homework.user.student_id%> - <% end %> - - <% if (users_for_homework(homework).include?(User.current) || is_teacher) %> - <%= link_to l(:button_edit), edit_homework_attach_path(homework) %> - <% if homework.user == User.current || is_teacher %> - <%= link_to(l(:label_bid_respond_delete), homework, - method: :delete, :confirm => l(:text_are_you_sure)) %> - <% end %> - <% end %> - + <% if is_evaluation || is_teacher%> + <%= render :partial => 'app_link', :locals => {:attachments => homework.attachments} %> + <% end %> + + 终评得分:  + <% totle_homework_score = score_for_homework(homework) %> + ;"> + <% score = totle_homework_score == "0.00"? "N/A" : totle_homework_score %> + <%= score %> +    + <% if is_teacher %> + <%= link_to "教师评分>>",homework_attach_path(homework) %> + <% end %> + +
    - @@ -22,10 +22,9 @@

    - +
    <%= link_to_project(course) %> - <%= l(:label_homework) %> (<%= link_to (course.homeworks.count), {:controller => 'projects', :action => 'homework', :id => course.identifier} %>) + <%= link_to_course(course) %> + <%= l(:label_homework) %> (<%= link_to (course.homeworks.count), {:controller => 'courses', :action => 'homework', :id => course.id} %>)     - <%= l(:label_course_news)%> (<%= link_to (course.news.count), {:controller => 'news', :action => 'index', :project_id => course.identifier} %>) + <%= l(:label_course_news)%> (<%= link_to (course.news.count), {:controller => 'news', :action => 'index', :course_id => course.id} %>)
    <%= format_time(course.created_on) %> <%= format_time(course.created_at) %> - <% t_course = Course.find_by_extra(course.identifier) %> - 教师:<%= link_to(t_course.teacher.lastname+t_course.teacher.firstname, user_path(t_course.teacher)) %> + 教师:<%= link_to(course.teacher.lastname+course.teacher.firstname, user_path(course.teacher)) %>
    + + +
    +
    + + + <% if @bid.reward_type == Bid::Homework %> + + + + <% else %> + + + + <% end %> + + + +
    <%= select_tag 'bid', options_for_select(select_option_helper(@option)), :name => 'bid', :class => 'grayline' %> + +
    + <%= link_to '创建项目', new_project_path(course: 0, project_type: 0), :target => '_blank' %> +
    +
    <%= f.text_area :bid_message, :id => "bid_message", :required => true, :rows => 4, :cols => 40, :placeholder => l(:label_bid_reason_homework), :style => "resize: none;", :class => 'noline' %>
    <%= f.text_area :bid_message, :id => "bid_message", :required => true, :rows => 4, :cols => 40, :placeholder => l(:label_bid_reason), :style => "resize: none;", :class => 'noline' %>
    + <%= submit_tag l(:button_add), :name => nil, :class => "enterprise", + :onmouseout => "this.style.backgroundPosition = 'left top'", + :onmouseover => "this.style.backgroundPosition = 'left -30px'" %> + <%= submit_tag l(:button_cancel), :name => nil, :onclick => "cancel();", + :type => 'button', :class => "enterprise", :onmouseout => "this.style.backgroundPosition = 'left top'", + :onmouseover => "this.style.backgroundPosition = 'left -30px'" %> +
    + <% end %> + + <% end %> +
    + <%= render :partial => 'project_list', :locals => {:bidding_project => @bidding_project, :bid => @bid} %> +
    +<% end %> + diff --git a/app/views/boards/_course_show.html.erb b/app/views/boards/_course_show.html.erb new file mode 100644 index 000000000..c9f78d8e1 --- /dev/null +++ b/app/views/boards/_course_show.html.erb @@ -0,0 +1,106 @@ + + + + + + + + + +
    <%=h @board.name %>
    + +<% if !User.current.logged?%> +
    + <%= l(:label_user_login_course_board) %> + <%= link_to l(:label_user_login_new), signin_path %> +
    +
    +<% end %> + + +
    + 共有 <%=link_to @topics.count %> 个贴子 + + <%= link_to l(:label_message_new), + new_board_message_path(@board), + :class => 'icon icon-add', + :onclick => 'showAndScrollTo("add-message", "message_subject"); return false;' if User.current.logged? %> + +
    +
    + <% if @topics.any? %> + + <% @topics.each do |topic| %> + + + + + +
    <%= link_to image_tag(url_to_avatar(topic.author), :class => "avatar"), user_path(topic.author) %> + + + + + + + +
    <%= link_to h(topic.subject), board_message_path(@board, topic) %> + +
    <%=link_to (topic.replies_count), board_message_path(@board, topic) %>
    回答
    <%= authoring topic.created_on, topic.author %>
    + + + <% end %> + + + <% else %> +

    <%= l(:label_no_data) %>

    + <% end %> +
    + +<% other_formats_links do |f| %> + <%= f.link_to 'Atom', :url => {:key => User.current.rss_key} %> +<% end %> + +<% html_title @board.name %> + +<% content_for :header_tags do %> + <%= auto_discovery_link_tag(:atom, {:format => 'atom', :key => User.current.rss_key}, :title => "#{@course}: #{@board}") %> +<% end %> diff --git a/app/views/boards/_project_show.html.erb b/app/views/boards/_project_show.html.erb new file mode 100644 index 000000000..35868090c --- /dev/null +++ b/app/views/boards/_project_show.html.erb @@ -0,0 +1,110 @@ + + + + + + + + + +
    <%=h @board.name %>
    + +<% if !User.current.logged?%> +
    + <% if @project.project_type == 1 %> + <%= l(:label_user_login_course_board) %> + <% else %> + <%= l(:label_user_login_project_board) %> + <% end %> + <%= link_to l(:label_user_login_new), signin_path %> +
    +
    +<% end %> + + +
    + 共有 <%=link_to @topics.count %> 个贴子 + + <%= link_to l(:label_message_new), + new_board_message_path(@board), + :class => 'icon icon-add', + :onclick => 'showAndScrollTo("add-message", "message_subject"); return false;' if User.current.logged? %> + +
    +
    + <% if @topics.any? %> + + <% @topics.each do |topic| %> + + + + + +
    <%= link_to image_tag(url_to_avatar(topic.author), :class => "avatar"), user_path(topic.author) %> + + + + + + + +
    <%= link_to h(topic.subject), board_message_path(@board, topic) %> + +
    <%=link_to (topic.replies_count), board_message_path(@board, topic) %>
    回答
    <%= authoring topic.created_on, topic.author %>
    + + + <% end %> + + + <% else %> +

    <%= l(:label_no_data) %>

    + <% end %> +
    + +<% other_formats_links do |f| %> + <%= f.link_to 'Atom', :url => {:key => User.current.rss_key} %> +<% end %> + +<% html_title @board.name %> + +<% content_for :header_tags do %> + <%= auto_discovery_link_tag(:atom, {:format => 'atom', :key => User.current.rss_key}, :title => "#{@project}: #{@board}") %> +<% end %> diff --git a/app/views/boards/show.html.erb b/app/views/boards/show.html.erb index 849519d0d..6e5888363 100644 --- a/app/views/boards/show.html.erb +++ b/app/views/boards/show.html.erb @@ -1,110 +1,5 @@ - - - - - - - - - -
    <%=h @board.name %>
    - -<% if !User.current.logged?%> -
    - <% if @project.project_type == 1 %> - <%= l(:label_user_login_course_board) %> - <% else %> - <%= l(:label_user_login_project_board) %> - <% end %> - <%= link_to l(:label_user_login_new), signin_path %> -
    -
    -<% end %> - - -
    -共有 <%=link_to @topics.count %> 个贴子 - - <%= link_to l(:label_message_new), - new_board_message_path(@board), - :class => 'icon icon-add', - :onclick => 'showAndScrollTo("add-message", "message_subject"); return false;' if User.current.logged? %> - -
    -
    -<% if @topics.any? %> - - <% @topics.each do |topic| %> - - - - - -
    <%= link_to image_tag(url_to_avatar(topic.author), :class => "avatar"), user_path(topic.author) %> - - - - - - - -
    <%= link_to h(topic.subject), board_message_path(@board, topic) %> - -
    <%=link_to (topic.replies_count), board_message_path(@board, topic) %>
    回答
    <%= authoring topic.created_on, topic.author %>
    - - - <% end %> - - -<% else %> -

    <%= l(:label_no_data) %>

    -<% end %> -
    - -<% other_formats_links do |f| %> - <%= f.link_to 'Atom', :url => {:key => User.current.rss_key} %> -<% end %> - -<% html_title @board.name %> - -<% content_for :header_tags do %> - <%= auto_discovery_link_tag(:atom, {:format => 'atom', :key => User.current.rss_key}, :title => "#{@project}: #{@board}") %> +<% if @project %> + <%= render :partial => 'project_show', locals: {project: @project} %> +<% elsif @course %> + <%= render :partial => 'course_show', locals: {course: @course} %> <% end %> diff --git a/app/views/contests/_list_projects.html.erb b/app/views/contests/_list_projects.html.erb index 48a5ed328..10086e5a3 100644 --- a/app/views/contests/_list_projects.html.erb +++ b/app/views/contests/_list_projects.html.erb @@ -76,7 +76,8 @@ <%= l(:label_contest_user) %> <% unless c_project.user.nil? %> - <%= c_project.user.lastname %><%= c_project.user.firstname %> + + <%= link_to c_project.user.lastname + c_project.user.firstname,user_path(c_project.user) %> <% end %> diff --git a/app/views/contests/show_attendingcontest.html.erb b/app/views/contests/show_attendingcontest.html.erb index d919baffe..ecdfd5ac5 100644 --- a/app/views/contests/show_attendingcontest.html.erb +++ b/app/views/contests/show_attendingcontest.html.erb @@ -259,7 +259,10 @@ <%= l(:label_attendingcontest_time) %> :<%= format_time c_project.created_at %> <%= l(:label_attendingcontest_spoksman) %> - :<%= c_project.user.name %> + + <% unless c_project.nil? || c_project.user.nil? %> + :<%= link_to c_project.user.name,user_path(c_project.user) %> + <% end %>
    @@ -293,7 +296,10 @@ <%= l(:label_attendingcontest_time) %> :<%= format_time c_softapplication.created_at %> <%= l(:label_attendingcontest_spoksman) %> - :<%= c_softapplication.softapplication.user.name %> + + <% unless c_softapplication.nil? || c_softapplication.softapplication.nil? || c_softapplication.softapplication.user.nil? %> + :<%= link_to c_softapplication.softapplication.user.name,user_path(c_softapplication.softapplication.user) %> + <% end %>
    diff --git a/app/views/contests/show_contest.html.erb b/app/views/contests/show_contest.html.erb index 67414b0c8..c379bc668 100644 --- a/app/views/contests/show_contest.html.erb +++ b/app/views/contests/show_contest.html.erb @@ -15,7 +15,7 @@ <%= render :partial => "/praise_tread/praise_tread", - :locals => {:obj => @contest,:show_flag => true,:user_id =>User.current.id}%> + :locals => {:obj => @contest,:show_flag => true,:user_id =>User.current.id,:horizontal => false}%> diff --git a/app/views/courses/_course.html.erb b/app/views/courses/_course.html.erb new file mode 100644 index 000000000..80cd7df9d --- /dev/null +++ b/app/views/courses/_course.html.erb @@ -0,0 +1,87 @@ +
    +
    + <% if get_avatar?(course)%> + <%= image_tag(url_to_avatar(course), :class => "avatar2") %> + <% else %> + <%= image_tag('../images/avatars/course/course.jpg', :class => "avatar2") %> + <% end %> +
    + +
    +

    + <%= content_tag('span',"#{l(:label_bid_show_course_name)}:", :class => "course-font")%> + <%= content_tag('span', link_to("#{@course.name}", course_path(@course), :class => "info"))%> +

    +

    + <%= content_tag('span', "#{l(:label_institution_name)}:", :class => "course-font")%> + <% @admin = @course.course_infos%> + <%if @admin&&@admin.first&&@admin.first.user&&@admin.first.user.user_extensions%> + + <%# unless @course.course_extra.school.nil? %> + <%= @course.teacher.user_extensions.school.try(:name) %> + <%# end %> + <% end %> +

    +

    + <%= content_tag('div', "#{l(:field_teacher_name)}:", :class => "info course-font teacher") %> + <% if @admin.size > 0 %> + <%= content_tag('a', @admin.collect{|u| link_to(u.user.lastname+u.user.firstname, user_path(u.user_id))}.join(", ").html_safe) %> + <% end %> +

    + +
    + +
    +

    + <%= content_tag('span', link_to("#{@course.homeworks.count}", homework_course_path(@course)), :class => "info") %> + <%= content_tag('span', l(:label_x_task, :count => @course.homeworks.count)) %> +

    +

    + <% files_count = @course.attachments.count %> + <%= content_tag('span', link_to(files_count, course_files_path(@course)), :class => "info") %> + <%= content_tag('span', l(:label_x_data,:count => files_count)) %> +

    +

    + <%= content_tag('span', "#{garble @course.members.count}", :class => "info") %> + <%= content_tag('span', l(:label_x_member, :count => @course.members.count)) %> +

    + + +

    + + <%= content_tag('span', link_to("#{@course_activity_count[@course.id]}", course_path(@course)), :class => "info") %> + <%= content_tag('span', l(:label_x_activity, :count => @course_activity_count[@course.id])) %> +

    + + +
    + + <% if(course_endTime_timeout? @course) %> + + 课程学期已结束 + + <% else %> + <%= join_in_course_for_list(@course, User.current,['regular'])%> + <% end -%> +
    +
    +
    + +
    +
    + <%= content_tag "span","#{l(:label_duration_time)}:", :class => "course-font"%> + <%= get_course_term @course %> +
    +
    + +
    + <%= content_tag "span", "#{l(:label_course_brief_introduction)}:", :class => "course-font" %> + <%= content_tag "div", course.short_description, :class => "brief_introduction", :title => course.short_description %> +
    + +
    +
    + <%= image_tag( "/images/sidebar/tags.png") %> + <%= render :partial => 'tags/tag_name', :locals => {:obj => @course,:object_flag => "9",:non_list_all => true }%> +
    +
    diff --git a/app/views/projects/_course_form.html.erb b/app/views/courses/_course_form.html.erb similarity index 86% rename from app/views/projects/_course_form.html.erb rename to app/views/courses/_course_form.html.erb index 017c4e6ee..67f3c5a8d 100644 --- a/app/views/projects/_course_form.html.erb +++ b/app/views/courses/_course_form.html.erb @@ -17,21 +17,20 @@ <% object = [] %> -<% object << 'project' %> <% object << 'course' %> <%= error_messages_for object %> - -<% unless @project.new_record? %> -

    <%= render :partial=>"avatar/avatar_form",:locals=> {source:@project} %>

    + +<% unless @course.new_record? %> +

    <%= render :partial=>"avatar/avatar_form",:locals=> {source:@course} %>

    <% end %> -

    +

    - @@ -292,48 +291,33 @@ - -

    +

    <%= l(:text_command) %> <% end %> - -

    +

    -

    <%= f.check_box :is_public, :style => "margin-left:10px;" %><%= l(:label_public_info) %>

    -

    <%= f.text_field :project_type, :value => 1 %>

    +

    <%= f.check_box :is_public, :style => "margin-left:10px;" %><%= l(:label_course_public_info) %>

    +

    <%= f.text_field :course_type, :value => 1 %>

    -<%= wikitoolbar_for 'project_description' %> +<%= wikitoolbar_for 'course_description' %> -<% @project.custom_field_values.each do |value| %> -

    <%= custom_field_tag_with_label :project, value %>

    +<% @course.custom_field_values.each do |value| %> +

    <%= custom_field_tag_with_label :course, value %>

    <% end %> -<%= call_hook(:view_projects_form, :project => @project, :form => f) %> +<%= call_hook(:view_courses_form, :course => @course, :form => f) %> - + -<% unless @project.identifier_frozen? %> +<% unless @course.extra_frozen? %> <% content_for :header_tags do %> - <%= javascript_include_tag 'project_identifier' %> + <%= javascript_include_tag 'course_identifier' %> <% end %> <% end %> -<% if !User.current.admin? && @project.inherit_members? && @project.parent && User.current.member_of?(@project.parent) %> - <%= javascript_tag do %> - $(document).ready(function() { - $("#project_inherit_members").change(function(){ - if (!$(this).is(':checked')) { - if (!confirm("<%= escape_javascript(l(:text_own_membership_delete_confirmation)) %>")) { - $("#project_inherit_members").attr("checked", true); - } - } - }); - }); - <% end %> -<% end %> diff --git a/app/views/courses/_edit.html.erb b/app/views/courses/_edit.html.erb new file mode 100644 index 000000000..92f59f85e --- /dev/null +++ b/app/views/courses/_edit.html.erb @@ -0,0 +1,6 @@ +
    +<%= labelled_form_for @course do |f| %> + <%= render :partial => 'course_form', :locals => { :f => f } %> + <%= submit_tag l(:button_save) %> +<% end %> +
    diff --git a/app/views/projects/_homework_form.html.erb b/app/views/courses/_homework_form.html.erb similarity index 95% rename from app/views/projects/_homework_form.html.erb rename to app/views/courses/_homework_form.html.erb index 596d83071..b30785e1b 100644 --- a/app/views/projects/_homework_form.html.erb +++ b/app/views/courses/_homework_form.html.erb @@ -21,7 +21,6 @@ <%= error_messages_for 'bid' %> -

    <%= l(:label_homeworks_form_new_description) %>

    <%= f.text_field :name, :required => true, :size => 60, :style => "width:490px;", :maxlength => Bid::NAME_LENGTH_LIMIT %>

    @@ -34,7 +33,7 @@

    <%= f.select :is_evaluation, is_evaluation_option %>

    -

    <%= hidden_field_tag 'course_id', @project.id %> +

    <%= hidden_field_tag 'course_id', @course.id %>

    <%= l(:label_attachment_plural) %>

    <%= render :partial => 'attachments/form', :locals => {:container => @homework} %>

    diff --git a/app/views/courses/_member_list.html.erb b/app/views/courses/_member_list.html.erb new file mode 100644 index 000000000..a8a9e8085 --- /dev/null +++ b/app/views/courses/_member_list.html.erb @@ -0,0 +1,35 @@ +<% if members.any? %> + <% members.each do |member| %> +
    + <% next if member.new_record? %> + <% unless member.created_on.nil? %> + <%= content_tag "p", "#{format_date(member.created_on)}#{l(:label_member_since)}", :class => "float_right member_since" %> + <% end %> + <%= member.user.nil? ? '' : (image_tag(url_to_avatar(member.user), :class => 'avatar')) %> + <% if @canShowCode %> + <%= content_tag "div", link_to(member.user.show_name, user_path(member.user)), :class => "nomargin avatar_name" %> + <% else %> + <%= content_tag "div", link_to(member.user.name, user_path(member.user)), :class => "nomargin avatar_name" %> + <% end %> + + + <% unless member.user.user_extensions.identity ==0 %> + + <%if @canShowCode%> + <%= content_tag "p", "#{l(:label_bidding_user_studentcode)}#{' : '}#{member.user.user_extensions.student_id}", :class => "nomargin avatar_name" %> + <% end %> + <% end %> +
      +

    +

    +
    + + <%= call_hook(:view_projects_settings_members_table_row, { :course => @course, :member => member}) %> +
    + <% end; reset_cycle %> + +<% else %> +

    + <%= l(:label_no_data) %> +

    +<% end %> \ No newline at end of file diff --git a/app/views/courses/_set_course_time.html.erb b/app/views/courses/_set_course_time.html.erb index 7f2b629c1..384b07df2 100644 --- a/app/views/courses/_set_course_time.html.erb +++ b/app/views/courses/_set_course_time.html.erb @@ -1,11 +1,11 @@ <% - id = "finish_course_#{project.id}" - display = (project.course_extra.teacher.id == User.current.id || User.current.admin?) + id = "finish_course_#{course.id}" + display = (course.teacher.id == User.current.id || User.current.admin?) %> <% if display #如果课程已结束%> - <% linkPath = course_endTime_timeout?(project) ? restartcourse_project_path(project) : finishcourse_project_path(project, format: :js) %> - <% desc = course_endTime_timeout?(project) ? '重启' : '关闭' %> + <% linkPath = course_endTime_timeout?(course) ? restartcourse_course_path(course) : finishcourse_course_path(course, format: :js) %> + <% desc = course_endTime_timeout?(course) ? '重启' : '关闭' %> <%= link_to "#{desc}课程", linkPath, :remote => true, :method => :post, :id => id, :confirm => ("确定要#{desc}课程?") %> <% else %> diff --git a/app/views/courses/feedback.html.erb b/app/views/courses/feedback.html.erb new file mode 100644 index 000000000..90803fdd0 --- /dev/null +++ b/app/views/courses/feedback.html.erb @@ -0,0 +1,102 @@ + + +<% reply_allow = JournalsForMessage.create_by_user? User.current %> + +

    <%= l(:label_user_response) %>

    + +<% if !User.current.logged?%> +
    + <%= l(:label_user_login_tips) %> + <%= link_to l(:label_user_login_new), signin_path %> +
    +
    +<% else %> +
    + <%= form_for('new_form', :method => :post, + :url => {:controller => 'words', :action => 'leave_course_message'}) do |f|%> + <%= f.text_area 'course_message', :rows => 3, :cols => 65, + :placeholder => "#{l(:label_welcome_my_respond)}", + :style => "resize: none; width: 98%", + :class => 'noline'%> + <%= submit_tag l(:button_leave_meassge), :name => nil , :class => "enterprise" , :style => "display: block; float: right; margin-right: 1%; margin-top: 1px;"%> + <% end %> +
    +<% end %> +
    +<% if @jour.size >0 %> +
      + <% for journal in @jour%> +
    • + <%= image_tag(url_to_avatar(journal.user), :class => "avatar") %> + + <%= link_to journal.user, user_path(journal.user)%> + <%= textilizable journal.notes%> + <%= l :label_update_time %>: <%= format_time journal.created_on %> + <% id = 'course_respond_form_'+journal.id.to_s%> + + <% if reply_allow %> + <%= link_to l(:label_projects_feedback_respond),'#', + {:focus => 'course_respond', + :onclick => "toggleAndSettingWordsVal($('##{id}'), + $('##{id} textarea'), + '#{l(:label_reply_plural)} #{journal.user.name}: '); + return false;"} %> + <% end %> + + +
      + <% if reply_allow %> +
      + <%= render :partial => 'words/new_respond', :locals => {:journal => journal, :m_reply_id => journal} %> +
      + <% end %> +
      +
      + <%= render :partial => "words/journal_reply", :locals => {:journal => journal } %> +
      +
    • + <% end %> +
    +<% end %> + + \ No newline at end of file diff --git a/app/views/courses/file.html.erb b/app/views/courses/file.html.erb new file mode 100644 index 000000000..3ea345168 --- /dev/null +++ b/app/views/courses/file.html.erb @@ -0,0 +1 @@ +

    文件列表

    \ No newline at end of file diff --git a/app/views/courses/finishcourse.js.erb b/app/views/courses/finishcourse.js.erb new file mode 100644 index 000000000..e67426953 --- /dev/null +++ b/app/views/courses/finishcourse.js.erb @@ -0,0 +1,12 @@ +<% if @save_flag %> +<% if Rails.env.development? %> +console.debug('课程修改成功:结束时间改为<%=Course.find_by_extra(@course.extra).try(:endup_time)%>'); +<% end %> +$('#content-title-top-div').html("<%= j(render partial: 'users/my_course_ex', :locals => {:memberships => @memberships,:user=>@user, +:memberships_doing=>@memberships_doing,:memberships_done=>@memberships_done} )%>") +//$('#finish_course_ <%=@course.id%>').replaceWith("<%= j(render partial: 'courses/set_course_time', :locals => {:course => @course} )%>") +<% else %> +alert('权限不足,设置失败,请在论坛提交问题,等待管理员处理。'); +<% end %> + + diff --git a/app/views/projects/homework.html.erb b/app/views/courses/homework.html.erb similarity index 79% rename from app/views/projects/homework.html.erb rename to app/views/courses/homework.html.erb index 0f3d22130..acbbaeb4b 100644 --- a/app/views/projects/homework.html.erb +++ b/app/views/courses/homework.html.erb @@ -7,8 +7,8 @@
    - <% if User.current.logged? && (User.current.admin? || (!Member.where('user_id = ? and project_id = ?', User.current.id, @project.id).first.nil? && (Member.where('user_id = ? and project_id = ?', User.current.id, @project.id).first.roles&Role.where(id: [3, 4, 7, 9] )).size >0))%> - <%= link_to(l(:label_course_homework_new), {:controller => 'projects', :action => 'new_homework'}, :class => 'icon icon-add') %> + <% if User.current.logged? && (User.current.admin? || (!Member.where('user_id = ? and course_id = ?', User.current.id, @course.id).first.nil? && (Member.where('user_id = ? and course_id = ?', User.current.id, @course.id).first.roles&Role.where(id: [3, 4, 7, 9] )).size >0))%> + <%= link_to(l(:label_course_homework_new), {:controller => 'courses', :action => 'new_homework'}, :class => 'icon icon-add') %> <% end %>
    @@ -18,7 +18,7 @@
    -

    课程: <%= @project.name%>

    +

    课程: <%= @course.name%>

    上传作业

    diff --git a/app/views/courses/index.html.erb b/app/views/courses/index.html.erb new file mode 100644 index 000000000..c29903d78 --- /dev/null +++ b/app/views/courses/index.html.erb @@ -0,0 +1,67 @@ +<% content_for :header_tags do %> + <%= auto_discovery_link_tag(:atom, {:action => 'index', :format => 'atom', :key => User.current.rss_key}) %> +<% end %> + +
    + <%= form_tag(:controller => 'courses', :action => 'search', :method => :get) do %> + + + + + + <% end %> + <% end %> + + + + + + + +
    <%= l(:label_course_practice) %><%= l(:label_user_location) %> : + <% if User.current.logged?%> + <% if User.current.user_extensions.identity == 0 %> + <%= link_to(l(:label_course_new), {:controller => 'courses', :action => 'new'}, + :class => 'icon icon-add') if User.current.allowed_to?(:add_course,nil, :global => true) %> + +
    <%= link_to request.host()+"/course", :controller => 'courses', :action => 'index', :course_type => 1 %> <%=link_to l(:field_homepage), home_path %> > <%=link_to l(:label_course_practice), :controller => 'courses', :action => 'index', :course_type => 1 %>
    + <% end %> +
    +<%= sort_course(@s_type, @school_id)%> + +
    + <%if @courses%> + <%= render_course_hierarchy(@courses)%> + <%end%> +
    + + + +<% if User.current.logged? %> +

    + <%= l(:label_my_course) %> +

    +<% end %> + +<% other_formats_links do |f| %> + <%= f.link_to 'Atom', :url => {:key => User.current.rss_key} %> +<% end %> + +<% content_for :sidebar do %> + <%= form_tag({}, :method => :get) do %> +

    <%= l(:label_project_plural) %>

    + +

    + <%= submit_tag l(:button_apply), :class => 'button-small', :name => nil %> +

    + <% end %> +<% end %> + +<% html_title(l(:label_new_course)) -%> diff --git a/app/views/courses/member.html.erb b/app/views/courses/member.html.erb new file mode 100644 index 000000000..3d3076bcc --- /dev/null +++ b/app/views/courses/member.html.erb @@ -0,0 +1,10 @@ +
    +

    + <%= @subPage_title %> +

    +
    +
    + <%= error_messages_for 'member' %> + <%= render :partial => @render_file, :locals => {:members => @members} %> +
    + diff --git a/app/views/courses/new.html.erb b/app/views/courses/new.html.erb new file mode 100644 index 000000000..81e6ec37a --- /dev/null +++ b/app/views/courses/new.html.erb @@ -0,0 +1,9 @@ +<%= labelled_form_for @course do |f| %> +

    <%=l(:label_course_new)%>

    +
    + <%= render :partial => 'course_form', :locals => { :f => f } %> + <%= submit_tag l(:button_create), :class => "enterprise"%> + + <%= javascript_tag "$('#course_name').focus();" %> +
    +<% end %> diff --git a/app/views/projects/new_homework.html.erb b/app/views/courses/new_homework.html.erb similarity index 82% rename from app/views/projects/new_homework.html.erb rename to app/views/courses/new_homework.html.erb index e1fd553b0..ec25cef0f 100644 --- a/app/views/projects/new_homework.html.erb +++ b/app/views/courses/new_homework.html.erb @@ -1,6 +1,6 @@

    <%=l(:label_course_new_homework)%>

    -<%= labelled_form_for @homework, :url => {:controller => 'bids', :action => 'create_homework'} do |f| %> +<%= labelled_form_for @homework, :url => {:controller => 'bids', :action => 'create_homework',:course_id=>@course.id} do |f| %>
    <%= render :partial => 'homework_form', :locals => { :f => f } %> <%= submit_tag l(:button_create), :class => "enterprise" %> diff --git a/app/views/courses/new_join.js.erb b/app/views/courses/new_join.js.erb new file mode 100644 index 000000000..c0a6f4a50 --- /dev/null +++ b/app/views/courses/new_join.js.erb @@ -0,0 +1,3 @@ +$('#ajax-modal').html('<%= escape_javascript(render :partial => 'projects/new_join', :locals => {:course => @course}) %>'); +showModal('ajax-modal', '400px'); +$('#ajax-modal').addClass('new-watcher'); diff --git a/app/views/courses/search.html.erb b/app/views/courses/search.html.erb new file mode 100644 index 000000000..96f8c227d --- /dev/null +++ b/app/views/courses/search.html.erb @@ -0,0 +1,66 @@ +<% content_for :header_tags do %> +<%= auto_discovery_link_tag(:atom, {:action => 'index', :format => 'atom', :key => User.current.rss_key}) %> +<% end %> +
    + <%= form_tag(:controller => 'courses', :action => 'search', :method => :get) do %> + + + + + + <% end %> + <% end %> + + + + + + + +
    <%= l(:label_course_practice) %><%= l(:label_user_location) %> : + <% if User.current.logged?%> + <% if User.current.user_extensions.identity == 0 %> + <%= link_to(l(:label_course_new), {:controller => 'courses', :action => 'new'}, :class => 'icon icon-add') if User.current.allowed_to?(:add_course, nil, :global => true) %> + +
    <%= link_to "forge.trustie.net/courses", :controller => 'courses', :action => 'index'%> <%=link_to l(:field_homepage), home_path %> > <%=link_to l(:label_course_practice), :controller => 'courses', :action => 'index' %>
    + <% end %> +
    + +<% if @courses.size == 0 %> +<%= render :partial => 'layouts/no_content'%> +<% else %> +
    + <%= render_course_hierarchy(@courses)%> +
    +<% end %> + + + +<% if User.current.logged? %> +

    + <%= l(:label_my_projects) %> +

    +<% end %> + +<% other_formats_links do |f| %> +<%= f.link_to 'Atom', :url => {:key => User.current.rss_key} %> +<% end %> + +<% content_for :sidebar do %> +<%= form_tag({}, :method => :get) do %> +

    <%= l(:label_project_plural) %>

    + +

    + <%= submit_tag l(:button_apply), :class => 'button-small', :name => nil %> +

    +<% end %> +<% end %> + +<% html_title(l(:label_course_all)) -%> diff --git a/app/views/courses/settings.html.erb b/app/views/courses/settings.html.erb new file mode 100644 index 000000000..c2030ffec --- /dev/null +++ b/app/views/courses/settings.html.erb @@ -0,0 +1,3 @@ +

    <%=l(:label_settings)%>

    +<%= render_tabs course_settings_tabs %> +<% html_title(l(:label_settings)) -%> diff --git a/app/views/courses/settings/_members.html.erb b/app/views/courses/settings/_members.html.erb new file mode 100644 index 000000000..0879b7956 --- /dev/null +++ b/app/views/courses/settings/_members.html.erb @@ -0,0 +1,92 @@ +<%= error_messages_for 'member' %> +<% + roles = Role.givable.all + roles = roles[3..5] + members = @course.member_principals.includes(:roles, :principal).all.sort +%> + +
    + <% if members.any? %> + + + + + + + <%= call_hook(:view_projects_settings_members_table_header, :course => @course) %> + + + + <% members.each do |member| %> + <% next if member.new_record? %> + + + + + <% if member.roles.first.to_s == "Manager" %> + + <% else %> + + <% end %> + + <%= call_hook(:view_projects_settings_members_table_header, {:course => @course, :member => member}) %> + + <% end; reset_cycle %> + +
    <%= l(:label_user) %><%= l(:label_role_plural) %>
    <%= link_to_user member.principal %> + + <%= h member.roles.sort.collect(&:to_s).join(', ') %> + + <%= form_for(member, {:as => :membership, :remote => true, :url => membership_path(member), + :method => :put, + :html => {:id => "member-#{member.id}-roles-form", :class => 'hol'}} + ) do |f| %> + +

    + <% roles.each do |role| %> +
    + <% end %>

    + <%= hidden_field_tag 'membership[role_ids][]', '' %> +

    <%= submit_tag l(:button_change), :class => "small" %> + <%= link_to_function l(:button_cancel), + "$('#member-#{member.id}-roles').show(); $('#member-#{member.id}-roles-form').hide(); return false;" + %>

    + <% end %> +
    + <%= link_to_function l(:button_edit), + "$('#member-#{member.id}-roles').hide(); $('#member-#{member.id}-roles-form').show(); return false;", + :class => 'icon icon-edit' %> + <%= delete_link membership_path(member), + :remote => true, + :data => (!User.current.admin? && member.include?(User.current) ? {:confirm => l(:text_own_membership_delete_confirmation)} : {}) if member.deletable? %> +
    + <% else %> +

    <%= l(:label_no_data) %>

    + <% end %> +
    + +
    + <% if roles.any? %> + <%= form_for(@member, {:as => :membership, :url => course_memberships_path(@course), :remote => true, :method => :post}) do |f| %> +
    + <%= l(:label_member_new) %> + +

    <%= label_tag "principal_search", l(:label_principal_search) %><%= text_field_tag 'principal_search', nil %>

    + <%= javascript_tag "observeSearchfield('principal_search', null, '#{ escape_javascript autocomplete_course_memberships_path(@course, :format => 'js') }')" %> + +
    + <%= render_principals_for_new_course_members(@course) %> +
    + +

    <%= l(:label_role_plural) %>: + <% roles.each do |role| %> + + + <% end %>

    + +

    <%= submit_tag l(:button_add), :id => 'member-add-submit' %>

    +
    + <% end %> + <% end %> +
    diff --git a/app/views/courses/show.html.erb b/app/views/courses/show.html.erb new file mode 100644 index 000000000..5a440aff3 --- /dev/null +++ b/app/views/courses/show.html.erb @@ -0,0 +1,109 @@ +<% if @events_by_day.size >0 %> +
    + +

    + <%= l(:label_date_from_to, :start => format_date(@date_to - @days), :end => format_date(@date_to-1)) %> +

    + + <% @events_by_day.keys.sort.reverse.each do |day| %> +
    + <% sort_activity_events(@events_by_day[day]).each do |e, in_group| -%> +
    + + + + + +
    <%= image_tag(url_to_avatar(e.event_author), :class => "avatar")%> + + + + + + + + + + <% if e.event_type == "issue" %> + + <% end %> + +
    + <%= h(e.event_title) if @course.nil? || (e.course != nil && @course.id != e.course.id) %> + + <% if @canShowRealName %> + <%= link_to_user(e.event_author) if e.respond_to?(:event_author) %>(<%= link_to_user(e.event_author,@canShowRealName) if e.respond_to?(:event_author) %>) + <% else %> + <%= link_to_user(e.event_author) if e.respond_to?(:event_author) %> + <% end %> + + <%= l(:label_new_activity) %> + + + <%= link_to "#{eventToLanguageCourse(e.event_type, @course)}: "<< format_activity_title(e.event_title), (e.event_type.eql?("attachment")&&e.container.kind_of?(Course)) ? course_files_path(e.container) : e.event_url %> +
    +

    + <%= h(truncate(strip_tags(e.event_description).gsub(/ /,' '), length: 30, omission:'...')) %> +

    <%= l :label_activity_time %>:  <%= format_activity_day(day) %> <%= format_time(e.event_datetime, false) %> <%= link_to l(:label_find_all_comments), issue_path(e) %> <%= l(:label_comments_count, :count => e.journals.count)%>
    +
    + + <% end %> +
    + + + <% if format_date(day) == format_date(@date_to - @days) %> +

    Test

    +
    + + + + + +
    <%= image_tag(url_to_avatar(@user), :class => "avatar") %> + + + + + +
    <%= link_to (h @user.try(:name)), user_path(@user) if @user %> <%= l(:label_user_create_project) %> <%= link_to @course.name %> !
    <%= l :label_update_time %>: <%= format_time(@course.created_on) %> +
    +
    + <% end %> + <% end -%> + + + + +
    +<% else %> +
    + + + + + +
    <%= image_tag(url_to_avatar(@user), :class => "avatar") %> + + + + + +
    + <% + #判断是否显示真名 + if @canShowRealName + %> + <%= link_to (h @user.try(:name)), user_path(@user) if @user %>(<%= link_to (h @user.try(:realname)), user_path(@user) if @user %>) + <% else %> + <%= link_to (h @user.try(:name)), user_path(@user) if @user %> + <% end %> + <%= l(:label_user_create_project) %> <%= link_to @course.name %> !
    <%= l :label_update_time %>: <%= format_time(@course.created_at) %> +
    +
    +<% end %> + + diff --git a/app/views/files/_course_file.html.erb b/app/views/files/_course_file.html.erb new file mode 100644 index 000000000..c6f872d61 --- /dev/null +++ b/app/views/files/_course_file.html.erb @@ -0,0 +1,71 @@ + +<% attachmenttypes = @course.attachmenttypes %> +<% sufixtypes = @course.contenttypes %> + +<%= t(:label_user_course) %>资源共享区 + +
    + + <%#= link_to(l(:label_attachment_new), 'javascript:void(0);', :onclick=>"$('#file_buttons').slideToggle();", :class => 'icon icon-add') if User.current.allowed_to?(:manage_files, @course) %> +
    +
    + <%= link_to(l(:label_upload_files), 'javascript:void(0);', :class => 'icon m5p5 button_submit', :onclick => "$('#relation_file_div').slideUp();$('#upload_file_div').slideToggle('slow');") if User.current.allowed_to?(:manage_files, @course) %> + <%= link_to(l(:label_relation_files), 'javascript:void(0);', :onclick => "$('#upload_file_div').slideUp();$('#relation_file_div').slideToggle();", :class => 'icon m5p5 button_submit') if User.current.allowed_to?(:manage_files, @course) %> + + <% if attachmenttypes.any? %> +       + + <%= select_tag "attachment_browse", content_tag(:option, l(:attachment_all), :value => '0') +options_from_collection_for_select(attachmenttypes, "id", "typeName"), + :onchange => "course_attachmenttypes_searchex(this.value)" %> + <% end %> + <% if sufixtypes.any? %> +   + + <%= select_tag "attach_sufix_browse", content_tag(:option, l(:attachment_all), :value => '0') +options_for_select(sufixtypes), + :onchange => "course_attachment_contenttypes_searchex(this.value)" %> + <% end %> + + + + +
    + +
    +<%= javascript_tag "observeSearchfield('attach_search', null, '#{ escape_javascript attachments_autocomplete_path(:course_id => @course.id, :format => 'js') }')" %> + + +<% delete_allowed = User.current.allowed_to?(:manage_files, @course) %> + +
    + <%= render :partial => 'course_show_all_attachment' %> +
    + +<% html_title(l(:label_attachment_plural)) -%> \ No newline at end of file diff --git a/app/views/files/_course_new.html.erb b/app/views/files/_course_new.html.erb new file mode 100644 index 000000000..960b2d399 --- /dev/null +++ b/app/views/files/_course_new.html.erb @@ -0,0 +1,41 @@ +

    <%=l(:label_attachment_new)%>

    +<% attachmenttypes = course.attachmenttypes %> +<%= error_messages_for 'attachment' %> +<%= form_tag(course_files_path(course), :multipart => true,:remote => true,:method => :post,:name=>"upload_form", :class => "tabular") do %> +
    +

    + <% if attachmenttypes.any? %> + <%= l(:attachment_type) %> + <%= select_tag "attachment_type", + options_from_collection_for_select(attachmenttypes, "id", + "typeName", 2), {style: 'width:100px'} %> + <% end %> +

    + +

    <%=l(:label_attachment_plural)%><%= render :partial => 'attachments/form' %>

    +
    +<%= submit_tag l(:button_add) %> +<% end %> +
    + + diff --git a/app/views/files/_course_show_all_attachment.html.erb b/app/views/files/_course_show_all_attachment.html.erb new file mode 100644 index 000000000..1a8a8ca65 --- /dev/null +++ b/app/views/files/_course_show_all_attachment.html.erb @@ -0,0 +1,72 @@ +<% selAttachType =@attachtype %> +<% selContentType =@contenttype %> +<% attachmenttypes = @course.attachmenttypes %> +<% delete_allowed = User.current.allowed_to?(:manage_files, @course) %> +<% edit_allowed = User.current.allowed_to?(:manage_files, @course) %> + + + + + + + + + + + <%= sort_header_tag('filename', :caption => l(:field_filename), :scope => "col", :id => "vzebra-adventure") %> + <%#= sort_header_tag('created_on', :caption => l(:label_date), :default_order => 'desc', :scope => "col", :id => "vzebra-comedy") %> + <%= sort_header_tag('size', :caption => l(:field_filesize), :default_order => 'desc', :scope => "col", :id => "vzebra-children") %> + <%= sort_header_tag('attach_type', :caption => l(:attachment_browse), :default_order => 'desc', :scope => "col", :id => "vzebra-attachmenttype") %> + <%= sort_header_tag('content_type', :caption => l(:attachment_sufix_browse), :default_order => 'desc', :scope => "col", :id => "vzebra-contenttype") %> + <%= sort_header_tag('downloads', :caption => l(:field_downloads), :default_order => 'desc', :scope => "col", :id => "vzebra-action") %> + <%= sort_header_tag('operation', :caption => "", :scope => "col", :id => "vzebra-children") %> + + + + + <% @containers.each do |container| %> + <% next if container.attachments.empty? -%> + <% if container.is_a?(Version) -%> + + + + <% end -%> + <% container.attachments.each do |file| %> + "> + + + + + + + + + + + + + <% end -%> + <% reset_cycle %> + <% end -%> + + + + +
    + <%= link_to(h(container), {:controller => 'versions', :action => 'show', :id => container}, :class => "icon icon-package", :style => "color: #666666;") %> +
    <%= link_to_attachment file, :download => true, :title => file.filename+"\n"+file.description.to_s, :style => "width: 230px; overflow: hidden; white-space: nowrap;text-overflow: ellipsis;" %><%= number_to_human_size(file.filesize) %> + <%= file.attachmentstype.typeName %> + + <%= render :partial => 'attachments/course_type_edit', :locals => {:attachmenttypes => attachmenttypes, :attachment => file, :contentype => selContentType} %> + + <%= file.show_suffix_type %><%= file.downloads %> + <%= link_to(image_tag('delete.png'), attachment_path(file), + :data => {:confirm => l(:text_are_you_sure)}, :method => :delete) if delete_allowed %> +
    +
    + <%# @preTags = %w|预设A 预设B 预设C 预设D 预设E 预设Z | %> + <%= render :partial => 'tags/tag', :locals => {:obj => file, :object_flag => "6"} %> +
    +
    + +
    diff --git a/app/views/files/_course_sort_by_attachtypel.html.erb b/app/views/files/_course_sort_by_attachtypel.html.erb new file mode 100644 index 000000000..f73cac072 --- /dev/null +++ b/app/views/files/_course_sort_by_attachtypel.html.erb @@ -0,0 +1,71 @@ +<% selAttachType =@attachtype %> +<% selContentType =@contenttype %> +<% attachmenttypes = @course.attachmenttypes %> +<% delete_allowed = User.current.allowed_to?(:manage_files, @course) %> +<% edit_allowed = User.current.allowed_to?(:manage_files, @course) %> + + + + + + + + + + + <%= sort_header_tag('filename', :caption => l(:field_filename), :scope => "col", :id => "vzebra-adventure") %> + <%#= sort_header_tag('created_on', :caption => l(:label_date), :default_order => 'desc', :scope => "col", :id => "vzebra-comedy") %> + <%= sort_header_tag('size', :caption => l(:field_filesize), :default_order => 'desc', :scope => "col", :id => "vzebra-children") %> + <%= sort_header_tag('attach_type', :caption => l(:attachment_browse), :default_order => 'desc', :scope => "col", :id => "vzebra-attachmenttype") %> + <%= sort_header_tag('content_type', :caption => l(:attachment_sufix_browse), :default_order => 'desc', :scope =>"col", :id=> "vzebra-contenttype")%> + <%= sort_header_tag('downloads', :caption => l(:field_downloads), :default_order => 'desc', :scope => "col", :id => "vzebra-action") %> + <%= sort_header_tag('operation', :caption => "", :scope => "col", :id => "vzebra-children") %> + + + + + <% @containers.each do |container| %> + <% next if container.attachments.empty? -%> + <% container.attachments.each do |file| %> + <% if isTypeOk(file,selAttachType,selContentType) %> + "> + + + + + + + + + + + + + <% end -%> + <% end -%> + <% reset_cycle %> + <% end -%> + + + + +
    <%= link_to_attachment file, :download => true, :title => file.filename+"\n"+file.description.to_s, :style => "width: 230px; overflow: hidden; white-space: nowrap;text-overflow: ellipsis;" %><%= number_to_human_size(file.filesize) %> + <%= file.attachmentstype.typeName %> +   + + <%= render :partial => 'attachments/course_type_edit', :locals => {:attachmenttypes => attachmenttypes, + :attachment => file,:contentype=>selContentType} %> + + <%= file.show_suffix_type %><%= file.downloads %> + <%= link_to(image_tag('delete.png'), attachment_path(file), + :data => {:confirm => l(:text_are_you_sure)}, :method => :delete) if delete_allowed %> +
    +
    + <%# @preTags = %w|预设A 预设B 预设C 预设D 预设E 预设Z | %> + <%= render :partial => 'tags/tag', :locals => {:obj => file, :object_flag => "6"} %> +
    +
    + +
    + diff --git a/app/views/files/_new.html.erb b/app/views/files/_new.html.erb index a1cfb37e2..af65bbcf4 100644 --- a/app/views/files/_new.html.erb +++ b/app/views/files/_new.html.erb @@ -2,7 +2,7 @@ <% versions = project.versions.sort %> <% attachmenttypes = project.attachmenttypes %> <%= error_messages_for 'attachment' %> -<%= form_tag(project_files_path(project), :multipart => true,:remote => false,:method => :post,:name=>"upload_form", :class => "tabular") do %> +<%= form_tag(project_files_path(project), :multipart => true,:remote => true,:method => :post,:name=>"upload_form", :class => "tabular") do %>

    @@ -13,6 +13,8 @@ <%= select_tag "version_id", content_tag('option', '') + options_from_collection_for_select(versions, "id", "name"), {style: 'width:100px'} %> + <% else %> + <% end %> <% if attachmenttypes.any? %> diff --git a/app/views/files/_project_file.html.erb b/app/views/files/_project_file.html.erb new file mode 100644 index 000000000..1212db052 --- /dev/null +++ b/app/views/files/_project_file.html.erb @@ -0,0 +1,71 @@ + +<% attachmenttypes = @project.attachmenttypes %> +<% sufixtypes = @project.contenttypes %> + +<%= (@project.project_type == 1) ? t(:label_user_course) : t(:label_project) %>资源共享区 + +
    + + <%#= link_to(l(:label_attachment_new), 'javascript:void(0);', :onclick=>"$('#file_buttons').slideToggle();", :class => 'icon icon-add') if User.current.allowed_to?(:manage_files, @project) %> +
    +
    + <%= link_to(l(:label_upload_files), 'javascript:void(0);', :class => 'icon m5p5 button_submit', :onclick => "$('#relation_file_div').slideUp();$('#upload_file_div').slideToggle('slow');") if User.current.allowed_to?(:manage_files, @project) %> + <%= link_to(l(:label_relation_files), 'javascript:void(0);', :onclick => "$('#upload_file_div').slideUp();$('#relation_file_div').slideToggle();", :class => 'icon m5p5 button_submit') if User.current.allowed_to?(:manage_files, @project) %> + + <% if attachmenttypes.any? %> +       + + <%= select_tag "attachment_browse", content_tag(:option, l(:attachment_all), :value => '0') +options_from_collection_for_select(attachmenttypes, "id", "typeName"), + :onchange => "attachmenttypes_searchex(this.value)" %> + <% end %> + <% if sufixtypes.any? %> +   + + <%= select_tag "attach_sufix_browse", content_tag(:option, l(:attachment_all), :value => '0') +options_for_select(sufixtypes), + :onchange => "attachment_contenttypes_searchex(this.value)" %> + <% end %> + + + + +
    + +
    +<%= javascript_tag "observeSearchfield('attach_search', null, '#{ escape_javascript attachments_autocomplete_path(:project_id => @project.id, :format => 'js') }')" %> + + +<% delete_allowed = User.current.allowed_to?(:manage_files, @project) %> + +
    + <%= render :partial => 'show_all_attachment' %> +
    + +<% html_title(l(:label_attachment_plural)) -%> \ No newline at end of file diff --git a/app/views/files/create.js.erb b/app/views/files/create.js.erb new file mode 100644 index 000000000..0eca9c1ed --- /dev/null +++ b/app/views/files/create.js.erb @@ -0,0 +1,32 @@ +<%if @addTag%> +<% if @obj_flag == '3'%> + +$('#tags_show_issue').html('<%= escape_javascript(render :partial => 'tags/tag_name', + :locals => {:obj => @obj,:non_list_all => false,:object_flag => @obj_flag}) %>'); +//$('#put-tag-form-issue').hide(); +$('#name-issue').val(""); +<% elsif @obj_flag == '6'%> +$("#tags_show-<%=@obj.class%>-<%=@obj.id%>").empty(); +$("#tags_show-<%=@obj.class%>-<%=@obj.id%>").html('<%= escape_javascript(render :partial => 'tags/tag_name', + :locals => {:obj => @obj,:non_list_all => false,:object_flag => @obj_flag}) %>'); +$("#put-tag-form- <%=@obj.class%>- <%=@obj.id%>").hide(); +$("#put-tag-form-<%=@obj.class%>-<%=@obj.id%> #name").val(""); +<% else %> + +$('#tags_show').html('<%= escape_javascript(render :partial => 'tags/tag_name', + :locals => {:obj => @obj,:non_list_all => false,:object_flag => @obj_flag}) %>'); +$('#tags_show').html('<%=render_attachments_tag_save(@project, nil)%>'); +$('#put-tag-form #name').val(""); +//$('#put-tag-form').hide(); +<% end %> +<%else%> +$("#attachments_fields").children().remove(); +$("#upload_file_count").text("未上传文件"); +$('#upload_file_div').slideToggle('slow'); +<%if @project%> +$("#all_browse_div").html('<%= j(render partial: "show_all_attachment")%>'); +<%elsif @course%> +$("#all_browse_div").html('<%= j(render partial: "course_show_all_attachment")%>'); +<%end%> +<% end %> + diff --git a/app/views/files/getattachtype.js.erb b/app/views/files/getattachtype.js.erb index 3bc9863b2..88722073f 100644 --- a/app/views/files/getattachtype.js.erb +++ b/app/views/files/getattachtype.js.erb @@ -1,5 +1,13 @@ <% if @attachtype==0 && @contenttype=='0' %> +<% if @project%> $("#all_browse_div").html('<%= j(render partial: "show_all_attachment")%>'); -<%else%> -$("#all_browse_div").html('<%= j(render partial: "sort_by_attachtypel")%>'); +<% elsif @course%> +$("#all_browse_div").html('<%= j(render partial: "course_show_all_attachment")%>'); +<%end%> +<%else%> +<% if @project%> +$("#all_browse_div").html('<%= j(render partial: "sort_by_attachtypel")%>') +<% elsif @course%> +$("#all_browse_div").html('<%= j(render partial: "course_sort_by_attachtypel")%>') +<%end%>; <%end%> diff --git a/app/views/files/index.html.erb b/app/views/files/index.html.erb index 9c1eee9d8..b086b90db 100644 --- a/app/views/files/index.html.erb +++ b/app/views/files/index.html.erb @@ -1,75 +1,10 @@ -<% attachmenttypes = @project.attachmenttypes %> -<% sufixtypes = @project.contenttypes %> +<% if @isproject %> + <%= render :partial => 'project_file', locals: {project: @project} %> +<% else %> + <%= render :partial => 'course_file', locals: {course: @course} %> +<% end %> -<%= (@project.project_type == 1) ? t(:label_user_course) : t(:label_project) %>资源共享区 - -
    - - <%#= link_to(l(:label_attachment_new), 'javascript:void(0);', :onclick=>"$('#file_buttons').slideToggle();", :class => 'icon icon-add') if User.current.allowed_to?(:manage_files, @project) %> -
    -
    - <%#= link_to('上传文件', new_project_file_path(@project), :class => 'icon m5p5 button_submit') if User.current.allowed_to?(:manage_files, @project) %> - <%= link_to(l(:label_upload_files), 'javascript:void(0);', :class => 'icon m5p5 button_submit', :onclick => "$('#relation_file_div').slideUp();$('#upload_file_div').slideToggle('slow');") if User.current.allowed_to?(:manage_files, @project) %> - <%= link_to(l(:label_relation_files), 'javascript:void(0);', :onclick => "$('#upload_file_div').slideUp();$('#relation_file_div').slideToggle();", :class => 'icon m5p5 button_submit') if User.current.allowed_to?(:manage_files, @project) %> - - <% if attachmenttypes.any? %> -       - - <%= select_tag "attachment_browse", content_tag(:option, l(:attachment_all), :value => '0') +options_from_collection_for_select(attachmenttypes, "id", "typeName"), - :onchange => "attachmenttypes_searchex(this.value)" %> - <% end %> - <% if sufixtypes.any? %> -   - - <%= select_tag "attach_sufix_browse", content_tag(:option, l(:attachment_all), :value => '0') +options_for_select(sufixtypes), - :onchange => "attachment_contenttypes_searchex(this.value)" %> - <% end %> - - - - -
    - -
    -<%= javascript_tag "observeSearchfield('attach_search', null, '#{ escape_javascript attachments_autocomplete_path(:project_id => @project.id, :format => 'js') }')" %> - - -<% delete_allowed = User.current.allowed_to?(:manage_files, @project) %> - -
    - <%= render :partial => 'show_all_attachment' %> -
    - -<% html_title(l(:label_attachment_plural)) -%> diff --git a/app/views/homework_attach/_comprehensive_evaluation.html.erb b/app/views/homework_attach/_comprehensive_evaluation.html.erb index 08db30542..b9ae1b496 100644 --- a/app/views/homework_attach/_comprehensive_evaluation.html.erb +++ b/app/views/homework_attach/_comprehensive_evaluation.html.erb @@ -1,23 +1,9 @@ <% is_teacher = is_course_teacher User.current,homework.bid.courses.first %> <% if comprehensive_evaluation != nil && comprehensive_evaluation.count > 0 %> - <% stars = homework.rates(:quality).where("rater_id = #{comprehensive_evaluation.first.user.id}").select("stars").first %>
    作业综评: - -
    - <% if stars != nil %> -
    - <% else %> -
    - <% end %> -
    -
    -
    -
    -
    + <%= render :partial => 'show_score', locals: {:stars => teaher_score} %>
    <%= comprehensive_evaluation.first.notes%>
    @@ -31,7 +17,7 @@
    <%= render :partial => 'evaluation', :locals => {:homework => homework} %>
    - <%= render :partial => 'addjour', :locals => {:homework_attach => homework, :sta => 0,:is_comprehensive_evaluation => 1} %> + <%= render :partial => 'evaluation_add_jour', :locals => {:homework_attach => homework, :sta => 0,:is_comprehensive_evaluation => 1} %>
    <% else %> diff --git a/app/views/homework_attach/_evaluation_add_jour.html.erb b/app/views/homework_attach/_evaluation_add_jour.html.erb new file mode 100644 index 000000000..aacbf4c12 --- /dev/null +++ b/app/views/homework_attach/_evaluation_add_jour.html.erb @@ -0,0 +1,93 @@ + + + + +<%= form_for('new_form', :method => :post, + :url => {:controller => 'homework_attach', + :action => 'comprehensive_evaluation_jour', + :jour_id => homework_attach.id, + :is_comprehensive_evaluation => is_comprehensive_evaluation, + :sta => sta}) do |f|%> + +
    + <%= render :partial => 'words/pre_show', :locals => {:content => @content} %> +
    + + <% if User.current.logged? %> +

    + + + +
    <%= f.text_area 'user_message', :rows => 3, :cols => 65, :value => "#{l(:label_leave_a_message)}", + :onfocus => "clearInfo('new_form_user_message','#{l(:label_leave_a_message)}')", + :onblur => "showInfo('new_form_user_message','#{l(:label_leave_a_message)}')", + :style => "resize: none;", :class => 'noline'%>
    + <%= f.text_field :reference_user_id, :style=>"display:none"%> + + + + +
    <%= submit_tag l(:button_leave_meassge), + :name => nil , :class => "enterprise", + :onmouseout => "this.style.backgroundPosition = 'left top'", + :onmouseover => "this.style.backgroundPosition = 'left -31px'"%> + <%= submit_tag l(:button_clear), :name => nil, :class => "enterprise", + :onclick => "clearMessage('new_form_user_message');", + :onmouseout => "this.style.backgroundPosition = 'left top'", + :onmouseover => "this.style.backgroundPosition = 'left -31px'" %>
    + <% else %> +

    + <%= l(:label_user_login_tips) %> + <%= link_to l(:label_user_login_new), signin_path %> +
    + <% end %> +<% end %> diff --git a/app/views/homework_attach/_show_score.html.erb b/app/views/homework_attach/_show_score.html.erb new file mode 100644 index 000000000..7c2403e10 --- /dev/null +++ b/app/views/homework_attach/_show_score.html.erb @@ -0,0 +1,14 @@ + +
    + <% if stars != nil %> +
    + <% else %> +
    + <% end %> +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/app/views/homework_attach/addjours.js.erb b/app/views/homework_attach/addjours.js.erb index ed5887a7f..e16609b68 100644 --- a/app/views/homework_attach/addjours.js.erb +++ b/app/views/homework_attach/addjours.js.erb @@ -1,6 +1,6 @@ <% if @add_jour.is_comprehensive_evaluation == 1 %> $('#comprehensive_evaluation').html('<%= escape_javascript(render(:partial => 'comprehensive_evaluation', - :locals => {:comprehensive_evaluation => @comprehensive_evaluation,:homework => @homework} )) %>'); + :locals => {:comprehensive_evaluation => @comprehensive_evaluation,:homework => @homework,:teaher_score => @teaher_score} )) %>'); <% else %> $('#message').html('<%= escape_javascript(render(:partial => 'showjour', :locals => {:jour =>@jour, :state => false,:homework => @homework} )) %>'); $('#pre_show').html('<%= escape_javascript(render(:partial => 'pre_show', :locals => {:content => nil})) %>'); diff --git a/app/views/homework_attach/edit.html.erb b/app/views/homework_attach/edit.html.erb index f7104840b..985ccfdfc 100644 --- a/app/views/homework_attach/edit.html.erb +++ b/app/views/homework_attach/edit.html.erb @@ -1,10 +1,10 @@ @@ -16,9 +16,9 @@
    <%= link_to request.host()+"/courses", :controller => 'projects', :action => 'course'%>

    <%=link_to "主页", home_path %> > <%=link_to l(:label_course_practice), :controller => 'projects', :action => 'course' %> > - <%= link_to(@homework.bid.courses.first.name.to_s, homework_project_path(@homework.bid.courses.first)) if @homework.bid.courses.first%> > +

    <%= link_to request.host()+"/courses", :controller => 'courses', :action => 'index'%>

    <%=link_to "主页", home_path %> > <%=link_to l(:label_course_practice), :controller => 'courses', :action => 'index' %> > + <%= link_to(@homework.bid.courses.first.name.to_s, homework_course_path(@homework.bid.courses.first)) if @homework.bid.courses.first%> > <%=link_to(@homework.bid.name, respond_path(@homework.bid)) %> > <%= link_to "修改作业",edit_homework_attach_path(@homework)%>

    @@ -42,11 +42,22 @@
    <%= form_for(@homework) do |f|%>

    - 标 题: + 标      题:  <%= f.text_field :name, :required => true, :name => "homework_name", :size => 60, :style => "width:490px;"%>

    - 描 述: + 提交项目: + <% if @homework.project.nil? %> + <%= f.select :project_id, options_for_select(user_projects_option),:name => "project_id", :required => true%> + <% else %> + <%= f.select :project_id, options_for_select(user_projects_option,@homework.project.id),:name => "project_id", :required => true%> + <% end %> + + <%= link_to '创建项目', new_project_path(course: 0, project_type: 0), :target => '_blank' %> +

    提交项目可以为空

    +

    +

    + 描      述:  <%= f.text_area :description, :rows => 8, :name => "homework_description", :class => 'wiki-edit', :style => "font-size:small;width:490px;margin-left:10px;" %> diff --git a/app/views/homework_attach/new.html.erb b/app/views/homework_attach/new.html.erb index 618fc15a1..9c594835a 100644 --- a/app/views/homework_attach/new.html.erb +++ b/app/views/homework_attach/new.html.erb @@ -6,9 +6,9 @@ - <%= link_to request.host()+"/courses", :controller => 'projects', :action => 'course'%> -

    <%=link_to "主页", home_path %> > <%=link_to l(:label_course_practice), :controller => 'projects', :action => 'course' %> > - <%= link_to(@bid.courses.first.name.to_s, homework_project_path(@bid.courses.first)) if @bid.courses.first%> > + <%= link_to request.host()+"/courses", :controller => 'courses', :action => 'index'%> +

    <%=link_to "主页", home_path %> > <%=link_to l(:label_course_practice), :controller => 'courses', :action => 'index' %> > + <%= link_to(@bid.courses.first.name.to_s, homework_course_path(@bid.courses.first)) if @bid.courses.first%> > <%=link_to(@bid.name, respond_path(@bid)) %> > <%= link_to "创建作业", new_homework_attach_path(@bid)%>

    @@ -23,11 +23,17 @@ :bid_id => @bid }) do |f|%>

    - 标 题: + 标      题: <%= f.text_field "name", :required => true, :size => 60, :style => "width:490px;" %>

    - 描 述: + 提交项目: + <%= f.select :project_id, options_for_select(user_projects_option),:name => "project_id", :required => true, :style => "width:490px;"%> + <%= link_to '创建项目', new_project_path(course: 0, project_type: 0), :target => '_blank' %> +

    提交项目可以为空

    +

    +

    + 描      述: <%= f.text_area "description", :rows => 8, :class => 'wiki-edit', :style => "font-size:small;width:490px;margin-left:10px;" %> diff --git a/app/views/homework_attach/show.html.erb b/app/views/homework_attach/show.html.erb index 4ab6141dc..87dcf60cb 100644 --- a/app/views/homework_attach/show.html.erb +++ b/app/views/homework_attach/show.html.erb @@ -24,7 +24,7 @@ 发布人员:<%= link_to @homework.user, user_path(@homework.user)%> - 所属任务:<%= link_to(@homework.bid.name, project_for_bid_path(@homework.bid))%> + 所属任务:<%= link_to(@homework.bid.name, course_for_bid_path(@homework.bid))%> @@ -49,7 +49,7 @@ 平均评分: - <%= rating_for @homework, :static => true, dimension: :quality, class: 'rateable div_inline' %> + <%= render :partial => 'show_score', :locals => {:stars => @totle_score} %> 发布时间:<%=format_time @homework.created_at %> @@ -110,17 +110,12 @@

    - <% score = @homework.average(:quality).try(:avg).try(:round, 2).to_s %>
    最终得分
    - <% if score == "" %> - 0分 - <% else %> - <%= score %>分 - <% end %> + <%= @totle_score %>分
    - <%= rating_for @homework, :static => true, dimension: :quality, class: 'rateable div_inline' %> + <%= render :partial => 'show_score', :locals => {:stars => @totle_score} %>
    @@ -137,7 +132,7 @@
    - <%= render :partial => 'comprehensive_evaluation', :locals => {:comprehensive_evaluation => @comprehensive_evaluation,:homework => @homework} %> + <%= render :partial => 'comprehensive_evaluation', :locals => {:comprehensive_evaluation => @comprehensive_evaluation,:homework => @homework, :teaher_score => @teaher_score} %>
    diff --git a/app/views/issues/_list.html.erb b/app/views/issues/_list.html.erb index 2b17b4fb1..dd3487258 100644 --- a/app/views/issues/_list.html.erb +++ b/app/views/issues/_list.html.erb @@ -10,7 +10,7 @@ <% column_content = ( query.inline_columns.map {|column| "#{column_content_new(column, issue)}"}) %> - <%= render :partial => "/praise_tread/praise_tread",:locals => {:obj => issue,:show_flag => true,:user_id =>User.current.id}%> + <%= render :partial => "/praise_tread/praise_tread",:locals => {:obj => issue,:show_flag => true,:user_id =>User.current.id,:horizontal => false}%> <% if issue.tracker_id == 1 %> <%= image_tag("/images/task.png", :class => "img-tag-issues") %> diff --git a/app/views/issues/show.html.erb b/app/views/issues/show.html.erb index d261957c6..89fc862d0 100644 --- a/app/views/issues/show.html.erb +++ b/app/views/issues/show.html.erb @@ -33,7 +33,7 @@ - <%= render :partial => "/praise_tread/praise_tread",:locals => {:obj => @issue,:show_flag => true,:user_id =>User.current.id}%> + <%= render :partial => "/praise_tread/praise_tread",:locals => {:obj => @issue,:show_flag => true,:user_id =>User.current.id,:horizontal => false}%>

    @@ -147,7 +147,7 @@ end %>

    <% if @issue.editable? %> - \ No newline at end of file diff --git a/app/views/layouts/base_bids.html.erb b/app/views/layouts/base_bids.html.erb index f82a5bd2d..075ee847f 100644 --- a/app/views/layouts/base_bids.html.erb +++ b/app/views/layouts/base_bids.html.erb @@ -68,7 +68,7 @@ - + <% if User.current.login? %> @@ -143,7 +143,7 @@ <% if @bid.watcher_users.size>0 %> <% for user in @bid.watcher_users%> - <%= image_tag(url_to_avatar(user), :class => "avatar", :title => user.name ) %> + <%= link_to image_tag(url_to_avatar(user), :class => "avatar", :title => user.name ),user_path(user) %> <% end %> <% else %>

    <%= l(:label_project_no_follow) %>

    @@ -164,8 +164,8 @@
    <%= h @bid.name %><%= link_to @bid.name,bid_path %>
    <% if @bid.projects.size>0 %> - <% for project in @bid.projects%> - <%= image_tag(url_to_avatar(project), :class => "avatar", :title => project.name) %> + <% for project in @bid.projects%> + <%= link_to image_tag(url_to_avatar(project), :class => "avatar", :title => project.name),project_path(project) %> <% end%> <% else %>

    <%= l(:label_no_bid_project) %>

    diff --git a/app/views/layouts/base_courses.html.erb b/app/views/layouts/base_courses.html.erb index dfdf0a102..ac5cc104d 100644 --- a/app/views/layouts/base_courses.html.erb +++ b/app/views/layouts/base_courses.html.erb @@ -26,71 +26,60 @@
    - <% @project = Project.find_by_id(@project.id) %> - <% @course = Course.find_by_extra(@project.identifier) %> - + + > <%= link_to l(:label_course_practice), :controller => 'courses', :action => 'index' %> + > <%= link_to @course.name, nil %>

    高校课程实践社区 <%= l(:label_user_location) %> :
    <%= link_to request.host()+"/course", :controller => 'projects', :action => 'course' %><%= link_to request.host()+"/course", :controller => 'courses', :action => 'index' %>

    <%= link_to "主页", home_path %> - > <%= link_to l(:label_course_practice), :controller => 'projects', :action => 'course' %> - > <%= link_to @project.name, nil %>

    - + -
    - -
    -
      -
    • - <%= link_to l(:label_question_student), {:controller => 'bids', :action => 'show' },:class => link_class(:respond)%> -
    • - <% if User.current.member_of? @bid.courses.first%> -
    • - <% if User.current.logged? && @bid.courses.first && (!Member.where('user_id = ? and project_id = ?', User.current.id, @bid.courses.first.id).first.nil? && (Member.where('user_id = ? and project_id = ?', User.current.id, @bid.courses.first.id).first.roles&Role.where('id = ? or id = ? or id =?',5, 10, 7)).size >0) %> - <%= link_to l(:label_homework_commit), {:controller => 'bids', :action => 'show_project' },:class => link_class(:project)%> - <% else %> - <%= link_to l(:label_homework_info), {:controller => 'bids', :action => 'show_project' },:class => link_class(:project)%> - - <% end %> -
    • +
      +
      + <%= l(:label_commit_homework) %> +
      +
      + + + + +
      + <% if @bid.homework_type == 1 %> + <% if @bid.homeworks.size>0 %> + <% for homework in @bid.homeworks.eager_load(:user) %> + <%= link_to image_tag(url_to_avatar(homework.user), :class => "avatar", :title => homework.user.name), user_path(homework.user), :class => "avatar" %> + <% end %> + <% else %> +

      + <%= l(:label_no_course_project) %> +

      <% end %> - - - + <% else %> + <% if @bid.courses.size>0 %> + <% for course in @bid.courses %> + <%= link_to image_tag(url_to_avatar(course), :class => "avatar", :title => course.name), course_path(course), :class => "avatar" %> + <% end %> + <% else %> +

      + <%= l(:label_no_course_project) %> +

      + <% end %> + <% end %>
      +
      +
    +
    +
    +
    + + +
    - <%= yield %> - <%= call_hook :view_layouts_base_content %> -
    -
    - <%= render :partial => 'layouts/base_footer'%> - - - +
    +
      +
    • + <%= link_to l(:label_question_student), {:controller => 'bids', :action => 'show'}, :class => link_class(:respond) %> +
    • + <% if User.current.member_of_course? course %> +
    • + <% if User.current.logged? && course && (!Member.where('user_id = ? and course_id = ?', User.current.id, course.id).first.nil? && (Member.where('user_id = ? and course_id = ?', User.current.id, course.id).first.roles&Role.where('id = ? or id = ? or id =?', 5, 10, 7)).size >0) %> + <%= link_to l(:label_homework_commit), course_for_bid_path, :class => link_class(:course) %> + <% else %> + <%= link_to l(:label_homework_info), course_for_bid_path, :class => link_class(:course) %> + <% end %> +
    • + <% end %> + + +
    +
    - - + <%= yield %> + <%= call_hook :view_layouts_base_content %> +
    + + <%= render :partial => 'layouts/base_footer' %> + + + - - <%= call_hook :view_layouts_base_body_bottom %> + + + + + <%= call_hook :view_layouts_base_body_bottom %> + <% end %> diff --git a/app/views/layouts/base_newcontest.html.erb b/app/views/layouts/base_newcontest.html.erb index 91120feb8..a14f25cd6 100644 --- a/app/views/layouts/base_newcontest.html.erb +++ b/app/views/layouts/base_newcontest.html.erb @@ -62,7 +62,7 @@
    - + <% if User.current.login? %> diff --git a/app/views/layouts/base_projects.html.erb b/app/views/layouts/base_projects.html.erb index 433e8aae6..bd15b128e 100644 --- a/app/views/layouts/base_projects.html.erb +++ b/app/views/layouts/base_projects.html.erb @@ -57,7 +57,7 @@ @@ -166,12 +183,13 @@ --> + <% unless @user.user_extensions.nil? %> <% unless @user.user_extensions.identity == 2 %> diff --git a/app/views/members/autocomplete.js.erb b/app/views/members/autocomplete.js.erb index ba98983d3..e7a52f7f3 100644 --- a/app/views/members/autocomplete.js.erb +++ b/app/views/members/autocomplete.js.erb @@ -1 +1,5 @@ + <% if @project%> $('#principals_for_new_member').html('<%= escape_javascript(render_principals_for_new_members(@project)) %>'); + <% elsif @course%> + $('#principals_for_new_member').html('<%= escape_javascript(render_principals_for_new_course_members(@course)) %>'); + <%end%> diff --git a/app/views/members/create.js.erb b/app/views/members/create.js.erb index 3607ce448..3b01980ad 100644 --- a/app/views/members/create.js.erb +++ b/app/views/members/create.js.erb @@ -1,4 +1,9 @@ +<%if @project%> $('#tab-content-members').html('<%= escape_javascript(render :partial => 'projects/settings/members') %>'); +<%elsif @course%> +$('#tab-content-members').html('<%= escape_javascript(render :partial => 'courses/settings/members') %>'); +<%end%> + hideOnLoad(); <%if !@applied_members%> diff --git a/app/views/members/destroy.js.erb b/app/views/members/destroy.js.erb index 17beff44c..2d0d26271 100644 --- a/app/views/members/destroy.js.erb +++ b/app/views/members/destroy.js.erb @@ -1,2 +1,6 @@ + <%if @project%> $('#tab-content-members').html('<%= escape_javascript(render :partial => 'projects/settings/members') %>'); + <%elsif @course%> + $('#tab-content-members').html('<%= escape_javascript(render :partial => 'courses/settings/members') %>'); + <%end%> hideOnLoad(); diff --git a/app/views/members/update.js.erb b/app/views/members/update.js.erb index 245828aac..9f6709701 100644 --- a/app/views/members/update.js.erb +++ b/app/views/members/update.js.erb @@ -1,3 +1,7 @@ +<%if @project%> $('#tab-content-members').html('<%= escape_javascript(render :partial => 'projects/settings/members') %>'); +<%elsif @course%> +$('#tab-content-members').html('<%= escape_javascript(render :partial => 'courses/settings/members') %>'); +<%end%> hideOnLoad(); $("#member-<%= @member.id %>").effect("highlight"); diff --git a/app/views/memos/show.html.erb b/app/views/memos/show.html.erb index 5f1fcdc65..830f18d85 100644 --- a/app/views/memos/show.html.erb +++ b/app/views/memos/show.html.erb @@ -1,4 +1,6 @@
    + + <%= render :partial => "/praise_tread/praise_tread",:locals => {:obj => @memo,:show_flag => true,:user_id =>User.current.id,:horizontal => true}%>
    <%= link_to image_tag(url_to_avatar(@memo.author), :class => "avatar"), user_path(@memo.author) %>

    <%=link_to @memo.author.name, user_path(@memo.author) %>

    @@ -46,15 +48,17 @@
    <%= label_tag l(:field_subject) %>: <%=h @memo.subject %>
    - <%= raw @memo.content %> + <%=h sanitize(@memo.content.html_safe) %>

    <% if @memo.attachments.any?%> <% options = {:author => true, :deletable => @memo.deleted_attach_able_by?(User.current) } %> <%= render :partial => 'attachments/links', :locals => {:attachments => @memo.attachments, :options => options} %> <% end %>

    +
    -
    <%= authoring @memo.created_at, @memo.author.name %>
    + +
    <%= authoring @memo.created_at, @memo.author %>

    @@ -119,7 +123,8 @@
    - + +
    <%= h @contest.name %><%= link_to @contest.name, show_contest_contest_path(@contest) %>
    <%= image_tag(url_to_avatar(@project), :class => 'avatar2') %>
    - <%= @project.name %> + <%= link_to @project.name, project_path(@project)%>
    diff --git a/app/views/layouts/base_users.html.erb b/app/views/layouts/base_users.html.erb index 99971e0f3..0f7c273f1 100644 --- a/app/views/layouts/base_users.html.erb +++ b/app/views/layouts/base_users.html.erb @@ -16,7 +16,25 @@ <%= call_hook :view_layouts_base_html_head %> <%= yield :header_tags -%> + + +
    @@ -56,7 +74,9 @@
    - @@ -92,18 +112,15 @@ <% comments_score = comments_count * 0.1 %> <% finall_influence_score = news_score + wiki_contents_score + comments_score %> <% finall_user_score = finall_messages_score + finall_user_project_score + finall_activity_score + finall_influence_score %> - + + - - +
    <%= h (@user.name) %> + + + <%= link_to h (@user.name) %> <%= image_tag(gender_avatar_uri(@user), weight:"25px", height:"25px") if (@user.user_extensions && (@user.user_extensions.identity != 2) )%>
    - <%= l(:label_user_grade)%>: - <%= link_to(format("%.2f" , finall_user_score).to_f, {:controller => 'users', - :action => 'show_score', - :remote => true, - :id => @user.id - }, :style => 'color :#E8770D;') %> +
    + <%= render :partial => 'users/user_score', :locals => {:user => @user}%> +
    <%= l(:field_occupation) %>: <% unless @user.user_extensions.school.nil? %> - <%= @user.user_extensions.school.name %> + <%= link_to @user.user_extensions.school.name, options={:controller => 'welcome',:action => 'course',:school_id => @user.user_extensions.school.id}, html_options={:method => 'get'} %> <% end %>
    <%= authoring reply.created_at, reply.author.name %><%= authoring reply.created_at, reply.author %>
    diff --git a/app/views/messages/_course_show.html.erb b/app/views/messages/_course_show.html.erb new file mode 100644 index 000000000..243406a3c --- /dev/null +++ b/app/views/messages/_course_show.html.erb @@ -0,0 +1,200 @@ + + +
    + + <%= render :partial => "/praise_tread/praise_tread",:locals => {:obj => @topic,:show_flag => true,:user_id =>User.current.id,:horizontal => true}%> +
    + <%= watcher_link(@topic, User.current) %> + <%= link_to( + l(:button_quote), + {:action => 'quote', :id => @topic}, + :remote => true, + :method => 'get', + :class => 'icon icon-comment', + :remote => true) if !@topic.locked? && authorize_for('messages', 'reply') %> + <%= link_to( + l(:button_edit), + {:action => 'edit', :id => @topic}, + :class => 'icon icon-edit' + ) if @message.editable_by?(User.current) %> + <%= link_to( + l(:button_delete), + {:action => 'destroy', :id => @topic}, + :method => :post, + :data => {:confirm => l(:text_are_you_sure)}, + :class => 'icon icon-del' + ) if @message.destroyable_by?(User.current) %> +
    + +
    +
    + <%= link_to image_tag(url_to_avatar(@topic.author), :class => "avatar"), user_path(@topic.author) %> +
    +

    + <%= link_to @topic.author, user_path(@topic.author) %> +

    +
    +
    +
    + <% if @project %> + <%= label_tag l(:field_subject) %>: <%= link_to @topic.subject, project_boards_path(@topic.project) %> + <% elsif @course %> + <%= label_tag l(:field_subject) %>: <%= link_to @topic.subject, course_boards_path(@topic.course) %> + <% end %> +
    +
    + <%= textilizable(@topic, :content) %> + <%= link_to_attachments @topic, :author => false %> +
    +
    +
    <%= authoring @topic.created_on, @topic.author %>
    + + +
    <%= toggle_link l(:button_reply), "reply", :focus => 'message_content' %>
    +
    + + + + +
    +
    +
    + +<% unless @replies.empty? %> +
    +
    +
    +
    +

    <%= l(:label_reply_plural) %> (<%= @reply_count %>)

    + <% reply_count = 0 %> + <% @replies.each do |message| %> +
    "> + + + + + + + + + + + + + + +
    <%= link_to image_tag(url_to_avatar(message.author), :class => "avatar"), user_path(message.author) %> +
    + <%= link_to( + "引用", + {:action => 'quote', :id => message}, + :remote => true, + :method => 'get', + :title => l(:button_quote)) if !@topic.locked? && authorize_for('messages', 'reply') %> + <%= link_to( + #image_tag('edit.png'), + "编辑", + {:action => 'edit', :id => message}, + :title => l(:button_edit) + ) if message.editable_by?(User.current) %> + <%= link_to( + #image_tag('delete.png'), + "删除", + {:action => 'destroy', :id => message}, + :method => :post, + :data => {:confirm => l(:text_are_you_sure)}, + :title => l(:button_delete) + ) if message.destroyable_by?(User.current) %> +
    +
    + <%= textilizable message, :content, :attachments => message.attachments %> +
    + <%= link_to_attachments message, :author => false %>
    <%= authoring message.created_on, message.author %>
    +
    + + <% end %> + +<% end %> + + + + +<% if !@topic.locked? && authorize_for_course('messages', 'reply') %> + +<% end %> + +<% html_title @topic.subject %> + + \ No newline at end of file diff --git a/app/views/messages/_form.html.erb b/app/views/messages/_form.html.erb index 04940dbdc..931b472c7 100644 --- a/app/views/messages/_form.html.erb +++ b/app/views/messages/_form.html.erb @@ -19,7 +19,12 @@ <% if !replying && !@message.new_record? && @message.safe_attribute?('board_id') %>


    - <%= f.select :board_id, boards_options_for_select(@message.project.boards) %>

    + <%# modify by nwb%> + <% if @message.project %> + <%= f.select :board_id, boards_options_for_select(@message.project.boards) %>

    + <% elsif @message.course %> + <%= f.select :board_id, boards_options_for_select(@message.course.boards) %>

    + <% end %> <% end %>

    diff --git a/app/views/messages/_project_show.html.erb b/app/views/messages/_project_show.html.erb new file mode 100644 index 000000000..4456f36e9 --- /dev/null +++ b/app/views/messages/_project_show.html.erb @@ -0,0 +1,200 @@ + + +

    + + <%= render :partial => "/praise_tread/praise_tread",:locals => {:obj => @topic,:show_flag => true,:user_id =>User.current.id,:horizontal => true}%> +
    + <%= watcher_link(@topic, User.current) %> + <%= link_to( + l(:button_quote), + {:action => 'quote', :id => @topic}, + :remote => true, + :method => 'get', + :class => 'icon icon-comment', + :remote => true) if !@topic.locked? && authorize_for('messages', 'reply') %> + <%= link_to( + l(:button_edit), + {:action => 'edit', :id => @topic}, + :class => 'icon icon-edit' + ) if @message.editable_by?(User.current) %> + <%= link_to( + l(:button_delete), + {:action => 'destroy', :id => @topic}, + :method => :post, + :data => {:confirm => l(:text_are_you_sure)}, + :class => 'icon icon-del' + ) if @message.destroyable_by?(User.current) %> +
    + +
    +
    + <%= link_to image_tag(url_to_avatar(@topic.author), :class => "avatar"), user_path(@topic.author) %> +
    +

    + <%= link_to @topic.author, user_path(@topic.author) %> +

    +
    +
    +
    + <% if @project %> + <%= label_tag l(:field_subject) %>: <%= link_to @topic.subject, project_boards_path(@topic.project) %> + <% elsif @course %> + <%= label_tag l(:field_subject) %>: <%= link_to @topic.subject, course_boards_path(@topic.course) %> + <% end %> +
    +
    + <%= textilizable(@topic, :content) %> + <%= link_to_attachments @topic, :author => false %> +
    +
    +
    <%= authoring @topic.created_on, @topic.author %>
    + + +
    <%= toggle_link l(:button_reply), "reply", :focus => 'message_content' %>
    +
    + + + + +
    +
    +
    + +<% unless @replies.empty? %> +
    +
    +
    +
    +

    <%= l(:label_reply_plural) %> (<%= @reply_count %>)

    + <% reply_count = 0 %> + <% @replies.each do |message| %> +
    "> + + + + + + + + + + + + + + +
    <%= link_to image_tag(url_to_avatar(message.author), :class => "avatar"), user_path(message.author) %> +
    + <%= link_to( + "引用", + {:action => 'quote', :id => message}, + :remote => true, + :method => 'get', + :title => l(:button_quote)) if !@topic.locked? && authorize_for('messages', 'reply') %> + <%= link_to( + #image_tag('edit.png'), + "编辑", + {:action => 'edit', :id => message}, + :title => l(:button_edit) + ) if message.editable_by?(User.current) %> + <%= link_to( + #image_tag('delete.png'), + "删除", + {:action => 'destroy', :id => message}, + :method => :post, + :data => {:confirm => l(:text_are_you_sure)}, + :title => l(:button_delete) + ) if message.destroyable_by?(User.current) %> +
    +
    + <%= textilizable message, :content, :attachments => message.attachments %> +
    + <%= link_to_attachments message, :author => false %>
    <%= authoring message.created_on, message.author %>
    +
    + + <% end %> + +<% end %> + + + + +<% if !@topic.locked? && authorize_for('messages', 'reply') %> + +<% end %> + +<% html_title @topic.subject %> + + \ No newline at end of file diff --git a/app/views/messages/edit.html.erb b/app/views/messages/edit.html.erb index b7f591296..2577a4634 100644 --- a/app/views/messages/edit.html.erb +++ b/app/views/messages/edit.html.erb @@ -1,4 +1,8 @@ -<%= board_breadcrumb(@message) %> +<% if @message.project %> + <%= board_breadcrumb(@message) %> +<% elsif @message.course %> + <%= course_board_breadcrumb(@message) %> +<% end %>

    <%= avatar(@topic.author, :size => "24") %><%=h @topic.subject %>

    diff --git a/app/views/messages/new.html.erb b/app/views/messages/new.html.erb index f02af1daa..202634238 100644 --- a/app/views/messages/new.html.erb +++ b/app/views/messages/new.html.erb @@ -1,4 +1,8 @@ -

    <%= link_to h(@board.name), :controller => 'boards', :action => 'show', :project_id => @project, :id => @board %> » <%= l(:label_message_new) %>

    +<% if @project %> +

    <%= link_to h(@board.name), :controller => 'boards', :action => 'show', :project_id => @project, :id => @board %> » <%= l(:label_message_new) %>

    +<% elsif @course %> +

    <%= link_to h(@board.name), :controller => 'boards', :action => 'show', :course_id => @course, :id => @board %> » <%= l(:label_message_new) %>

    +<% end %> <%= form_for @message, :url => {:action => 'new'}, :html => {:multipart => true, :id => 'message-form'} do |f| %> <%= render :partial => 'form', :locals => {:f => f} %> diff --git a/app/views/messages/show.html.erb b/app/views/messages/show.html.erb index 92b62cb60..6e5888363 100644 --- a/app/views/messages/show.html.erb +++ b/app/views/messages/show.html.erb @@ -1,196 +1,5 @@ - - -
    - - <%= render :partial => "/praise_tread/praise_tread",:locals => {:obj => @topic,:show_flag => true,:user_id =>User.current.id}%> -
    - <%= watcher_link(@topic, User.current) %> - <%= link_to( - l(:button_quote), - {:action => 'quote', :id => @topic}, - :remote => true, - :method => 'get', - :class => 'icon icon-comment', - :remote => true) if !@topic.locked? && authorize_for('messages', 'reply') %> - <%= link_to( - l(:button_edit), - {:action => 'edit', :id => @topic}, - :class => 'icon icon-edit' - ) if @message.editable_by?(User.current) %> - <%= link_to( - l(:button_delete), - {:action => 'destroy', :id => @topic}, - :method => :post, - :data => {:confirm => l(:text_are_you_sure)}, - :class => 'icon icon-del' - ) if @message.destroyable_by?(User.current) %> -
    - -
    -
    - <%= link_to image_tag(url_to_avatar(@topic.author), :class => "avatar"), user_path(@topic.author) %> -
    -

    - <%= link_to @topic.author, user_path(@topic.author) %> -

    -
    -
    -
    - <%= label_tag l(:field_subject) %>: <%= link_to @topic.subject, project_boards_path(@topic.project) %> -
    -
    - <%= textilizable(@topic, :content) %> - <%= link_to_attachments @topic, :author => false %> -
    -
    -
    <%= authoring @topic.created_on, @topic.author %>
    - - -
    <%= toggle_link l(:button_reply), "reply", :focus => 'message_content' %>
    -
    - - - - -
    -
    -
    - -<% unless @replies.empty? %> -
    -
    -
    -
    -

    <%= l(:label_reply_plural) %> (<%= @reply_count %>)

    -<% reply_count = 0 %> -<% @replies.each do |message| %> -
    "> - - - - - - - - - - - - - - -
    <%= link_to image_tag(url_to_avatar(message.author), :class => "avatar"), user_path(message.author) %> -
    - <%= link_to( - "引用", - {:action => 'quote', :id => message}, - :remote => true, - :method => 'get', - :title => l(:button_quote)) if !@topic.locked? && authorize_for('messages', 'reply') %> - <%= link_to( - #image_tag('edit.png'), - "编辑", - {:action => 'edit', :id => message}, - :title => l(:button_edit) - ) if message.editable_by?(User.current) %> - <%= link_to( - #image_tag('delete.png'), - "删除", - {:action => 'destroy', :id => message}, - :method => :post, - :data => {:confirm => l(:text_are_you_sure)}, - :title => l(:button_delete) - ) if message.destroyable_by?(User.current) %> -
    -
    - <%= textilizable message, :content, :attachments => message.attachments %> -
    - <%= link_to_attachments message, :author => false %>
    <%= authoring message.created_on, message.author %>
    -
    - +<% if @project %> + <%= render :partial => 'project_show', locals: {project: @project} %> +<% elsif @course %> + <%= render :partial => 'course_show', locals: {course: @course} %> <% end %> - -<% end %> - - - - -<% if !@topic.locked? && authorize_for('messages', 'reply') %> - -<% end %> - -<% html_title @topic.subject %> - - \ No newline at end of file diff --git a/app/views/news/_course_form.html.erb b/app/views/news/_course_form.html.erb new file mode 100644 index 000000000..6e3060c3c --- /dev/null +++ b/app/views/news/_course_form.html.erb @@ -0,0 +1,13 @@ +<%= error_messages_for @news %> +
    + <% str = l(:bale_news_notice)%> + <%= str %> +
    +
    +

    <%= f.text_field :title, :required => true, :size => 60, :style => "width:488px;" %>

    + +

    <%= f.text_area :description, :required => true, :cols => 60, :rows => 11, :class => 'wiki-edit', :style => "width:490px;" %>

    +

    <%= render :partial => 'attachments/form', :locals => {:container => @news} %>

    +
    + +<%= wikitoolbar_for 'news_description' %> diff --git a/app/views/news/_course_news.html.erb b/app/views/news/_course_news.html.erb new file mode 100644 index 000000000..5104cd851 --- /dev/null +++ b/app/views/news/_course_news.html.erb @@ -0,0 +1,94 @@ +<% + btn_tips = l(:label_news_notice) + label_tips = l(:label_course_news) +%> + + + <%= label_tips %> + +<%= link_to(btn_tips, + new_course_news_path(@course), + :class => 'icon icon-add', + :onclick => 'showAndScrollTo("add-news", "news_title"); return false;') %> + +<% if @course && User.current.allowed_to?(:manage_news, @course) %> + +<% end %> +
    + <% if @newss.empty? %> +

    + <%= l(:label_no_data) %> +

    + <% else %> + <% @newss.each do |news| %> + + + + + + +
    <%= link_to image_tag(url_to_avatar(news.author), :class => "avatar"), user_path(news.author) %> + + + + + + + + + + + +
    + <%= link_to_user(news.author) if news.respond_to?(:author) %><%= l(:label_project_notice) %><%= link_to h(news.title), news_path(news) %> + <%= delete_link news_path(news) if User.current.allowed_to?(:manage_news, @couese) %> +
    + <%= textilizable(news, :description) %>
    <%= l :label_update_time %> + : <%= format_time(news.created_on) %><%= link_to l(:label_project_newother), news_path(news) %><%= "(#{l(:label_x_comments, :count => news.comments_count)})" if news.comments_count >= 0 %>
    +
    + <% end %> + <% end %> +
    + +
    + + + <% other_formats_links do |f| %> + <%= f.link_to 'Atom', :url => {:course_id => @course, :key => User.current.rss_key} %> + <% end %> + + <% content_for :header_tags do %> + <%= auto_discovery_link_tag(:atom, params.merge({:format => 'atom', :page => nil, :key => User.current.rss_key})) %> + <%= stylesheet_link_tag 'scm' %> + <% end %> + + <% html_title(l(:label_course_news)) -%> +
    + + diff --git a/app/views/news/_course_show.html.erb b/app/views/news/_course_show.html.erb new file mode 100644 index 000000000..2ef952f6d --- /dev/null +++ b/app/views/news/_course_show.html.erb @@ -0,0 +1,85 @@ +
    + <%= watcher_link(@news, User.current) %> + <%= link_to(l(:button_edit), + edit_news_path(@news), + :class => 'icon icon-edit', + :accesskey => accesskey(:edit), + :onclick => '$("#edit-news").show(); return false;') if User.current.allowed_to?(:manage_news, @course) %> + <%= delete_link news_path(@news) if User.current.allowed_to?(:manage_news, @course) %> +
    + +

    <%=h @news.title %>

    + +<% if authorize_for('news', 'edit') %> + +<% end %> + +
    + +
    + <%= textilizable(@news, :description) %> +
    + <%= link_to_attachments @news %> +
    + + <% if @news.commentable? %> +

    + <%= toggle_link l(:label_comment_add), "add_comment_form", :focus => "comment_comments" %> +

    + <%= form_tag({:controller => 'comments', :action => 'create', :id => @news}, :id => "add_comment_form", :style => "display:none;") do %> +
    + <%= text_area 'comment', 'comments', :cols => 80, :rows => 15, :class => 'wiki-edit' %> + <%= wikitoolbar_for 'comment_comments' %> +
    +

    + <%= submit_tag l(:button_add) %> +

    + <% end %> + <% end %> + + <% html_title @news.title -%> + + <% content_for :header_tags do %> + <%= stylesheet_link_tag 'scm' %> + <% end %> + + +
    +
    +

    <%= l(:label_comment_plural) %>

    + <% comments = @comments.reverse %> + <% comments.each do |comment| %> + <% next if comment.new_record? %> + + + + + +
    <%= image_tag(url_to_avatar(comment.author), :class => "avatar")%> + + + + + + + + + + + +
    <%= link_to_user(comment.author) if comment.respond_to?(:author) %> <%= l(:label_project_newadd) %><%= l(:label_comment_plural) %>
    +

    + <%= textilizable(comment.comments) %> +

    <%= format_time(comment.created_on) %><%= link_to_if_authorized image_tag('delete.png'), {:controller => 'comments', :action => 'destroy', :id => @news, :comment_id => comment}, + :data => {:confirm => l(:text_are_you_sure)}, :method => :delete, :title => l(:button_delete) %>
    + <% end if @comments.any? %> +
    diff --git a/app/views/news/_form.html.erb b/app/views/news/_form.html.erb index bfdfeaa37..0601ee25b 100644 --- a/app/views/news/_form.html.erb +++ b/app/views/news/_form.html.erb @@ -1,6 +1,6 @@ <%= error_messages_for @news %>
    - <% str = (@project.project_type == 1) ? l(:bale_news_notice) : l(:label_news_new) %> + <% str = @project ? l(:bale_news_notice) : l(:label_news_new) %> <%= str %>
    diff --git a/app/views/news/_project_news.html.erb b/app/views/news/_project_news.html.erb new file mode 100644 index 000000000..416b648a9 --- /dev/null +++ b/app/views/news/_project_news.html.erb @@ -0,0 +1,108 @@ +<% + if @project.project_type == Project::ProjectType_course + btn_tips = l(:label_news_notice) + label_tips = l(:label_course_news) + else + btn_tips = l(:label_news_new) + label_tips = l(:label_news) + end +%> + + + <%= label_tips %> + +<%= link_to(btn_tips, + new_project_news_path(@project), + :class => 'icon icon-add', + :onclick => 'showAndScrollTo("add-news", "news_title"); return false;') %> + +<% if @project && User.current.allowed_to?(:manage_news, @project) %> + +<% end %> +
    + <% if @newss.empty? %> +

    + <%= l(:label_no_data) %> +

    + <% else %> + <% @newss.each do |news| %> + + + + + + +
    <%= link_to image_tag(url_to_avatar(news.author), :class => "avatar"), user_path(news.author) %> + + <% if @project.project_type == 1 %> + + + + <% else %> + + + + <% end %> + + + + + + + +
    + <%= link_to_user(news.author) if news.respond_to?(:author) %><%= l(:label_project_notice) %><%= link_to h(news.title), news_path(news) %> + <%= delete_link news_path(news) if User.current.allowed_to?(:manage_news, @project) %> +
    + <%= link_to_user(news.author) if news.respond_to?(:author) %><%= l(:label_project_newshare) %> <%= link_to h(news.title), news_path(news) %> + <%= delete_link news_path(news) if User.current.allowed_to?(:manage_news, @project) %> +
    + <%= textilizable(news, :description) %>
    <%= l :label_update_time %> + : <%= format_time(news.created_on) %><%= link_to l(:label_project_newother), news_path(news) %><%= "(#{l(:label_x_comments, :count => news.comments_count)})" if news.comments_count >= 0 %>
    +
    + <% end %> + <% end %> +
    + +
    + + + <% other_formats_links do |f| %> + <%= f.link_to 'Atom', :url => {:project_id => @project, :key => User.current.rss_key} %> + <% end %> + + <% content_for :header_tags do %> + <%= auto_discovery_link_tag(:atom, params.merge({:format => 'atom', :page => nil, :key => User.current.rss_key})) %> + <%= stylesheet_link_tag 'scm' %> + <% end %> + + <% html_title(l(:label_news_plural)) -%> +
    + + diff --git a/app/views/news/_project_show.html.erb b/app/views/news/_project_show.html.erb new file mode 100644 index 000000000..c8a8c5767 --- /dev/null +++ b/app/views/news/_project_show.html.erb @@ -0,0 +1,85 @@ +
    + <%= watcher_link(@news, User.current) %> + <%= link_to(l(:button_edit), + edit_news_path(@news), + :class => 'icon icon-edit', + :accesskey => accesskey(:edit), + :onclick => '$("#edit-news").show(); return false;') if User.current.allowed_to?(:manage_news, @project) %> + <%= delete_link news_path(@news) if User.current.allowed_to?(:manage_news, @project) %> +
    + +

    <%=h @news.title %>

    + +<% if authorize_for('news', 'edit') %> + +<% end %> + +
    + +
    + <%= textilizable(@news, :description) %> +
    + <%= link_to_attachments @news %> +
    + + <% if @news.commentable? %> +

    + <%= toggle_link l(:label_comment_add), "add_comment_form", :focus => "comment_comments" %> +

    + <%= form_tag({:controller => 'comments', :action => 'create', :id => @news}, :id => "add_comment_form", :style => "display:none;") do %> +
    + <%= text_area 'comment', 'comments', :cols => 80, :rows => 15, :class => 'wiki-edit' %> + <%= wikitoolbar_for 'comment_comments' %> +
    +

    + <%= submit_tag l(:button_add) %> +

    + <% end %> + <% end %> + + <% html_title @news.title -%> + + <% content_for :header_tags do %> + <%= stylesheet_link_tag 'scm' %> + <% end %> + + +
    +
    +

    <%= l(:label_comment_plural) %>

    + <% comments = @comments.reverse %> + <% comments.each do |comment| %> + <% next if comment.new_record? %> + + + + + +
    <%= image_tag(url_to_avatar(comment.author), :class => "avatar")%> + + + + + + + + + + + +
    <%= link_to_user(comment.author) if comment.respond_to?(:author) %> <%= l(:label_project_newadd) %><%= l(:label_comment_plural) %>
    +

    + <%= textilizable(comment.comments) %> +

    <%= format_time(comment.created_on) %><%= link_to_if_authorized image_tag('delete.png'), {:controller => 'comments', :action => 'destroy', :id => @news, :comment_id => comment}, + :data => {:confirm => l(:text_are_you_sure)}, :method => :delete, :title => l(:button_delete) %>
    + <% end if @comments.any? %> +
    diff --git a/app/views/news/index.html.erb b/app/views/news/index.html.erb index 4dfa21d52..2635e52a6 100644 --- a/app/views/news/index.html.erb +++ b/app/views/news/index.html.erb @@ -1,108 +1,5 @@ -<% - if @project.project_type == Project::ProjectType_course - btn_tips = l(:label_news_notice) - label_tips = l(:label_course_news) - else - btn_tips = l(:label_news_new) - label_tips = l(:label_news) - end -%> - - - <%= label_tips %> - -<%= link_to(btn_tips, - new_project_news_path(@project), - :class => 'icon icon-add', - :onclick => 'showAndScrollTo("add-news", "news_title"); return false;') %> - -<% if @project && User.current.allowed_to?(:manage_news, @project) %> - +<% if @project %> + <%= render :partial => 'project_news', locals: {project: @project} %> +<% elsif @course %> + <%= render :partial => 'course_news', locals: {course: @course} %> <% end %> -
    - <% if @newss.empty? %> -

    - <%= l(:label_no_data) %> -

    - <% else %> - <% @newss.each do |news| %> - - - - - - -
    <%= link_to image_tag(url_to_avatar(news.author), :class => "avatar"), user_path(news.author) %> - - <% if @project.project_type == 1 %> - - - - <% else %> - - - - <% end %> - - - - - - - -
    - <%= link_to_user(news.author) if news.respond_to?(:author) %><%= l(:label_project_notice) %><%= link_to h(news.title), news_path(news) %> - <%= delete_link news_path(news) if User.current.allowed_to?(:manage_news, @project) %> -
    - <%= link_to_user(news.author) if news.respond_to?(:author) %><%= l(:label_project_newshare) %> <%= link_to h(news.title), news_path(news) %> - <%= delete_link news_path(news) if User.current.allowed_to?(:manage_news, @project) %> -
    - <%= textilizable(news, :description) %>
    <%= l :label_update_time %> - : <%= format_time(news.created_on) %><%= link_to l(:label_project_newother), news_path(news) %><%= "(#{l(:label_x_comments, :count => news.comments_count)})" if news.comments_count >= 0 %>
    -
    - <% end %> - <% end %> -
    - -
    - - - <% other_formats_links do |f| %> - <%= f.link_to 'Atom', :url => {:project_id => @project, :key => User.current.rss_key} %> - <% end %> - - <% content_for :header_tags do %> - <%= auto_discovery_link_tag(:atom, params.merge({:format => 'atom', :page => nil, :key => User.current.rss_key})) %> - <%= stylesheet_link_tag 'scm' %> - <% end %> - - <% html_title(l(:label_news_plural)) -%> -
    - - diff --git a/app/views/news/new.html.erb b/app/views/news/new.html.erb index feaf7540b..68fad17f2 100644 --- a/app/views/news/new.html.erb +++ b/app/views/news/new.html.erb @@ -1,9 +1,17 @@ - -<%= labelled_form_for @news, :url => project_news_index_path(@project), - :html => { :id => 'news-form', :multipart => true } do |f| %> - <%= render :partial => 'news/form', :locals => { :f => f } %> - <%= submit_tag l(:button_create), :class => "whiteButton m3p10 h30" %> - <%= preview_link preview_news_path(:project_id => @project), 'news-form' ,target='preview',{:class => 'whiteButton m3p10'}%> +<% if @project %> + <%= labelled_form_for @news, :url => project_news_index_path(@project), + :html => {:id => 'news-form', :multipart => true} do |f| %> + <%= render :partial => 'news/form', :locals => {:f => f} %> + <%= submit_tag l(:button_create), :class => "whiteButton m3p10 h30" %> + <%= preview_link preview_news_path(:project_id => @project), 'news-form', target='preview', {:class => 'whiteButton m3p10'} %> + <% end %> +<% elsif @course %> + <%= labelled_form_for @news, :url => course_news_index_path(@course), + :html => {:id => 'news-form', :multipart => true} do |f| %> + <%= render :partial => 'news/form', :locals => {:f => f} %> + <%= submit_tag l(:button_create), :class => "whiteButton m3p10 h30" %> + <%= preview_link preview_news_path(:course_id => @course), 'news-form', target='preview', {:class => 'whiteButton m3p10'} %> + <% end %> <% end %>
    diff --git a/app/views/news/show.html.erb b/app/views/news/show.html.erb index ed1bcacb5..6e5888363 100644 --- a/app/views/news/show.html.erb +++ b/app/views/news/show.html.erb @@ -1,85 +1,5 @@ -
    - <%= watcher_link(@news, User.current) %> - <%= link_to(l(:button_edit), - edit_news_path(@news), - :class => 'icon icon-edit', - :accesskey => accesskey(:edit), - :onclick => '$("#edit-news").show(); return false;') if User.current.allowed_to?(:manage_news, @project) %> - <%= delete_link news_path(@news) if User.current.allowed_to?(:manage_news, @project) %> -
    - -

    <%=h @news.title %>

    - -<% if authorize_for('news', 'edit') %> - +<% if @project %> + <%= render :partial => 'project_show', locals: {project: @project} %> +<% elsif @course %> + <%= render :partial => 'course_show', locals: {course: @course} %> <% end %> - -
    - -
    - <%= textilizable(@news, :description) %> -
    - <%= link_to_attachments @news %> -
    - - <% if @news.commentable? %> -

    - <%= toggle_link l(:label_comment_add), "add_comment_form", :focus => "comment_comments" %> -

    - <%= form_tag({:controller => 'comments', :action => 'create', :id => @news}, :id => "add_comment_form", :style => "display:none;") do %> -
    - <%= text_area 'comment', 'comments', :cols => 80, :rows => 15, :class => 'wiki-edit' %> - <%= wikitoolbar_for 'comment_comments' %> -
    -

    - <%= submit_tag l(:button_add) %> -

    - <% end %> - <% end %> - - <% html_title @news.title -%> - - <% content_for :header_tags do %> - <%= stylesheet_link_tag 'scm' %> - <% end %> - - -
    -
    -

    <%= l(:label_comment_plural) %>

    - <% comments = @comments.reverse %> - <% comments.each do |comment| %> - <% next if comment.new_record? %> - - - - - -
    <%= image_tag(url_to_avatar(comment.author), :class => "avatar")%> - - - - - - - - - - - -
    <%= link_to_user(comment.author) if comment.respond_to?(:author) %> <%= l(:label_project_newadd) %><%= l(:label_comment_plural) %>
    -

    - <%= textilizable(comment.comments) %> -

    <%= format_time(comment.created_on) %><%= link_to_if_authorized image_tag('delete.png'), {:controller => 'comments', :action => 'destroy', :id => @news, :comment_id => comment}, - :data => {:confirm => l(:text_are_you_sure)}, :method => :delete, :title => l(:button_delete) %>
    - <% end if @comments.any? %> -
    diff --git a/app/views/open_source_projects/master_apply.html.erb b/app/views/open_source_projects/master_apply.html.erb index 0288692fc..f99701932 100644 --- a/app/views/open_source_projects/master_apply.html.erb +++ b/app/views/open_source_projects/master_apply.html.erb @@ -39,11 +39,7 @@
    - <%= l(:label_user_grade) %>: <%= link_to( format("%.2f" , finall_user_score).to_f, {:controller => 'users', - :action => 'show_score', - :remote => true, - :id => user.id}, - :style=>"color: #EC6300;") %> + <%= l(:label_user_grade) %>: <%= render :partial => 'users/user_score', :locals => {:user => user}%>
    diff --git a/app/views/praise_tread/_praise_tread.html.erb b/app/views/praise_tread/_praise_tread.html.erb index 5fee2a593..2b859cf76 100644 --- a/app/views/praise_tread/_praise_tread.html.erb +++ b/app/views/praise_tread/_praise_tread.html.erb @@ -1,57 +1,127 @@ <% if User.current.logged? %> -
    + <% if horizontal %> + +
    - <% @is_valuate = is_praise_or_tread(obj,user_id)%> - <% if @is_valuate.size > 0 %> - <% @flag = @is_valuate.first.praise_or_tread %> - <% if @flag == 1 %> - - - - - - - - - - - -
    <%= image_tag "/images/praise_tread/praise_false.png" , weight:"22px", height:"22px",:title => l(:label_issue_praise_over) %>
    <%= get_praise_num(obj)%>
    <%= image_tag "/images/praise_tread/tread_false.png",weight:"22px", height:"22px",:title => l(:label_issue_appraise_over) %>
    - - <% elsif @flag == 0 %> - - - - - - - - - - - - -
    <%= image_tag "/images/praise_tread/praise_false.png",weight:"22px", height:"22px", :title => l(:label_issue_appraise_over) %>
    <%= get_praise_num(obj)%>
    <%= image_tag "/images/praise_tread/tread_false.png",weight:"22px", height:"22px",:title => l(:label_issue_tread_over) %>
    - <% end %> + <% @is_valuate = is_praise_or_tread(obj,user_id)%> + <% if @is_valuate.size > 0 %> + <% @flag = @is_valuate.first.praise_or_tread %> + <% if @flag == 1 %> + + + + + + +
    <%= image_tag "/images/praise_tread/praise_false.png" , weight:"22px", height:"22px",:title => l(:label_issue_praise_over) %><%= get_praise_num(obj)%><%= image_tag "/images/praise_tread/tread_false.png",weight:"22px", height:"22px",:title => l(:label_issue_appraise_over) %>
    - <% else %> - - - - - - - - - - - -
    <%= link_to image_tag("/images/praise_tread/praise_true.png",weight:"22px", height:"22px",:title => l(:label_issue_praise)), - :controller=>"praise_tread",:action=>"praise_plus",:remote=>true,:obj_id => obj.id,:obj_type => obj.class%>
    <%= get_praise_num(obj)%>
    <%= link_to image_tag("/images/praise_tread/tread_true.png",weight:"22px", height:"22px",:title => l(:label_issue_tread)),:controller=>"praise_tread", - :action=>"tread_plus",:remote=>true,:obj_id => obj.id,:obj_type => obj.class %>
    - - <% end %> -
    + <% elsif @flag == 0 %> -<% end %> + + + + + + +
    <%= image_tag "/images/praise_tread/praise_false.png",weight:"22px", height:"22px", :title => l(:label_issue_appraise_over) %><%= get_praise_num(obj)%><%= image_tag "/images/praise_tread/tread_false.png",weight:"22px", height:"22px",:title => l(:label_issue_tread_over) %>
    + <% end %> + + <% else %> + + <% if user_id == obj.author_id %> + + + + + + +
    <%= image_tag "/images/praise_tread/praise_true.png" , weight:"22px", height:"22px",:title => l(:label_issue_not_praise_over) %><%= get_praise_num(obj)%><%= image_tag "/images/praise_tread/tread_true.png",weight:"22px", height:"22px",:title => l(:label_issue_not_treed_over) %>
    + <% else %> + + + + + + +
    <%= link_to image_tag("/images/praise_tread/praise_true.png",weight:"22px", height:"22px",:title => l(:label_issue_praise)), + :controller=>"praise_tread",:action=>"praise_plus",:remote=>true,:obj_id => obj.id,:obj_type => obj.class,:horizontal => horizontal %> <%= get_praise_num(obj)%> <%= link_to image_tag("/images/praise_tread/tread_true.png",weight:"22px", height:"22px",:title => l(:label_issue_tread)),:controller=>"praise_tread", + :action=>"tread_plus",:remote=>true,:obj_id => obj.id,:obj_type => obj.class,:horizontal => horizontal %>
    + <% end %> + + + <% end %> +
    + + <% else %> + +
    + + <% @is_valuate = is_praise_or_tread(obj,user_id)%> + <% if @is_valuate.size > 0 %> + <% @flag = @is_valuate.first.praise_or_tread %> + <% if @flag == 1 %> + + + + + + + + + + + +
    <%= image_tag "/images/praise_tread/praise_false.png" , weight:"22px", height:"22px",:title => l(:label_issue_praise_over) %>
    <%= get_praise_num(obj)%>
    <%= image_tag "/images/praise_tread/tread_false.png",weight:"22px", height:"22px",:title => l(:label_issue_appraise_over) %>
    + + <% elsif @flag == 0 %> + + + + + + + + + + + + +
    <%= image_tag "/images/praise_tread/praise_false.png",weight:"22px", height:"22px", :title => l(:label_issue_appraise_over) %>
    <%= get_praise_num(obj)%>
    <%= image_tag "/images/praise_tread/tread_false.png",weight:"22px", height:"22px",:title => l(:label_issue_tread_over) %>
    + <% end %> + + <% else %> + <% if user_id == obj.author_id %> + + + + + + + + + + + +
    <%= image_tag "/images/praise_tread/praise_true.png",weight:"22px", height:"22px", :title => l(:label_issue_not_praise_over) %>
    <%= get_praise_num(obj)%>
    <%= image_tag "/images/praise_tread/tread_true.png",weight:"22px", height:"22px",:title => l(:label_issue_not_tread_over) %>
    + <% else %> + + + + + + + + + + +
    <%= link_to image_tag("/images/praise_tread/praise_true.png",weight:"22px", height:"22px",:title => l(:label_issue_praise)), + :controller=>"praise_tread",:action=>"praise_plus",:remote=>true,:obj_id => obj.id,:obj_type => obj.class ,:horizontal => horizontal %>
    <%= get_praise_num(obj)%>
    <%= link_to image_tag("/images/praise_tread/tread_true.png",weight:"22px", height:"22px",:title => l(:label_issue_tread)),:controller=>"praise_tread", + :action=>"tread_plus",:remote=>true,:obj_id => obj.id,:obj_type => obj.class ,:horizontal => horizontal %>
    + <% end %> + + + <% end %> +
    + <% end %> + <% end %> diff --git a/app/views/praise_tread/praise_minus.js.erb b/app/views/praise_tread/praise_minus.js.erb index 74f7d6bfe..ab298ba2e 100644 --- a/app/views/praise_tread/praise_minus.js.erb +++ b/app/views/praise_tread/praise_minus.js.erb @@ -1,3 +1,3 @@ $('#praise_tread').html('<%= j( -render :partial => "/praise_tread/praise_tread",:locals => {:obj => @obj,:show_flag => false,:user_id => User.current.id} +render :partial => "/praise_tread/praise_tread",:locals => {:obj => @obj,:show_flag => false,:user_id => User.current.id,:horizontal=>@horizontal} )%>'); diff --git a/app/views/praise_tread/praise_plus.js.erb b/app/views/praise_tread/praise_plus.js.erb index c2584dcd2..d56ff0e68 100644 --- a/app/views/praise_tread/praise_plus.js.erb +++ b/app/views/praise_tread/praise_plus.js.erb @@ -1,4 +1,4 @@ $('#praise_tread_<%= @obj.id %>').html('<%= j( -render :partial => "/praise_tread/praise_tread",:locals => {:obj => @obj,:user_id => User.current.id} +render :partial => "/praise_tread/praise_tread",:locals => {:obj => @obj,:user_id => User.current.id,:horizontal => @horizontal} )%>'); diff --git a/app/views/praise_tread/tread_plus.js.erb b/app/views/praise_tread/tread_plus.js.erb index 89efec2dc..1104440ec 100644 --- a/app/views/praise_tread/tread_plus.js.erb +++ b/app/views/praise_tread/tread_plus.js.erb @@ -1,5 +1,5 @@ $('#praise_tread_<%= @obj.id %>').html('<%= j( -render :partial => "/praise_tread/praise_tread",:locals => {:obj => @obj,:user_id => User.current.id} +render :partial => "/praise_tread/praise_tread",:locals => {:obj => @obj,:user_id => User.current.id,:horizontal => @horizontal} )%>'); diff --git a/app/views/projects/_course.html.erb b/app/views/projects/_course.html.erb index 6ea802037..6c4bfe9a6 100644 --- a/app/views/projects/_course.html.erb +++ b/app/views/projects/_course.html.erb @@ -18,7 +18,11 @@ <%if @admin&&@admin.first&&@admin.first.user&&@admin.first.user.user_extensions%> <%# unless @project.course_extra.school.nil? %> - <%= @project.course_extra.teacher.user_extensions.school.try(:name) %> + + <% unless @project.course_extra.teacher.user_extensions.school.nil? %> + <%= link_to @project.course_extra.teacher.user_extensions.school.try(:name),options={:controller => 'welcome',:action => 'course',:school_id => @project.course_extra.teacher.user_extensions.school.id}, html_options={:method => 'get'}%> + <% end %> + <%# end %> <% end %>

    diff --git a/app/views/projects/_show_projects_score.html.erb b/app/views/projects/_show_projects_score.html.erb index e9b21e571..d135cfbdb 100644 --- a/app/views/projects/_show_projects_score.html.erb +++ b/app/views/projects/_show_projects_score.html.erb @@ -28,7 +28,7 @@

    <%= l(:label_projects_score) %>

    - +
    <%= image_tag(url_to_avatar(@project), :class => 'avatar2') %> diff --git a/app/views/projects/show_projects_score.html.erb b/app/views/projects/show_projects_score.html.erb new file mode 100644 index 000000000..95a7085d4 --- /dev/null +++ b/app/views/projects/show_projects_score.html.erb @@ -0,0 +1,97 @@ + +<% issue_count = @project.issues.count %> +<% issue_journal_count = @project.issue_changes.count %> +<% issue_score = issue_count * 0.2 %> +<% issue_journal_score = issue_journal_count * 0.1 %> +<% finall_issue_score = issue_score + issue_journal_score %> + +<% new_count = @project.news.count %> +<% new_score = new_count * 0.1 %> +<% finall_new_score = new_score %> + +<% document_count = @project.documents.count %> +<% file_score = document_count * 0.1 %> +<% finall_file_score = file_score %> + +<% changeset_count = @project.changesets.count %> +<% code_submit_score = changeset_count * 0.3 %> +<% finall_code_submit_score = code_submit_score %> + +<% board_message_count = 0 %> +<% @project.boards.each do |board| %> + <% board_message_count += board.messages_count %> +<% end %> +<% topic_score = board_message_count * 0.1 %> +<% finall_topic_score = topic_score %> + +<% finall_project_score = finall_issue_score + finall_new_score + finall_file_score + finall_code_submit_score + topic_score %> + + + <%= h html_title %> + + + <%= csrf_meta_tag %> + <%= favicon %> + <%= stylesheet_link_tag 'jquery/jquery-ui-1.9.2', 'application', 'nyan', :media => 'all' %> + <%= stylesheet_link_tag 'rtl', :media => 'all' if l(:direction) == 'rtl' %> + <%= javascript_heads %> + <%= heads_for_theme %> + <%= hubspot_head %> + <%= call_hook :view_layouts_base_html_head %> + + <%= yield :header_tags -%> + + +

    <%= l(:label_projects_score) %>

    +
    + + + + + + +
    <%= image_tag(url_to_avatar(@project), :class => 'avatar2') %> + + + +
    <%= @project.name %>
    +
    + + + +
    <%= l(:label_projects_score) %>
    <%= format("%.2f" , finall_project_score ).to_f %>
    +
    +
    + +
    +
      +
    • + <%= link_to l(:label_projects_score), {:controller => 'projects', :action => 'show_projects_score', :remote => true}%> : + <%= format("%.2f" , finall_project_score ).to_f %> +
    • +
    • + <%= link_to l(:label_issue_score), {:controller => 'projects', :action => 'issue_score_index', :remote => true}%> : + <%= format("%.2f" , finall_issue_score).to_f %> +
    • +
    • + <%= link_to l(:label_news_score), {:controller => 'projects', :action => 'news_score_index', :remote => true}%> : + <%= format("%.2f" , finall_new_score).to_f %> +
    • +
    • + <%= link_to l(:label_file_score), {:controller => 'projects', :action => 'file_score_index', :remote => true}%> : + <%= format("%.2f" , finall_file_score).to_f %> +
    • +
    • + <%= link_to l(:label_code_submit_score), {:controller => 'projects', :action => 'code_submit_score_index', :remote => true}%> : + <%= format("%.2f" , finall_code_submit_score).to_f %> +
    • +
    • + <%= link_to l(:label_topic_score), {:controller => 'projects', :action => 'projects_topic_score_index', :remote => true}%> : + <%= format("%.2f" , finall_topic_score).to_f %> +
    • +
    +
    +
    + <%= render :partial => 'projects/project_score_index', :locals => {:index => 0 } %> +
    + \ No newline at end of file diff --git a/app/views/tags/_tag_name.html.erb b/app/views/tags/_tag_name.html.erb index dad5d53f7..f5057aba3 100644 --- a/app/views/tags/_tag_name.html.erb +++ b/app/views/tags/_tag_name.html.erb @@ -7,7 +7,7 @@ // }); // }) - + <% @tags = obj.reload.tag_list %> <% if non_list_all and (@tags.size > 0) %> @@ -70,6 +70,7 @@ :taggable_id => obj.id, :taggable_type => object_flag %> <% end %> + <% when '6' %> <% if (User.current.logged? && User.current.admin? @@ -86,6 +87,12 @@ :taggable_id => obj.id, :taggable_type => object_flag %> <% end %> + <% when '9' %> + + <% if (CourseInfos.find_by_course_id(obj.id)).try(:user_id) == User.current.id %> + <%= link_to 'x', :controller => "tags", :action => "remove_tag", :remote => true, :tag_name => tag, + :taggable_id => obj.id, :taggable_type => object_flag %> + <% end %> <% end %> diff --git a/app/views/users/_course_form.html.erb b/app/views/users/_course_form.html.erb index 13ab819dc..f5cada9a8 100644 --- a/app/views/users/_course_form.html.erb +++ b/app/views/users/_course_form.html.erb @@ -1,44 +1,44 @@
    -
      +
        <% for membership in memberships %>
      • - + '); + th.html(title); + header.append(th); + $('tr.changeset td.id a').each(function(i){ + var revision = this.getAttribute("href"); + revision = revision.substr(revision.lastIndexOf("/") + 1); + var review = review_counts['revision_' + revision]; + var td = $('
        <%= image_tag(url_to_avatar(membership.project), :class => 'avatar') %><%= image_tag(url_to_avatar(membership.course), :class => 'avatar') %> + + + +<% end %> +<% if issue.code_review_assignment %> + <% + assignment = issue.code_review_assignment + repository_id = assignment.repository_identifier +%> + + + + + +<% end %> + diff --git a/plugins/redmine_code_review/app/views/code_review/_new_form.html.erb b/plugins/redmine_code_review/app/views/code_review/_new_form.html.erb new file mode 100644 index 000000000..81feda16e --- /dev/null +++ b/plugins/redmine_code_review/app/views/code_review/_new_form.html.erb @@ -0,0 +1,121 @@ +<% +# Code Review plugin for Redmine +# Copyright (C) 2009-2013 Haruyuki Iida +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +-%> + + +
        +

        + <%= l(:label_line_number, :line => @review.line) %> +

        + <%= form_for @review,:as => :review, + :url => {:controller => 'code_review', :action => 'new', :id=>@project}, :html => {:id => 'review_form'} do |f| %> + <%= error_messages_for 'review' %> + <%= error_messages_for 'issue' %> + <%= error_messages_for 'relation' %> + <%= f.hidden_field(:change_id) %> + <%= f.hidden_field(:line) %> + <%= hidden_field_tag(:action_type, @review.action_type) %> + <%= hidden_field_tag(:rev, @review.revision) %> + <%= hidden_field_tag(:rev_to, @review.rev_to) %> + <%= hidden_field_tag(:path, @review.path) %> + <%= hidden_field_tag(:file_count, @review.file_count) %> + <%= hidden_field_tag(:attachment_id, @review.attachment_id) %> + <%= hidden_field_tag(:repository_id, @repository_id) %> + <%= hidden_field_tag(:diff_all, @review.diff_all) %> +

        + + <%= f.text_field :subject, :size => 70, :required => true %> +

        + + <% if @setting.tracker_in_review_dialog %> +

        + + <%= select :issue, :tracker_id, @project.trackers.collect {|t| [t.name, t.id]}, :required => true %> + +

        + <% end %> +

        + + <%= f.text_field :parent_id, :size => 10 %> + <% if @parent_candidate %> + <%= raw l(:label_parent_suggestion, {:issue_id => link_to_issue(@parent_candidate)}) %> + + <% end %> +

        + <% @issue.custom_field_values.each do |value| %> + <% next unless value.required? -%> +

        <%= custom_field_tag_with_label :issue, value %>

        + <% end %> +

        + <%= f.text_area :comment, + :cols => 30, + :rows => 12, + :accesskey => accesskey(:edit), + :class => 'wiki-edit' %> + +

        +

        + + <%= select :issue, :assigned_to_id, (@issue.assignable_users.collect {|m| [m.name, m.id]}), :include_blank => true %> +

        + <% unless @project.issue_categories.empty? %> +

        + + <%= select :issue, :category_id, (@project.issue_categories.collect {|c| [c.name, c.id]}), :include_blank => true %> +

        + <% end %> + <% unless @issue.assignable_versions.empty? %> +

        + + <%= select :issue, :fixed_version_id, (@issue.assignable_versions.collect {|v| [v.name, v.id]}), :include_blank => true, :selected => @default_version_id %> +

        + <% end %> + + <% + @allowed_statuses = @issue.new_statuses_allowed_to(User.current) + -%> + <% if @issue.new_record? || @allowed_statuses.any? %> +

        <%= f.select :status_id, (@allowed_statuses.collect {|p| [p.name, p.id]}), :required => true %>

        + <% else %> +

        <%= h(@issue.status.name) %>

        + <% end %> +

        + <% + submit_url = url_for(:controller => 'code_review', :action => 'new', :id=>@project) + %> + <%= button_to_function l(:button_apply), "$('#review-form').load('#{submit_url}', $('#review_form').serialize2json())" %> + + + <%= preview_link({ :controller => 'code_review', :action => 'preview', :id => @project}, 'review_form') %> +

        +
        + <%= wikitoolbar_for 'review_comment' %> + <% end %> + +
        + + diff --git a/plugins/redmine_code_review/app/views/code_review/_reply.html.erb b/plugins/redmine_code_review/app/views/code_review/_reply.html.erb new file mode 100644 index 000000000..7fccf0aa3 --- /dev/null +++ b/plugins/redmine_code_review/app/views/code_review/_reply.html.erb @@ -0,0 +1,36 @@ +<% +# Code Review plugin for Redmine +# Copyright (C) 2009 Haruyuki Iida +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +-%> +

        + + <%= authoring reply.created_on, reply.user %>. +

        + <%= avatar(reply.user, :size => "32") %> +
          + <% for detail in reply.details %> +
        • <%= show_detail(detail) %>
        • + <% end %> +
        + + +
        + <%= textilizable reply, :notes %> +
        + + +
        \ No newline at end of file diff --git a/plugins/redmine_code_review/app/views/code_review/_show.html.erb b/plugins/redmine_code_review/app/views/code_review/_show.html.erb new file mode 100644 index 000000000..560447b96 --- /dev/null +++ b/plugins/redmine_code_review/app/views/code_review/_show.html.erb @@ -0,0 +1,187 @@ +<% +# Code Review plugin for Redmine +# Copyright (C) 2009-2012 Haruyuki Iida +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +-%> +
        + +
        + + + <%= error_messages_for 'review' -%> + <%= error_messages_for 'reply' -%> + <% if @notice -%> +
        <%= @notice -%>
        + <% end -%> + <% if @error -%> +
        <%= @error -%>
        + <% end -%> + + +
        + + +
        + <% if authorize_for('code_review', 'update') -%> + <%= link_to_function l(:button_update), "$('#update-form-#{@review.id}').show();return false;", :class => 'icon icon-edit' %> + <% end %> + <% if authorize_for('code_review', 'destroy') -%> + <%= link_to(l(:button_delete), + {:controller => 'code_review', + :action => 'destroy', + :id => @project, + :review_id => @review}, + :update => "show_review_#{@review.id}", + :remote => true, + :confirm => l(:text_are_you_sure), + :success => "deleteReview(#{@review.id})", + :class => 'icon icon-del') %> + <% end -%> +
        + + +

        + <%= link_to h(@issue.tracker.name) + ' #' +@issue.id.to_s + ' (' + h(@review.issue.status) + ')', + :controller => 'issues', :action => 'show', :id => @review.issue.id %>: +
        + <%=h @review.subject %> +

        + + +

        + <%= avatar(@review.user, :size => "64") %> +
        + <%= authoring @review.created_at, @review.user %>. + <%= l(:label_updated_time, distance_of_time_in_words(Time.now, @review.updated_at)) + '.' if @review.created_at != @review.updated_at %> +

        +
        + + +
        + <%= textilizable @review, :comment %> +
        + + + +
        + + + <% journals = @review.issue.journals.sort {|a, b| a.id <=> b.id } %> + <% if respond_to?('render_journal') %> + <% # ChiliProject -%> + <% if journals.length > 0 %> +
        +

        <%= l(:label_history) %>

        + <%= render :partial => 'history', :locals => { :issue => @review.issue, :journals => journals } %> +
        + <% end %> + <% else %> + <% # Redmine -%> + <% if journals.length > 0 %> +

        <%= l(:label_history) %>

        + <% end %> + <%= render :partial => 'reply', :collection => journals %> + <% end %> + + + <% if authorize_for('code_review', 'reply') -%> +

        + <%= toggle_link l(:button_reply), "reply_#{@review.id}", :focus => 'reply_comment_' + @review.id.to_s %> +

        + <% + message_form_id = "message-form-#{@review.id}" + -%> + + <% end %> + +
        + +
        diff --git a/plugins/redmine_code_review/app/views/code_review/_show_error.html.erb b/plugins/redmine_code_review/app/views/code_review/_show_error.html.erb new file mode 100644 index 000000000..7b9c2db9e --- /dev/null +++ b/plugins/redmine_code_review/app/views/code_review/_show_error.html.erb @@ -0,0 +1,24 @@ +
        +

        Error

        + +

        change not found.

        + + @path = '<%=h @path %>'
        + @changeset = <%=h @changeset %>
        + @rev = <%=h @rev %>
        + <% if @changeset %> +
          + <% for change in @changeset.changes do%> +
        • + '<%=h change.path%>' +
        • + <% end %> +
        + <% end %> +
        + + \ No newline at end of file diff --git a/plugins/redmine_code_review/app/views/code_review/_update_diff_view.html.erb b/plugins/redmine_code_review/app/views/code_review/_update_diff_view.html.erb new file mode 100644 index 000000000..0d38e3ae6 --- /dev/null +++ b/plugins/redmine_code_review/app/views/code_review/_update_diff_view.html.erb @@ -0,0 +1,77 @@ +<% +# Code Review plugin for Redmine +# Copyright (C) 2009-2012 Haruyuki Iida +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +-%> + +
        + +
        + +
        +
        + +
        +
        + +
        + + + + diff --git a/plugins/redmine_code_review/app/views/code_review/_update_revisions.html.erb b/plugins/redmine_code_review/app/views/code_review/_update_revisions.html.erb new file mode 100644 index 000000000..48b9289ec --- /dev/null +++ b/plugins/redmine_code_review/app/views/code_review/_update_revisions.html.erb @@ -0,0 +1,49 @@ +<%# +# Code Review plugin for Redmine +# Copyright (C) 2009-2011 Haruyuki Iida +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +%> + + + + diff --git a/plugins/redmine_code_review/app/views/code_review/index.html.erb b/plugins/redmine_code_review/app/views/code_review/index.html.erb new file mode 100644 index 000000000..c82a9c0b3 --- /dev/null +++ b/plugins/redmine_code_review/app/views/code_review/index.html.erb @@ -0,0 +1,101 @@ +<% +# Code Review plugin for Redmine +# Copyright (C) 2009-2012 Haruyuki Iida +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +-%> + + +
        +

        + <%=h l(:code_reviews) %> +

        + + <% if @all_review_count > 0 %> +

        + <%= form_tag({:controller => 'code_review', :action=>'index', :id => @project}, :id => 'optionform') do %> + <%= check_box_tag 'show_closed', 'true', @show_closed, :onchange => "change_option($('#show_closed').is(':checked'));"%> <%=h l(:label_show_closed_reviews) %> + <% end %> + <%# observe_field 'show_closed', :with => 'show_closed', :update => 'content' %> +

        + <% end %> + + <% if @reviews == nil or @reviews.length == 0 %> +

        <%= l(:label_no_data) %>

        + <% else %> + + +
        - <%= link_to_project(membership.project) %> + <%= link_to_course(membership.course) %> - <%= render :partial => 'courses/set_course_time', :locals => {:project => membership.project} %> + <%= render :partial => 'courses/set_course_time', :locals => {:course => membership.course} %> <% if User.current == @user %> <% (membership.roles).each do |role| %> <% unless (role == Role.find(9) || role == Role.find(3)) %> - <%= join_in_course(membership.project, User.current) %>     + <%= join_in_course(membership.course, User.current) %>     <% end %> <% end %> <% else %> <% end %> - <%= l(:label_x_base_courses_member, :count => membership.project.members.count) %> - (<%= "#{membership.project.members.count}" %>)   + <%= l(:label_x_base_courses_member, :count => membership.course.members.count) %> + (<%= "#{membership.course.members.count}" %>)   <%= l(:label_homework) %> - (<%= link_to (membership.project.homeworks.count), {:controller => 'projects', :action => 'homework', :id => membership.project.identifier} %>) + (<%= link_to (membership.course.homeworks.count), {:controller => 'courses', :action => 'homework', :id => membership.course.id} %>)    <%= l(:label_course_news) %> - (<%= link_to (membership.project.news.count), {:controller => 'news', :action => 'index', :project_id => membership.project.identifier} %>) + (<%= link_to (membership.course.news.count), {:controller => 'news', :action => 'index', :course_id => membership.course.id} %>)

        - <%= membership.project.description %> + <%= membership.course.description %>

        - <% @course = Course.find_by_extra(membership.project.identifier) %> + <% @course = Course.find_by_extra(membership.course.extra) %> <% unless (@course.nil? || @course.teacher.nil? || @course.teacher.name.nil?) %> <%= l(:label_main_teacher) %> : <%= link_to(@course.teacher.realname, user_path(@course.teacher)) %> diff --git a/app/views/users/_course_list_have_entity.html.erb b/app/views/users/_course_list_have_entity.html.erb index 19fb88a6a..a0e721df5 100644 --- a/app/views/users/_course_list_have_entity.html.erb +++ b/app/views/users/_course_list_have_entity.html.erb @@ -1,6 +1,6 @@
        <%= l(:code_review) %>: + <% + label = URI.decode("#{review.repository_identifier + ':' if review.repository_identifier}#{review.path}#{'@' + review.revision if review.revision}:line #{review.line}") + -%> + <%= link_to(label, + :controller => 'code_review', :action => 'show', :id => project, :review_id => review.id, :repository_id => review.repository_identifier) %> +
        <%= l(:review_assigned_for) %>: + <% if assignment.path %> + <% + label = URI.decode("#{repository_id + ':' if repository_id}#{assignment.path}#{'@' + assignment.revision if assignment.revision}") + -%> + <%= link_to(label, + :controller => 'code_review', :action => 'show', :id => project, :assignment_id => assignment.id, :repository_id => repository_id) %> + <% elsif assignment.revision %> + <% + repo = project unless repository_id + repo ||= assignment.repository + %> + <%= l(:label_revision) + " "%> + <%= link_to_revision(assignment.revision, repo) %> + <% elsif assignment.attachment %> + <%= link_to(assignment.attachment.filename, :controller => 'attachments', :action => 'show', :id => attachment.id) %> + <% end %> +
        + + + <%= sort_header_tag "#{Issue.table_name}.id", :caption => '#' %> + <%= sort_header_tag "#{Issue.table_name}.status_id", :caption => l(:field_status)%> + <%= sort_header_tag "#{Issue.table_name}.subject", :caption => l(:field_subject)%> + <%= sort_header_tag 'path', :caption => l(:label_code_path)%> + + <%= sort_header_tag "#{Changeset.table_name}.revision", :caption => l(:label_revision)%> + <%= sort_header_tag "#{Changeset.table_name}.committer", :caption => l(:label_code_author)%> + <%= sort_header_tag 'user_id', :caption => l(:label_code_reviewer)%> + <%= sort_header_tag 'updated_at', :caption => l(:label_date) %> + + + + <% for review in @reviews %> + + + + + + + + + + + + + <% end %> + +
        + <%=h l(:label_code_line)%> +
        + <%= link_to review.issue.id.to_s, {:controller => 'issues', :action => 'show', + :id => review.issue.id}, :title => review.issue.subject %> + + <%=h review.issue.status %> + + <%=h review.issue.subject %> + + <% + review_path = URI.decode(review.path) + codepath = review_path + if (review_path.length > 55) + codepath = review_path[0, 15] + '...' + review_path[review_path.length - 35, 35] + end + -%> + <%= link_to(raw(codepath), {:controller => 'code_review', :action => 'show', :id => @project, :review_id => review.id}, :title => review_path) -%> + <%=h review.line %><%=h review.revision %><%=h review.committer %><%=h review.user.name %><%=h format_time(review.created_at) %>
        +

        <%= pagination_links_full @review_pages, @review_count %>

        + + <% end %> + + <% content_for :header_tags do %> + <%= stylesheet_link_tag "code_review.css", :plugin => "redmine_code_review", :media => "screen" %> + <% end %> + diff --git a/plugins/redmine_code_review/app/views/code_review_settings/_filters.html.erb b/plugins/redmine_code_review/app/views/code_review_settings/_filters.html.erb new file mode 100644 index 000000000..ec06aa1fc --- /dev/null +++ b/plugins/redmine_code_review/app/views/code_review_settings/_filters.html.erb @@ -0,0 +1,117 @@ +<% +# Code Review plugin for Redmine +# Copyright (C) 2009-2012 Haruyuki Iida +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +-%> + +

        + + <%= check_box_tag "auto_assign[filter_enabled]", true, @auto_assign.filter_enabled?, :onchange => 'setAutoAssignSettingFiltersEnable();' %><%=h l(:button_activate)%> + +

        +
        +
        +
        + <%= link_to_function(l(:button_add), "$('#add_filter_form').show('blind');", :class => 'icon icon-add') %> +
        + + + + + + + + + + + + <% @auto_assign.filters.each_with_index do |filter, i| -%> + <% tr_class = cycle('odd', 'even') -%> + + + + + + + + + + + + + + + <% end -%> + + + + + + + + + +
        #<%=h l(:auto_assign_filter_assign)%>/<%=h l(:auto_assign_filter_drop) %><%=h l(:auto_assign_filter_expression)%> <%=h l(:button_sort) %>
        <%= i + 1 %> + <%= hidden_field_tag "auto_assign[filters][#{i}][accept]", filter.accept? %> + <%= hidden_field_tag "auto_assign[filters][#{i}][expression]", filter.expression %> + <%= hidden_field_tag "auto_assign[filters][#{i}][order]", (i+1) * 10 %> + <%= filter.accept? ? l(:auto_assign_filter_assign) : l(:auto_assign_filter_drop)%> <%= filter.expression %> + <% + name = 'auto_assign_filter' + url = {:controller => 'code_review_settings', :action => 'sort', :id => @project, "#{name}[num]" => i} + -%> + <%= + link_to(image_tag('2uparrow.png', :alt => l(:label_sort_highest)), :remote => true, :url => url.merge({"#{name}[move_to]" => 'highest'}), :method => :post, :title => l(:label_sort_highest), :update => 'auto_assignment_filters', :submit => 'code_review_form') + + link_to(image_tag('1uparrow.png', :alt => l(:label_sort_higher)), :remote => true, :url => url.merge({"#{name}[move_to]" => 'higher'}), :method => :post, :title => l(:label_sort_higher), :update => 'auto_assignment_filters', :submit => 'code_review_form') + + link_to(image_tag('1downarrow.png', :alt => l(:label_sort_lower)), :remote => true, :url => url.merge({"#{name}[move_to]" => 'lower'}), :method => :post, :title => l(:label_sort_lower), :update => 'auto_assignment_filters', :submit => 'code_review_form') + + link_to(image_tag('2downarrow.png', :alt => l(:label_sort_lowest)), :remote => true, :url => url.merge({"#{name}[move_to]" => 'lowest'}), :method => :post, :title => l(:label_sort_lowest), :update => 'auto_assignment_filters', :submit => 'code_review_form') + -%> + + + + <%= link_to_function(l(:button_delete), "$('#auto_assign_tr_#{i}').remove();")%> + + <%= link_to_function(l(:button_edit), "$('#auto_assign_tr_#{i}').hide();$('#auto_assign_edit_tr_#{i}').show()")%> + + +
        + +
        +

        + + <%= select(:auto_assign, :accept_for_default, [[l(:auto_assign_filter_assign), true], [l(:auto_assign_filter_drop), false]]) %> +

        + +
        diff --git a/plugins/redmine_code_review/app/views/code_review_settings/_show.html.erb b/plugins/redmine_code_review/app/views/code_review_settings/_show.html.erb new file mode 100644 index 000000000..74454d49b --- /dev/null +++ b/plugins/redmine_code_review/app/views/code_review_settings/_show.html.erb @@ -0,0 +1,163 @@ +<% +# Code Review plugin for Redmine +# Copyright (C) 2010-2012 Haruyuki Iida +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +-%> +
        + + + <% + @code_review_setting = CodeReviewProjectSetting.find_or_create(@project) +%> + + <%= labelled_form_for :setting, @code_review_setting, + :url => {:controller => 'code_review_settings', + :action => 'update', :id => @project, :tab => 'code_review', + :partial => 'code_review_settings/update', + :setting_id => @code_review_setting.id}, :html => {:id => 'code_review_form'} do |f| %> + <%= error_messages_for 'code_review_setting' %> +
        + <%= f.hidden_field :lock_version %> +

        <%= f.check_box :tracker_in_review_dialog %>

        + + <%=h l(:select_tracker_for_code_reviews)%>: +

        <%= f.select :tracker_id, @project.trackers.collect {|t| [t.name, t.id]}, :required => true %>

        + + <%=h l(:select_tracker_for_code_review_assignment)%>: +

        <%= f.select :assignment_tracker_id, @project.trackers.collect {|t| [t.name, t.id]}, :required => true %>

        + +

        + <%= f.check_box :hide_code_review_tab %> +

        + +

        + + <%= f.radio_button(:auto_relation, CodeReviewProjectSetting::AUTORELATION_TYPE_RELATES) %> + <%=h l(:label_review_issue_relates) %> + + <%= f.radio_button(:auto_relation, CodeReviewProjectSetting::AUTORELATION_TYPE_BLOCKS) %> + <%=h l(:label_review_issue_blocks) %> + + <%= f.radio_button(:auto_relation, CodeReviewProjectSetting::AUTORELATION_TYPE_NONE) %> + <%=h l(:label_review_issue_do_nothing) %> + +

        +
        + +

        + <% + @auto_assign = @code_review_setting.auto_assign_settings + @auto_assign.subject = l(:code_review_requrest) if @auto_assign.subject.blank? + -%> + + <%= check_box_tag "auto_assign[enabled]", true, @auto_assign.enabled?, :onchange => 'setAutoAssignSettingFormEnable();'%><%=h l(:button_activate)%> +

        +
        +

        + + <%= select :auto_assign, :author_id, + (@project.users.collect {|user| + [user.name, user.id] + }), :selected => @auto_assign.author_id, :required => true %> +

        +

        + + <% @project.users.each do |user| %> + + <% end %> +

        +

        + + <%= text_field(:auto_assign, :subject, :size => 70) %> +

        +

        + + <%= text_area :auto_assign, :description, + :cols => 30, + :rows => 12, + :accesskey => accesskey(:edit), + :class => 'wiki-edit' %> +

        +

        +

        + <%= render :partial => 'code_review_settings/filters' %> +
        +

        +
        + +
        + <%= submit_tag l(:button_update) %> + <% end %> +
        +<%= wikitoolbar_for 'auto_assign_description' %> diff --git a/plugins/redmine_code_review/assets/images/closed_review.png b/plugins/redmine_code_review/assets/images/closed_review.png new file mode 100644 index 000000000..136593253 Binary files /dev/null and b/plugins/redmine_code_review/assets/images/closed_review.png differ diff --git a/plugins/redmine_code_review/assets/images/review.png b/plugins/redmine_code_review/assets/images/review.png new file mode 100644 index 000000000..5ff08181d Binary files /dev/null and b/plugins/redmine_code_review/assets/images/review.png differ diff --git a/plugins/redmine_code_review/assets/javascripts/code_review.js b/plugins/redmine_code_review/assets/javascripts/code_review.js new file mode 100644 index 000000000..625f376c9 --- /dev/null +++ b/plugins/redmine_code_review/assets/javascripts/code_review.js @@ -0,0 +1,354 @@ +/* +# Code Review plugin for Redmine +# Copyright (C) 2009-2013 Haruyuki Iida +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +var topZindex = 1000; +var action_type = ''; +var rev = ''; +var rev_to = ''; +var path = ''; +var urlprefix = ''; +var review_form_dialog = null; +var add_form_title = null; +var review_dialog_title = null; +var repository_id = null; +var filenames = []; + +var ReviewCount = function(total, open, progress){ + this.total = total; + this.open = open; + this.closed = total - open; + this.progress = progress +}; + +var CodeReview = function(id) { + this.id = id; + this.path = ''; + this.line = 0; + this.url = ''; + this.is_closed = false; +}; + +var review_counts = new Array(); +var code_reviews_map = new Array(); +var code_reviews_dialog_map = new Array(); + +function UpdateRepositoryView(title) { + var header = $("table.changesets thead tr:first"); + var th = $('
        ',{ + 'class':'progress' + }); + td.html(review.progress); + $(this.parentNode.parentNode).append(td); + }); + } +//add function $.down +if(! $.fn.down) +(function($) { + $.fn.down = function() { + var el = this[0] && this[0].firstChild; + while (el && el.nodeType != 1) + el = el.nextSibling; + return $(el); + }; +})(jQuery); + +function UpdateRevisionView() { + $('li.change').each(function(){ + var li = $(this); + if (li.hasClass('folder')) return; + + var a = li.down('a'); + if (a.size() == 0) return; + var path = a.attr('href').replace(urlprefix, '').replace(/\?.*$/, ''); + + var reviewlist = code_reviews_map[path]; + if (reviewlist == null) return; + + var ul = $('
          '); + for (var j = 0; j < reviewlist.length; j++) { + var review = reviewlist[j]; + var icon = review.is_closed? 'icon-closed-review': 'icon-review'; + var item = $('
        • ', { + 'class': 'icon ' + icon + ' code_review_summary' + }); + item.html(review.url); + ul.append(item); + } + li.append(ul); + }); +} + +function setAddReviewButton(url, change_id, image_tag, is_readonly, is_diff, attachment_id){ + var filetables = []; + var j = 0; + $('table').each(function(){ + if($(this).hasClass('filecontent')){ + filetables[j++] = this; + } + }); + j = 0; + $('table.filecontent th.filename').each(function(){ + filenames[j] = $.trim($(this).text()); + j++; + }); + addReviewUrl = url + '?change_id=' + change_id + '&action_type=' + action_type + + '&rev=' + rev + '&rev_to=' + rev_to + + '&attachment_id=' + attachment_id + '&repository_id=' + encodeURIComponent(repository_id); + if (path != null && path.length > 0) { + addReviewUrl = addReviewUrl + '&path=' + encodeURIComponent(path); + } + var num = 0; + if (is_diff) { + num = 1; + } + var i, l, tl; + for (i = 0, tl = filetables.length; i < tl; i++) { + var table = filetables[i]; + var trs = table.getElementsByTagName('tr'); + + for (j = 0,l = trs.length; j < l; j++) { + var tr = trs[j]; + var ths = tr.getElementsByTagName('th'); + + var th = ths[num]; + if (th == null) { + continue; + } + + var th_html = th.innerHTML; + + var line = th_html.match(/[0-9]+/); + if (line == null) { + continue; + } + + var span_html = ''; + + if (!is_readonly) { + span_html += image_tag; + } + span_html += ''; + th.innerHTML = th_html + span_html; + + var img = th.getElementsByTagName('img')[0]; + if (img != null ) { + img.id = 'add_revew_img_' + line + '_' + i; + $(img).click(clickPencil); + } + } + } + + +} + +function clickPencil(e) +{ +// alert('$(e.target).attr("id") = ' + $(e.target).attr("id")); + var result = $(e.target).attr("id").match(/([0-9]+)_([0-9]+)/); + var line = result[1]; + var file_count = eval(result[2]); + var url = addReviewUrl + '&line=' + line + '&file_count=' + file_count; + + if (path == null || path.length == 0) { + url = url + '&path=' + encodeURIComponent(filenames[file_count]) + '&diff_all=true'; + } + addReview(url); + formPopup(e.pageX, e.pageY); + e.preventDefault(); +} +var addReviewUrl = null; +var showReviewUrl = null; +var showReviewImageTag = null; +var showClosedReviewImageTag = null; + +function setShowReviewButton(line, review_id, is_closed, file_count) { + //alert('file_count = ' + file_count); + var span = $('#review_span_' + line + '_' + file_count); + if (span.size() == 0) { + return; + } + var innerSpan = $('',{id: 'review_' + review_id}); + span.append(innerSpan); + innerSpan.html(is_closed? showClosedReviewImageTag : showReviewImageTag); + var div = $('
          ', { + 'class':'draggable', + id: 'show_review_' + review_id + }); + $('#code_review').append(div); + innerSpan.down('img').click(function(e) { + var review_id = $(e.target).parent().attr('id').match(/[0-9]+/)[0]; + var span = $('#review_' + review_id); // span element of view review button + var pos = span.offset(); + showReview(showReviewUrl, review_id, pos.left + 10 + 5, pos.top + 25); + }); +} + +function popupReview(review_id) { + var span = $('#review_' + review_id); // span element of view review button + var pos = span.offset(); + $('html,body').animate({ scrollTop: pos.top }, + {duration: 'fast', + complete: function(){showReview(showReviewUrl, review_id, pos.left + 10 + 5, pos.top)}}); + // position and show popup dialog + // create popup dialog + //var win = showReview(showReviewUrl, review_id, pos.left + 10 + 5, pos.top); +// win.toFront(); +} + +function showReview(url, review_id, x, y) { + if (code_reviews_dialog_map[review_id] != null) { + var cur_win = code_reviews_dialog_map[review_id]; + cur_win.hide(); + code_reviews_dialog_map[review_id] = null; + } + $('#show_review_' + review_id).load(url, {review_id: review_id}); + var review = getReviewObjById(review_id); + + var win = $('#show_review_' + review_id).dialog({ + show: {effect:'scale'},// ? 'top-left' + //position: [x, y + 5], + width:640, + zIndex: topZindex, + title: review_dialog_title + }); +// win.getContent().style.color = "#484848"; +// win.getContent().style.background = "#ffffff"; + topZindex++; + code_reviews_dialog_map[review_id] = win; + return win +} + +function getReviewObjById(review_id) { + for (var reviewlist in code_reviews_map) { + for (var i = 0; i < reviewlist.length; i++) { + var review = reviewlist[i]; + if (review.id == review_id) { + return review; + } + } + } + return null; +} + +function formPopup(x, y){ + //@see http://docs.jquery.com/UI/Effects/Scale + var win = $('#review-form-frame').dialog({ + show: {effect:'scale', direction: 'both'},// ? 'top-left' +// position: [x, y + 5], + width:640, + zIndex: topZindex, + title: add_form_title + }); +// win.getContent().style.background = "#ffffff"; + if (review_form_dialog != null) { + review_form_dialog.destroy(); + review_form_dialog = null; + } + review_form_dialog = win; + topZindex += 10; + return false; +} + +function hideForm() { + if (review_form_dialog == null) { + return; + } + review_form_dialog.dialog('close'); + review_form_dialog = null; + $('#review-form').html(''); +} +function addReview(url) { + $('#review-form').load(url); +} + +function deleteReview(review_id) { + $('show_review_' + review_id).remove(); + $('review_' + review_id).remove(); + +} + +function changeImage(review_id, is_closed) { + var span = $('review_' + review_id); + var new_image = null; + var dummy = new Element('span'); + if (is_closed) { + dummy.insert(showClosedReviewImageTag); + } + else { + dummy.insert(showReviewImageTag); + } + new_image = dummy.down().getAttribute('src'); + //alert(new_image); + span.down('img').setAttribute('src', new_image); + +} + +function make_addreview_link(project, link) { + var alist = $('#content p a'); + if (alist == null) { + return; + } + var a = alist[0]; + var p = a.parentNode; + p.innerHTML = p.innerHTML + " | " + link; +} + +function call_update_revisions(url) { + var changeset_ids = ''; + var links = $$('table.changesets tbody tr.changeset td.id a'); + for (var i = 0; i < links.length; i++) { + var link = links[i]; + var href = link.getAttribute('href'); + var id = href.replace(/^.*\/revisions\//, ''); + if (i > 0) { + changeset_ids += ','; + } + changeset_ids += id; + } + new Ajax.Updater('code_review_revisions', url, + { + evalScripts:true, + method:'get', + parameters: 'changeset_ids=' + encodeURI(changeset_ids) + }); +} + +$.fn.serialize2json = function() +{ + var o = {}; + var a = this.serializeArray(); + $.each(a, function() { + if (o[this.name]) { + if (!o[this.name].push) { + o[this.name] = [o[this.name]]; + } + o[this.name].push(this.value || ''); + } else { + o[this.name] = this.value || ''; + } + }); + return o; +}; \ No newline at end of file diff --git a/plugins/redmine_code_review/assets/stylesheets/activity.css b/plugins/redmine_code_review/assets/stylesheets/activity.css new file mode 100644 index 000000000..e3cdc3d55 --- /dev/null +++ b/plugins/redmine_code_review/assets/stylesheets/activity.css @@ -0,0 +1,4 @@ + +dt.code_review { + background-image: url(../images/review.png); +} \ No newline at end of file diff --git a/plugins/redmine_code_review/assets/stylesheets/code_review.css b/plugins/redmine_code_review/assets/stylesheets/code_review.css new file mode 100644 index 000000000..11939ae79 --- /dev/null +++ b/plugins/redmine_code_review/assets/stylesheets/code_review.css @@ -0,0 +1,97 @@ +/* +# Code Review plugin for Redmine +# Copyright (C) 2009 Haruyuki Iida +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ +#review-form-frame { +height: 100%; +} + +.autoscroll table.filecontent th.line-num { + white-space: nowrap; + vertical-align: bottom; + padding-top: 0; + padding-bottom: 0; + text-align:left; +} + +table.filecontent th.line-num img{ + padding: 0; + margin: 0; + cursor: pointer; +} + + +.code-review-form-title { + background-color: #002059; + color: white; + padding-left: 2px; + padding-right: 2px; + cursor: default; +} + + +.code_review_viewer { + + min-width: 300px; + /* + max-width: 60%; + */ + /* max-height: 400px; */ +} + +.code_review_viewer .issue{ + +} + +.code_review_body { + background-color: white; + + padding:2px; + +} + +#code_review_list table.list td { + text-align: center; +} + +#code_review_list table.list td.path { + text-align: left; +} + +#code_review_list table.list td.subject { + text-align: left; +} + +.icon-review { + background-image: url(../images/review.png); + background-repeat: no-repeat; +} + +.icon-closed-review { + background-image: url(../images/closed_review.png); + background-repeat: no-repeat; +} + +.icon-settings { + background-image: url(../../../images/changeset.png); + background-repeat: no-repeat; +} + + +li.code_review_summary { + list-style-type: none; +} \ No newline at end of file diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/MIT-LICENSE b/plugins/redmine_code_review/assets/stylesheets/window_js/MIT-LICENSE new file mode 100644 index 000000000..5bcdad1bd --- /dev/null +++ b/plugins/redmine_code_review/assets/stylesheets/window_js/MIT-LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2006 Sébastien Gruhier (http://xilinus.com, http://itseb.com) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/alert.css b/plugins/redmine_code_review/assets/stylesheets/window_js/alert.css new file mode 100644 index 000000000..432d14e36 --- /dev/null +++ b/plugins/redmine_code_review/assets/stylesheets/window_js/alert.css @@ -0,0 +1,119 @@ +.overlay_alert { + background-color: #85BBEF; + filter:alpha(opacity=60); + -moz-opacity: 0.6; + opacity: 0.6; +} + +.alert_nw { + width: 5px; + height: 5px; + background: transparent url(alert/top_left.gif) no-repeat bottom left; +} + +.alert_n { + height: 5px; + background: transparent url(alert/top.gif) repeat-x bottom left; +} + +.alert_ne { + width: 5px; + height: 5px; + background: transparent url(alert/top_right.gif) no-repeat bottom left +} + +.alert_e { + width: 5px; + background: transparent url(alert/right.gif) repeat-y 0 0; +} + +.alert_w { + width: 5px; + background: transparent url(alert/left.gif) repeat-y 0 0; +} + +.alert_sw { + width: 5px; + height: 5px; + background: transparent url(alert/bottom_left.gif) no-repeat 0 0; +} + +.alert_s { + height: 5px; + background: transparent url(alert/bottom.gif) repeat-x 0 0; +} + +.alert_se, .alert_sizer { + width: 5px; + height: 5px; + background: transparent url(alert/bottom_right.gif) no-repeat 0 0; +} + +.alert_close { + width:0px; + height:0px; + display:none; +} + +.alert_minimize { + width:0px; + height:0px; + display:none; +} + +.alert_maximize { + width:0px; + height:0px; + display:none; +} + +.alert_title { + float:left; + height:1px; + width:100%; +} + +.alert_content { + overflow:visible; + color: #000; + font-family: Tahoma, Arial, sans-serif; + font: 12px arial; + background: #FFF; +} + +/* For alert/confirm dialog */ +.alert_window { + background: #FFF; + padding:20px; + margin-left:auto; + margin-right:auto; + width:400px; +} + +.alert_message { + font: 12px arial; + width:100%; + color:#F00; + padding-bottom:10px; +} + +.alert_buttons { + text-align:center; + width:100%; +} + +.alert_buttons input { + width:20%; + margin:10px; +} + +.alert_progress { + float:left; + margin:auto; + text-align:center; + width:100%; + height:16px; + background: #FFF url('alert/progress.gif') no-repeat center center +} + + diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/alert/bottom.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/alert/bottom.gif new file mode 100644 index 000000000..9870f5224 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/alert/bottom.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/alert/bottom_left.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/alert/bottom_left.gif new file mode 100644 index 000000000..583f113fa Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/alert/bottom_left.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/alert/bottom_right.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/alert/bottom_right.gif new file mode 100644 index 000000000..230ba12be Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/alert/bottom_right.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/alert/left.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/alert/left.gif new file mode 100644 index 000000000..4a3fab520 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/alert/left.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/alert/overlay.png b/plugins/redmine_code_review/assets/stylesheets/window_js/alert/overlay.png new file mode 100644 index 000000000..2f3344e5c Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/alert/overlay.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/alert/progress.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/alert/progress.gif new file mode 100644 index 000000000..529e72f45 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/alert/progress.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/alert/right.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/alert/right.gif new file mode 100644 index 000000000..85ba9e2a5 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/alert/right.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/alert/top.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/alert/top.gif new file mode 100644 index 000000000..8f6193664 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/alert/top.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/alert/top_left.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/alert/top_left.gif new file mode 100644 index 000000000..fabb33a18 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/alert/top_left.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/alert/top_right.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/alert/top_right.gif new file mode 100644 index 000000000..9fec6fa2b Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/alert/top_right.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/alert_lite.css b/plugins/redmine_code_review/assets/stylesheets/window_js/alert_lite.css new file mode 100644 index 000000000..c2ad538ca --- /dev/null +++ b/plugins/redmine_code_review/assets/stylesheets/window_js/alert_lite.css @@ -0,0 +1,88 @@ +.overlay_alert_lite { + background-color: #85BBEF; + filter:alpha(opacity=60); + -moz-opacity: 0.6; + opacity: 0.6; +} + +.alert_lite_sizer { + width:0px; + height:0px; + display:none; +} + +.alert_lite_close { + width:0px; + height:0px; + display:none; +} + +.alert_lite_minimize { + width:0px; + height:0px; + display:none; +} + +.alert_lite_maximize { + width:0px; + height:0px; + display:none; +} + +.alert_lite_title { + width:0px; + height:0px; + display:none; +} + +.alert_lite_content { + overflow:auto; + color: #000; + font-family: Tahoma, Arial, sans-serif; + font-size: 10px; + background: #FFF; +} + + +/* For alert/confirm dialog */ +.alert_lite_window { + border:1px solid #F00; + background: #FFF; + padding:20px; + margin-left:auto; + margin-right:auto; + width:400px; +} + +.alert_lite_message { + font-size:16px; + text-align:center; + width:100%; + color:#F00; + padding-bottom:10px; +} + +.alert_lite_buttons { + text-align:center; + width:100%; +} + +.alert_lite_buttons input { + width:20%; + margin:10px; +} + +.alert_lite_progress { + float:left; + margin:auto; + text-align:center; + width:100%; + height:16px; + background: #FFF url('alert/progress.gif') no-repeat center center +} + +table.alert_lite_header { + border:1px solid #F00; + background:#FFF +} + diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube.css b/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube.css new file mode 100644 index 000000000..7d2790e75 --- /dev/null +++ b/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube.css @@ -0,0 +1,150 @@ +.overlay_alphacube { + background-color: #85BBEF; + filter:alpha(opacity=60); + -moz-opacity: 0.6; + opacity: 0.6; +} + +.alphacube_nw { + background: transparent url(alphacube/left-top.gif) no-repeat 0 0; + width:10px; + height:25px; +} + +.alphacube_n { + background: transparent url(alphacube/top-middle.gif) repeat-x 0 0; + height:25px; +} + +.alphacube_ne { + background: transparent url(alphacube/right-top.gif) no-repeat 0 0; + width:10px; + height:25px; +} + +.alphacube_w { + background: transparent url(alphacube/frame-left.gif) repeat-y top left; + width:7px; +} + +.alphacube_e { + background: transparent url(alphacube/frame-right.gif) repeat-y top right; + width:7px; +} + +.alphacube_sw { + background: transparent url(alphacube/bottom-left-c.gif) no-repeat 0 0; + width:7px; + height:7px; +} + +.alphacube_s { + background: transparent url(alphacube/bottom-middle.gif) repeat-x 0 0; + height:7px; +} + +.alphacube_se, .alphacube_sizer { + background: transparent url(alphacube/bottom-right-c.gif) no-repeat 0 0; + width:7px; + height:7px; +} + +.alphacube_sizer { + cursor:se-resize; +} + +.alphacube_close { + width: 23px; + height: 23px; + background: transparent url(alphacube/button-close-focus.gif) no-repeat 0 0; + position:absolute; + top:0px; + right:11px; + cursor:pointer; + z-index:1000; +} + +.alphacube_minimize { + width: 23px; + height: 23px; + background: transparent url(alphacube/button-min-focus.gif) no-repeat 0 0; + position:absolute; + top:0px; + right:55px; + cursor:pointer; + z-index:1000; +} + +.alphacube_maximize { + width: 23px; + height: 23px; + background: transparent url(alphacube/button-max-focus.gif) no-repeat 0 0; + position:absolute; + top:0px; + right:33px; + cursor:pointer; + z-index:1000; +} + +.alphacube_title { + float:left; + height:14px; + font-size:14px; + text-align:center; + margin-top:2px; + width:100%; + color:#123456; +} + +.alphacube_content { + overflow:auto; + color: #000; + font-family: Tahoma, Arial, sans-serif; + font: 12px arial; + background:#FDFDFD; +} + +/* For alert/confirm dialog */ +.alphacube_window { + border:1px solid #F00; + background: #FFF; + padding:20px; + margin-left:auto; + margin-right:auto; + width:400px; +} + +.alphacube_message { + font: 12px arial; + text-align:center; + width:100%; + padding-bottom:10px; +} + +.alphacube_buttons { + text-align:center; + width:100%; +} + +.alphacube_buttons input { + width:20%; + margin:10px; +} + +.alphacube_progress { + float:left; + margin:auto; + text-align:center; + width:100%; + height:16px; + background: #FFF url('alert/progress.gif') no-repeat center center +} + +.alphacube_wired_frame { + background: #FFF; + filter:alpha(opacity=60); + -moz-opacity: 0.6; + opacity: 0.6; +} + + diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube/bottom-left-c.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube/bottom-left-c.gif new file mode 100644 index 000000000..531acdc51 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube/bottom-left-c.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube/bottom-middle.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube/bottom-middle.gif new file mode 100644 index 000000000..d4ce3be02 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube/bottom-middle.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube/bottom-right-c.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube/bottom-right-c.gif new file mode 100644 index 000000000..2164c22c1 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube/bottom-right-c.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube/button-close-focus.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube/button-close-focus.gif new file mode 100644 index 000000000..99f635c10 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube/button-close-focus.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube/button-max-focus.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube/button-max-focus.gif new file mode 100644 index 000000000..1708a1e0d Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube/button-max-focus.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube/button-min-focus.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube/button-min-focus.gif new file mode 100644 index 000000000..ff69d1b20 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube/button-min-focus.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube/frame-left.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube/frame-left.gif new file mode 100644 index 000000000..543f13db6 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube/frame-left.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube/frame-right.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube/frame-right.gif new file mode 100644 index 000000000..5d7afef93 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube/frame-right.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube/left-top.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube/left-top.gif new file mode 100644 index 000000000..8373aaae1 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube/left-top.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube/right-top.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube/right-top.gif new file mode 100644 index 000000000..77cf65ef8 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube/right-top.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube/top-middle.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube/top-middle.gif new file mode 100644 index 000000000..9cab17d53 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/alphacube/top-middle.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/behavior.htc b/plugins/redmine_code_review/assets/stylesheets/window_js/behavior.htc new file mode 100644 index 000000000..437c5ec92 --- /dev/null +++ b/plugins/redmine_code_review/assets/stylesheets/window_js/behavior.htc @@ -0,0 +1,51 @@ + + + + \ No newline at end of file diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/darkX.css b/plugins/redmine_code_review/assets/stylesheets/window_js/darkX.css new file mode 100644 index 000000000..2f83cfd46 --- /dev/null +++ b/plugins/redmine_code_review/assets/stylesheets/window_js/darkX.css @@ -0,0 +1,121 @@ +.overlay_darkX { + background-color: #85BBEF; + filter:alpha(opacity=60); + -moz-opacity: 0.6; + opacity: 0.6; +} + +.darkX_nw { + background: transparent url(darkX/titlebar-left-focused.png) no-repeat 0 0; + width:6px; + height:21px; +} +.darkX_n { + background: transparent url(darkX/titlebar-mid-focused.png) repeat-x 0 0; + height:21px; +} +.darkX_ne { + background: transparent url(darkX/titlebar-right-focused.png) no-repeat 0 0; + width:6px; + height:21px; +} +.darkX_w { + background: transparent url(darkX/frame-left-focused.png) repeat-y top left; + width:3px; +} + +.darkX_e { + background: transparent url(darkX/frame-right-focused.png) repeat-y top right; + width:3px; +} + +.darkX_sw { + background: transparent url(darkX/frame-bottom-left-focused.png) no-repeat 0 0; + width:5px; + height:3px; +} +.darkX_s { + background: transparent url(darkX/frame-bottom-mid-focused.png) repeat-x 0 0; + height:3px; +} +.darkX_se, .darkX_sizer { + background: transparent url(darkX/frame-bottom-right-focused.png) no-repeat 0 0; + width:5px; + height:3px; +} + +.darkX_sizer { + cursor:se-resize; +} + +.darkX_close { + width: 21px; + height: 21px; + background: transparent url(darkX/button-close-focused.png) no-repeat 0 0; + position:absolute; + top:0px; + right:5px; + cursor:pointer; + z-index:1000; +} + +.darkX_minimize { + width: 21px; + height: 21px; + background: transparent url(darkX/button-minimize-focused.png) no-repeat 0 0; + position:absolute; + top:0px; + right:26px; + cursor:pointer; + z-index:1000; +} + +.darkX_maximize { + width: 21px; + height: 21px; + background: transparent url(darkX/button-maximize-focused.png) no-repeat 0 0; + position:absolute; + top:0px; + right:47px; + cursor:pointer; + z-index:1000; +} + + +.darkX_title { + float:left; + height:14px; + font-size:12px; + text-align:center; + margin-top:2px; + width:100%; + color:#FFF; +} + +.darkX_content { + overflow:auto; + color: #E6DF2A; + font-family: Tahoma, Arial, sans-serif; + font-size: 14px; + background:#5E5148; +} + + +/* FOR IE */ +* html .darkX_minimize { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/darkX/button-minimize-focused.png", sizingMethod="crop"); +} + +* html .darkX_maximize { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/darkX/button-maximize-focused.png", sizingMethod="scale"); +} + +* html .darkX_close { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/darkX/button-close-focused.png", sizingMethod="crop"); +} diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/darkX/button-close-focused.png b/plugins/redmine_code_review/assets/stylesheets/window_js/darkX/button-close-focused.png new file mode 100644 index 000000000..da5a8ac43 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/darkX/button-close-focused.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/darkX/button-maximize-focused.png b/plugins/redmine_code_review/assets/stylesheets/window_js/darkX/button-maximize-focused.png new file mode 100644 index 000000000..b0bd9cd6f Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/darkX/button-maximize-focused.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/darkX/button-minimize-focused.png b/plugins/redmine_code_review/assets/stylesheets/window_js/darkX/button-minimize-focused.png new file mode 100644 index 000000000..b04e18f59 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/darkX/button-minimize-focused.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/darkX/frame-bottom-left-focused.png b/plugins/redmine_code_review/assets/stylesheets/window_js/darkX/frame-bottom-left-focused.png new file mode 100644 index 000000000..7d89f7b0a Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/darkX/frame-bottom-left-focused.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/darkX/frame-bottom-mid-focused.png b/plugins/redmine_code_review/assets/stylesheets/window_js/darkX/frame-bottom-mid-focused.png new file mode 100644 index 000000000..e50eacccc Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/darkX/frame-bottom-mid-focused.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/darkX/frame-bottom-right-focused.png b/plugins/redmine_code_review/assets/stylesheets/window_js/darkX/frame-bottom-right-focused.png new file mode 100644 index 000000000..891565911 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/darkX/frame-bottom-right-focused.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/darkX/frame-left-focused.png b/plugins/redmine_code_review/assets/stylesheets/window_js/darkX/frame-left-focused.png new file mode 100644 index 000000000..ff9f336f2 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/darkX/frame-left-focused.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/darkX/frame-right-focused.png b/plugins/redmine_code_review/assets/stylesheets/window_js/darkX/frame-right-focused.png new file mode 100644 index 000000000..f69ea0069 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/darkX/frame-right-focused.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/darkX/titlebar-left-focused.png b/plugins/redmine_code_review/assets/stylesheets/window_js/darkX/titlebar-left-focused.png new file mode 100644 index 000000000..1436e8410 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/darkX/titlebar-left-focused.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/darkX/titlebar-mid-focused.png b/plugins/redmine_code_review/assets/stylesheets/window_js/darkX/titlebar-mid-focused.png new file mode 100644 index 000000000..f7be50b14 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/darkX/titlebar-mid-focused.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/darkX/titlebar-right-focused.png b/plugins/redmine_code_review/assets/stylesheets/window_js/darkX/titlebar-right-focused.png new file mode 100644 index 000000000..ae23785d4 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/darkX/titlebar-right-focused.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/debug.css b/plugins/redmine_code_review/assets/stylesheets/window_js/debug.css new file mode 100644 index 000000000..69e3b7fc2 --- /dev/null +++ b/plugins/redmine_code_review/assets/stylesheets/window_js/debug.css @@ -0,0 +1,25 @@ +div.inspector div.inspectable { + padding: 0.25em 0 0.25em 1em; + background-color: Gray; + color: white; + border: outset 2px white; + cursor: pointer; +} + +div.inspector div.child { + margin: 0 0 0 1em; +} + +#debug_window_content { /* DIV container for debug sizing*/ + width:250px; + height:100px; + background-color:#000; +} + +#debug { /* DIV container for debug contents*/ + padding:3px; + color:#0f0; + font-family:monaco, Tahoma, Verdana, Arial, Helvetica, sans-serif; + font-size:10px; +} + diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/default.css b/plugins/redmine_code_review/assets/stylesheets/window_js/default.css new file mode 100644 index 000000000..6ab13789d --- /dev/null +++ b/plugins/redmine_code_review/assets/stylesheets/window_js/default.css @@ -0,0 +1,155 @@ +.overlay_dialog { + background-color: #666666; + filter:alpha(opacity=60); + -moz-opacity: 0.6; + opacity: 0.6; +} + +.overlay___invisible__ { + background-color: #666666; + filter:alpha(opacity=0); + -moz-opacity: 0; + opacity: 0; +} + +.dialog_nw { + width: 9px; + height: 23px; + background: transparent url(default/top_left.gif) no-repeat 0 0; +} + +.dialog_n { + background: transparent url(default/top_mid.gif) repeat-x 0 0; + height: 23px; +} + +.dialog_ne { + width: 9px; + height: 23px; + background: transparent url(default/top_right.gif) no-repeat 0 0; +} + +.dialog_e { + width: 2px; + background: transparent url(default/center_right.gif) repeat-y 0 0; +} + +.dialog_w { + width: 2px; + background: transparent url(default/center_left.gif) repeat-y 0 0; +} + +.dialog_sw { + width: 9px; + height: 19px; + background: transparent url(default/bottom_left.gif) no-repeat 0 0; +} + +.dialog_s { + background: transparent url(default/bottom_mid.gif) repeat-x 0 0; + height: 19px; +} + +.dialog_se { + width: 9px; + height: 19px; + background: transparent url(default/bottom_right.gif) no-repeat 0 0; +} + +.dialog_sizer { + width: 9px; + height: 19px; + background: transparent url(default/sizer.gif) no-repeat 0 0; + cursor:se-resize; +} + +.dialog_close { + width: 14px; + height: 14px; + background: transparent url(default/close.gif) no-repeat 0 0; + position:absolute; + top:5px; + left:8px; + cursor:pointer; + z-index:2000; +} + +.dialog_minimize { + width: 14px; + height: 15px; + background: transparent url(default/minimize.gif) no-repeat 0 0; + position:absolute; + top:5px; + left:28px; + cursor:pointer; + z-index:2000; +} + +.dialog_maximize { + width: 14px; + height: 15px; + background: transparent url(default/maximize.gif) no-repeat 0 0; + position:absolute; + top:5px; + left:49px; + cursor:pointer; + z-index:2000; +} + +.dialog_title { + float:left; + height:14px; + font-family: Tahoma, Arial, sans-serif; + font-size:12px; + text-align:center; + width:100%; + color:#000; +} + +.dialog_content { + overflow:auto; + color: #DDD; + font-family: Tahoma, Arial, sans-serif; + font-size: 10px; + background-color:#123; +} + +.top_draggable, .bottom_draggable { + cursor:move; +} + +.status_bar { + font-size:12px; +} +.status_bar input{ + font-size:12px; +} + +.wired_frame { + display: block; + position: absolute; + border: 1px #000 dashed; +} + +/* DO NOT CHANGE THESE VALUES*/ +.dialog { + display: block; + position: absolute; +} + +.dialog table.table_window { + border-collapse: collapse; + border-spacing: 0; + width: 100%; + margin: 0px; + padding:0px; +} + +.dialog table.table_window td , .dialog table.table_window th { + padding: 0; +} + +.dialog .title_window { + -moz-user-select:none; +} + diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/default/bottom_left.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/default/bottom_left.gif new file mode 100644 index 000000000..4c73d3563 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/default/bottom_left.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/default/bottom_mid.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/default/bottom_mid.gif new file mode 100644 index 000000000..9205d3019 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/default/bottom_mid.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/default/bottom_right.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/default/bottom_right.gif new file mode 100644 index 000000000..8d002eeb8 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/default/bottom_right.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/default/bottom_right_resize.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/default/bottom_right_resize.gif new file mode 100644 index 000000000..649b0d870 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/default/bottom_right_resize.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/default/center_left.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/default/center_left.gif new file mode 100644 index 000000000..79e7a1cca Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/default/center_left.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/default/center_right.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/default/center_right.gif new file mode 100644 index 000000000..554c55c86 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/default/center_right.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/default/clear.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/default/clear.gif new file mode 100644 index 000000000..c10b16694 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/default/clear.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/default/close.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/default/close.gif new file mode 100644 index 000000000..31ef5a394 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/default/close.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/default/inspect.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/default/inspect.gif new file mode 100644 index 000000000..ebeeb02f6 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/default/inspect.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/default/maximize.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/default/maximize.gif new file mode 100644 index 000000000..892a0f08c Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/default/maximize.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/default/minimize.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/default/minimize.gif new file mode 100644 index 000000000..a7214167b Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/default/minimize.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/default/overlay.png b/plugins/redmine_code_review/assets/stylesheets/window_js/default/overlay.png new file mode 100644 index 000000000..648e71ed6 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/default/overlay.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/default/resize.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/default/resize.gif new file mode 100644 index 000000000..c44070259 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/default/resize.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/default/sizer.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/default/sizer.gif new file mode 100644 index 000000000..649b0d870 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/default/sizer.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/default/top_left.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/default/top_left.gif new file mode 100644 index 000000000..774538ac6 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/default/top_left.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/default/top_mid.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/default/top_mid.gif new file mode 100644 index 000000000..6124e78bd Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/default/top_mid.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/default/top_right.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/default/top_right.gif new file mode 100644 index 000000000..fbc94bf2b Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/default/top_right.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/iefix/blank.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/iefix/blank.gif new file mode 100644 index 000000000..75b945d25 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/iefix/blank.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/iefix/iepngfix.css b/plugins/redmine_code_review/assets/stylesheets/window_js/iefix/iepngfix.css new file mode 100644 index 000000000..257a1b1e3 --- /dev/null +++ b/plugins/redmine_code_review/assets/stylesheets/window_js/iefix/iepngfix.css @@ -0,0 +1,3 @@ +/* PNG fix for all themes that uses PNG images on IE */ +td, div { behavior: url(../themes/iefix/iepngfix.htc) } + diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/iefix/iepngfix.htc b/plugins/redmine_code_review/assets/stylesheets/window_js/iefix/iepngfix.htc new file mode 100644 index 000000000..a6c683b9f --- /dev/null +++ b/plugins/redmine_code_review/assets/stylesheets/window_js/iefix/iepngfix.htc @@ -0,0 +1,54 @@ + + + + + \ No newline at end of file diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/lighting.css b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting.css new file mode 100644 index 000000000..95ec287a9 --- /dev/null +++ b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting.css @@ -0,0 +1,960 @@ +.overlay___invisible__ { + background-color: #666; + filter:alpha(opacity=0); + -moz-opacity: 0; + opacity: 0; +} + +.top_draggable, .bottom_draggable { + cursor:move; +} + +.status_bar { + font-size:12px; +} +.status_bar input{ + font-size:12px; +} + +.wired_frame { + display:block; + position:absolute; + border:1px #000 dashed; +} + + + +.overlay_bluelighting { + background-color:#FFF; + filter:alpha(opacity=60); + -moz-opacity:0.6; + opacity:0.6; +} + +.bluelighting_wired_frame { + background:#FFF; + filter:alpha(opacity=60); + -moz-opacity:0.6; + opacity:0.6; +} + +.bluelighting_nw { + background:transparent url(lighting/top-left-blue.png) no-repeat 0 0; + width:9px; + height:28px; +} + +.bluelighting_n { + background:transparent url(lighting/top-middle-blue.png) repeat-x 0 0; + height:28px; +} + +.bluelighting_ne { + background:transparent url(lighting/top-right-blue.png) no-repeat 0 0; + width:15px; + height:28px; +} + +.bluelighting_w { + background:transparent url(lighting/left-blue.png) repeat-y top left; + width:9px; +} + +.bluelighting_e { + background:transparent url(lighting/right-blue.png) repeat-y top right; + width:15px; +} + +.bluelighting_sw { + background:transparent url(lighting/bottom-left-blue.png) no-repeat 0 0; + width:9px; + height:15px; +} + +.bluelighting_s { + background:transparent url(lighting/bottom-middle-blue.png) repeat-x 0 0; + height:15px; +} + +.bluelighting_se, .bluelighting_sizer { + background:transparent url(lighting/bottom-right-blue.png) no-repeat 0 0; + width:15px; + height:15px; +} + +.bluelighting_sizer { + cursor:se-resize; +} + +.bluelighting_close { + width:15px; + height:9px; + background:transparent url(lighting/button-close-blue.png) no-repeat 0 0; + position:absolute; + top:11px; + right:10px; + cursor:pointer; + z-index:1000; +} + +.bluelighting_maximize { + width:15px; + height:9px; + background:transparent url(lighting/button-maximize-blue.png) no-repeat 0 0; + position:absolute; + top:11px; + right:25px; + cursor:pointer; + z-index:1000; +} + +.bluelighting_minimize { + width:15px; + height:9px; + background:transparent url(lighting/button-minimize-blue.png) no-repeat 0 0; + position:absolute; + top:11px; + right:40px; + cursor:pointer; + z-index:1000; +} + +.bluelighting_title { + float:left; + height:14px; + font-size:14px; + font-weight:bold; + font-family:Verdana, Arial, sans-serif; + text-align:center; + margin-top:2px; + width:100%; + color:#17385B; +} + +.bluelighting_content { + overflow:auto; + color:#000; + font-family:Verdana, Arial, sans-serif; + font-size:12px; + background:#BFDBFF; +} + +/* For alert/confirm dialog */ +.bluelighting_window { + border:1px solid #F00; + background:#FFF; + padding:20px; + margin-left:auto; + margin-right:auto; + width:400px; +} + +.bluelighting_message { + font-size:12px; + text-align:center; + width:100%; + padding-bottom:10px; +} + +.bluelighting_buttons { + text-align:center; + width:100%; +} + +.bluelighting_buttons input { + border:1px solid #999; + border-top-color:#CCC; + border-left-color:#CCC; + padding:2px; + background-color:#FFF; + color:#333; + background-image:url(lighting/background_buttons.gif); + background-repeat:repeat-x; + font-family:Verdana, Arial, sans-serif; + font-size:10px; + font-weight:bold; + text-align:center; +} + +.bluelighting_progress { + float:left; + margin:auto; + text-align:center; + width:100%; + height:16px; + background:transparent url('lighting/spinner.gif') no-repeat center center +} + +/* FOR IE */ +* html .bluelighting_nw { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-left-blue.png", sizingMethod="crop"); +} + +* html .bluelighting_n { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-middle-blue.png", sizingMethod="scale"); +} + +* html .bluelighting_ne { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-right-blue.png", sizingMethod="crop"); +} + +* html .bluelighting_w { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/left-blue.png", sizingMethod="scale"); +} + +* html .bluelighting_e { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/right-blue.png", sizingMethod="scale"); +} + +* html .bluelighting_sw { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-left-blue.png", sizingMethod="crop"); +} + +* html .bluelighting_s { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-middle-blue.png", sizingMethod="scale"); +} + +* html .bluelighting_se, * html .bluelighting_sizer { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-right-blue.png", sizingMethod="crop"); +} + +* html .bluelighting_close { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-close-blue.png", sizingMethod="crop"); +} + +* html .bluelighting_minimize { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-minimize-blue.png", sizingMethod="crop"); +} + +* html .bluelighting_maximize { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-maximize-blue.png", sizingMethod="crop"); +} + +* html .bluelighting_content { + background:#B8D7FF; +} + + + +.overlay_greylighting { + background-color:#FFF; + filter:alpha(opacity=60); + -moz-opacity:0.6; + opacity:0.6; +} + +.greylighting_wired_frame { + background:#FFF; + filter:alpha(opacity=60); + -moz-opacity:0.6; + opacity:0.6; +} + +.greylighting_nw { + background:transparent url(lighting/top-left-grey.png) no-repeat 0 0; + width:9px; + height:28px; +} + +.greylighting_n { + background:transparent url(lighting/top-middle-grey.png) repeat-x 0 0; + height:28px; +} + +.greylighting_ne { + background:transparent url(lighting/top-right-grey.png) no-repeat 0 0; + width:15px; + height:28px; +} + +.greylighting_w { + background:transparent url(lighting/left-grey.png) repeat-y top left; + width:9px; +} + +.greylighting_e { + background:transparent url(lighting/right-grey.png) repeat-y top right; + width:15px; +} + +.greylighting_sw { + background:transparent url(lighting/bottom-left-grey.png) no-repeat 0 0; + width:9px; + height:15px; +} + +.greylighting_s { + background:transparent url(lighting/bottom-middle-grey.png) repeat-x 0 0; + height:15px; +} + +.greylighting_se, .greylighting_sizer { + background:transparent url(lighting/bottom-right-grey.png) no-repeat 0 0; + width:15px; + height:15px; +} + +.greylighting_sizer { + cursor:se-resize; +} + +.greylighting_close { + width:15px; + height:9px; + background:transparent url(lighting/button-close-grey.png) no-repeat 0 0; + position:absolute; + top:11px; + right:10px; + cursor:pointer; + z-index:1000; +} + +.greylighting_maximize { + width:15px; + height:9px; + background:transparent url(lighting/button-maximize-grey.png) no-repeat 0 0; + position:absolute; + top:11px; + right:25px; + cursor:pointer; + z-index:1000; +} + +.greylighting_minimize { + width:15px; + height:9px; + background:transparent url(lighting/button-minimize-grey.png) no-repeat 0 0; + position:absolute; + top:11px; + right:40px; + cursor:pointer; + z-index:1000; +} + +.greylighting_title { + float:left; + height:14px; + font-size:14px; + font-weight:bold; + font-family:Verdana, Arial, sans-serif; + text-align:center; + margin-top:2px; + width:100%; + color:#525252; +} + +.greylighting_content { + overflow:auto; + color:#000; + font-family:Verdana, Arial, sans-serif; + font-size:12px; + background:#CDCDCD; +} + +/* For alert/confirm dialog */ +.greylighting_window { + border:1px solid #F00; + background:#FFF; + padding:20px; + margin-left:auto; + margin-right:auto; + width:400px; +} + +.greylighting_message { + font-size:12px; + text-align:center; + width:100%; + padding-bottom:10px; +} + +.greylighting_buttons { + text-align:center; + width:100%; +} + +.greylighting_buttons input { + border:1px solid #999; + border-top-color:#CCC; + border-left-color:#CCC; + padding:2px; + background-color:#FFF; + color:#333; + background-image:url(lighting/background_buttons.gif); + background-repeat:repeat-x; + font-family:Verdana, Arial, sans-serif; + font-size:10px; + font-weight:bold; + text-align:center; +} + +.greylighting_progress { + float:left; + margin:auto; + text-align:center; + width:100%; + height:16px; + background:transparent url('lighting/spinner.gif') no-repeat center center +} + +/* FOR IE */ +* html .greylighting_nw { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-left-grey.png", sizingMethod="crop"); +} + +* html .greylighting_n { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-middle-grey.png", sizingMethod="scale"); +} + +* html .greylighting_ne { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-right-grey.png", sizingMethod="crop"); +} + +* html .greylighting_w { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/left-grey.png", sizingMethod="scale"); +} + +* html .greylighting_e { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/right-grey.png", sizingMethod="scale"); +} + +* html .greylighting_sw { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-left-grey.png", sizingMethod="crop"); +} + +* html .greylighting_s { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-middle-grey.png", sizingMethod="scale"); +} + +* html greylighting_se, * html .greylighting_sizer { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-right-grey.png", sizingMethod="crop"); +} + +* html .greylighting_close { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-close-grey.png", sizingMethod="crop"); +} + +* html .greylighting_minimize { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-minimize-grey.png", sizingMethod="crop"); +} + +* html .greylighting_maximize { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-maximize-grey.png", sizingMethod="crop"); +} + +* html .greylighting_content { + background:#C7C7C7; +} + + + +.overlay_greenlighting { + background-color:#FFF; + filter:alpha(opacity=60); + -moz-opacity:0.6; + opacity:0.6; +} + +.greenlighting_wired_frame { + background:#FFF; + filter:alpha(opacity=60); + -moz-opacity:0.6; + opacity:0.6; +} + +.greenlighting_nw { + background:transparent url(lighting/top-left-green.png) no-repeat 0 0; + width:9px; + height:28px; +} + +.greenlighting_n { + background:transparent url(lighting/top-middle-green.png) repeat-x 0 0; + height:28px; +} + +.greenlighting_ne { + background:transparent url(lighting/top-right-green.png) no-repeat 0 0; + width:15px; + height:28px; +} + +.greenlighting_w { + background:transparent url(lighting/left-green.png) repeat-y top left; + width:9px; +} + +.greenlighting_e { + background:transparent url(lighting/right-green.png) repeat-y top right; + width:15px; +} + +.greenlighting_sw { + background:transparent url(lighting/bottom-left-green.png) no-repeat 0 0; + width:9px; + height:15px; +} + +.greenlighting_s { + background:transparent url(lighting/bottom-middle-green.png) repeat-x 0 0; + height:15px; +} + +.greenlighting_se, .greenlighting_sizer { + background:transparent url(lighting/bottom-right-green.png) no-repeat 0 0; + width:15px; + height:15px; +} + +.greenlighting_sizer { + cursor:se-resize; +} + +.greenlighting_close { + width:15px; + height:9px; + background:transparent url(lighting/button-close-green.png) no-repeat 0 0; + position:absolute; + top:11px; + right:10px; + cursor:pointer; + z-index:1000; +} + +.greenlighting_maximize { + width:15px; + height:9px; + background:transparent url(lighting/button-maximize-green.png) no-repeat 0 0; + position:absolute; + top:11px; + right:25px; + cursor:pointer; + z-index:1000; +} + +.greenlighting_minimize { + width:15px; + height:9px; + background:transparent url(lighting/button-minimize-green.png) no-repeat 0 0; + position:absolute; + top:11px; + right:40px; + cursor:pointer; + z-index:1000; +} + +.greenlighting_title { + float:left; + height:14px; + font-size:14px; + font-weight:bold; + font-family:Verdana, Arial, sans-serif; + text-align:center; + margin-top:2px; + width:100%; + color:#2A6002; +} + +.greenlighting_content { + overflow:auto; + color:#000; + font-family:Verdana, Arial, sans-serif; + font-size:12px; + background:#ACFCAF; +} + +/* For alert/confirm dialog */ +.greenlighting_window { + border:1px solid #F00; + background:#FFF; + padding:20px; + margin-left:auto; + margin-right:auto; + width:400px; +} + +.greenlighting_message { + font-size:12px; + text-align:center; + width:100%; + padding-bottom:10px; +} + +.greenlighting_buttons { + text-align:center; + width:100%; +} + +.greenlighting_buttons input { + border:1px solid #999; + border-top-color:#CCC; + border-left-color:#CCC; + padding:2px; + background-color:#FFF; + color:#333; + background-image:url(lighting/background_buttons.gif); + background-repeat:repeat-x; + font-family:Verdana, Arial, sans-serif; + font-size:10px; + font-weight:bold; + text-align:center; +} + +.greenlighting_progress { + float:left; + margin:auto; + text-align:center; + width:100%; + height:16px; + background:transparent url('lighting/spinner.gif') no-repeat center center +} + +/* FOR IE */ +* html .greenlighting_nw { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-left-green.png", sizingMethod="crop"); +} + +* html .greenlighting_n { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-middle-green.png", sizingMethod="scale"); +} + +* html .greenlighting_ne { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-right-green.png", sizingMethod="crop"); +} + +* html .greenlighting_w { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/left-green.png", sizingMethod="scale"); +} + +* html .greenlighting_e { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/right-green.png", sizingMethod="scale"); +} + +* html .greenlighting_sw { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-left-green.png", sizingMethod="crop"); +} + +* html .greenlighting_s { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-middle-green.png", sizingMethod="scale"); +} + +* html greenlighting_se, * html .greenlighting_sizer { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-right-green.png", sizingMethod="crop"); +} + +* html .greenlighting_close { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-close-green.png", sizingMethod="crop"); +} + +* html .greenlighting_minimize { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-minimize-green.png", sizingMethod="crop"); +} + +* html .greenlighting_maximize { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-maximize-green.png", sizingMethod="crop"); +} + +* html .greenlighting_content { + background:#A4FCA7; +} + + + +.overlay_darkbluelighting { + background-color:#FFF; + filter:alpha(opacity=60); + -moz-opacity:0.6; + opacity:0.6; +} + +.darkbluelighting_wired_frame { + background:#FFF; + filter:alpha(opacity=60); + -moz-opacity:0.6; + opacity:0.6; +} + +.darkbluelighting_nw { + background:transparent url(lighting/top-left-darkblue.png) no-repeat 0 0; + width:9px; + height:28px; +} + +.darkbluelighting_n { + background:transparent url(lighting/top-middle-darkblue.png) repeat-x 0 0; + height:28px; +} + +.darkbluelighting_ne { + background:transparent url(lighting/top-right-darkblue.png) no-repeat 0 0; + width:15px; + height:28px; +} + +.darkbluelighting_w { + background:transparent url(lighting/left-darkblue.png) repeat-y top left; + width:9px; +} + +.darkbluelighting_e { + background:transparent url(lighting/right-darkblue.png) repeat-y top right; + width:15px; +} + +.darkbluelighting_sw { + background:transparent url(lighting/bottom-left-darkblue.png) no-repeat 0 0; + width:9px; + height:15px; +} + +.darkbluelighting_s { + background:transparent url(lighting/bottom-middle-darkblue.png) repeat-x 0 0; + height:15px; +} + +.darkbluelighting_se, .darkbluelighting_sizer { + background:transparent url(lighting/bottom-right-darkblue.png) no-repeat 0 0; + width:15px; + height:15px; +} + +.darkbluelighting_sizer { + cursor:se-resize; +} + +.darkbluelighting_close { + width:15px; + height:9px; + background:transparent url(lighting/button-close-darkblue.png) no-repeat 0 0; + position:absolute; + top:11px; + right:10px; + cursor:pointer; + z-index:1000; +} + +.darkbluelighting_maximize { + width:15px; + height:9px; + background:transparent url(lighting/button-maximize-darkblue.png) no-repeat 0 0; + position:absolute; + top:11px; + right:25px; + cursor:pointer; + z-index:1000; +} + +.darkbluelighting_minimize { + width:15px; + height:9px; + background:transparent url(lighting/button-minimize-darkblue.png) no-repeat 0 0; + position:absolute; + top:11px; + right:40px; + cursor:pointer; + z-index:1000; +} + +.darkbluelighting_title { + float:left; + height:14px; + font-size:14px; + font-weight:bold; + font-family:Verdana, Arial, sans-serif; + text-align:center; + margin-top:2px; + width:100%; + color:#E4EFFD; +} + +.darkbluelighting_content { + overflow:auto; + color:#FFF; + font-family:Verdana, Arial, sans-serif; + font-size:12px; + background:#0413C0; +} + +/* For alert/confirm dialog */ +.darkbluelighting_window { + border:1px solid #F00; + background:#FFF; + padding:20px; + margin-left:auto; + margin-right:auto; + width:400px; +} + +.darkbluelighting_message { + font-size:12px; + text-align:center; + width:100%; + padding-bottom:10px; +} + +.darkbluelighting_buttons { + text-align:center; + width:100%; +} + +.darkbluelighting_buttons input { + border:1px solid #999; + border-top-color:#CCC; + border-left-color:#CCC; + padding:2px; + background-color:#FFF; + color:#333; + background-image:url(lighting/background_buttons.gif); + background-repeat:repeat-x; + font-family:Verdana, Arial, sans-serif; + font-size:10px; + font-weight:bold; + text-align:center; +} + +.darkbluelighting_progress { + float:left; + margin:auto; + text-align:center; + width:100%; + height:16px; + background:transparent url('lighting/spinner.gif') no-repeat center center +} + +/* FOR IE */ +* html .darkbluelighting_nw { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-left-darkblue.png", sizingMethod="crop"); +} + +* html .darkbluelighting_n { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-middle-darkblue.png", sizingMethod="scale"); +} + +* html .darkbluelighting_ne { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-right-darkblue.png", sizingMethod="crop"); +} + +* html .darkbluelighting_w { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/left-darkblue.png", sizingMethod="scale"); +} + +* html .darkbluelighting_e { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/right-darkblue.png", sizingMethod="scale"); +} + +* html .darkbluelighting_sw { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-left-darkblue.png", sizingMethod="crop"); +} + +* html .darkbluelighting_s { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-middle-darkblue.png", sizingMethod="scale"); +} + +* html darkbluelighting_se, * html .darkbluelighting_sizer { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-right-darkblue.png", sizingMethod="crop"); +} + +* html .darkbluelighting_close { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-close-darkblue.png", sizingMethod="crop"); +} + +* html .darkbluelighting_minimize { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-minimize-darkblue.png", sizingMethod="crop"); +} + +* html .darkbluelighting_maximize { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-maximize-darkblue.png", sizingMethod="crop"); +} + +* html .darkbluelighting_content { + background:#020EBA; +} + diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/background_buttons.gif b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/background_buttons.gif new file mode 100644 index 000000000..2fa58b29f Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/background_buttons.gif differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-left-blue.png b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-left-blue.png new file mode 100644 index 000000000..4592c19be Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-left-blue.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-left-darkblue.png b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-left-darkblue.png new file mode 100644 index 000000000..ce238f125 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-left-darkblue.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-left-green.png b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-left-green.png new file mode 100644 index 000000000..38f9e9e34 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-left-green.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-left-grey.png b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-left-grey.png new file mode 100644 index 000000000..2ace75e1b Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-left-grey.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-middle-blue.png b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-middle-blue.png new file mode 100644 index 000000000..439bcaa1d Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-middle-blue.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-middle-darkblue.png b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-middle-darkblue.png new file mode 100644 index 000000000..3fae972a1 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-middle-darkblue.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-middle-green.png b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-middle-green.png new file mode 100644 index 000000000..89a732f66 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-middle-green.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-middle-grey.png b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-middle-grey.png new file mode 100644 index 000000000..52bfee0de Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-middle-grey.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-right-blue.png b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-right-blue.png new file mode 100644 index 000000000..dffb75f08 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-right-blue.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-right-darkblue.png b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-right-darkblue.png new file mode 100644 index 000000000..62a4d8b8a Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-right-darkblue.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-right-green.png b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-right-green.png new file mode 100644 index 000000000..4aee20fc6 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-right-green.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-right-grey.png b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-right-grey.png new file mode 100644 index 000000000..caa27fe13 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/bottom-right-grey.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-close-blue.png b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-close-blue.png new file mode 100644 index 000000000..523e0dbc2 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-close-blue.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-close-darkblue.png b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-close-darkblue.png new file mode 100644 index 000000000..a7b8daa89 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-close-darkblue.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-close-green.png b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-close-green.png new file mode 100644 index 000000000..63f755b6c Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-close-green.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-close-grey.png b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-close-grey.png new file mode 100644 index 000000000..0c5375f42 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-close-grey.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-maximize-blue.png b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-maximize-blue.png new file mode 100644 index 000000000..2cdf404cf Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-maximize-blue.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-maximize-darkblue.png b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-maximize-darkblue.png new file mode 100644 index 000000000..4ef5758fa Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-maximize-darkblue.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-maximize-green.png b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-maximize-green.png new file mode 100644 index 000000000..d4c1e5787 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-maximize-green.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-maximize-grey.png b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-maximize-grey.png new file mode 100644 index 000000000..35da0e0fc Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-maximize-grey.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-minimize-blue.png b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-minimize-blue.png new file mode 100644 index 000000000..92db9a0db Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-minimize-blue.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-minimize-darkblue.png b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-minimize-darkblue.png new file mode 100644 index 000000000..e3d865464 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-minimize-darkblue.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-minimize-green.png b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-minimize-green.png new file mode 100644 index 000000000..4846e2f43 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-minimize-green.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-minimize-grey.png b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-minimize-grey.png new file mode 100644 index 000000000..310bcbbbc Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/button-minimize-grey.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/left-blue.png b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/left-blue.png new file mode 100644 index 000000000..30275bbb9 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/left-blue.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/left-darkblue.png b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/left-darkblue.png new file mode 100644 index 000000000..36c10e0d7 Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/left-darkblue.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/left-green.png b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/left-green.png new file mode 100644 index 000000000..c8aee739f Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/left-green.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/left-grey.png b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/left-grey.png new file mode 100644 index 000000000..acc2af03a Binary files /dev/null and b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/left-grey.png differ diff --git a/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/pngbehavior.htc b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/pngbehavior.htc new file mode 100644 index 000000000..36ea182e7 --- /dev/null +++ b/plugins/redmine_code_review/assets/stylesheets/window_js/lighting/pngbehavior.htc @@ -0,0 +1,67 @@ + + + + + \ No newline at end of file diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX.css b/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX.css new file mode 100644 index 000000000..2f83cfd46 --- /dev/null +++ b/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX.css @@ -0,0 +1,121 @@ +.overlay_darkX { + background-color: #85BBEF; + filter:alpha(opacity=60); + -moz-opacity: 0.6; + opacity: 0.6; +} + +.darkX_nw { + background: transparent url(darkX/titlebar-left-focused.png) no-repeat 0 0; + width:6px; + height:21px; +} +.darkX_n { + background: transparent url(darkX/titlebar-mid-focused.png) repeat-x 0 0; + height:21px; +} +.darkX_ne { + background: transparent url(darkX/titlebar-right-focused.png) no-repeat 0 0; + width:6px; + height:21px; +} +.darkX_w { + background: transparent url(darkX/frame-left-focused.png) repeat-y top left; + width:3px; +} + +.darkX_e { + background: transparent url(darkX/frame-right-focused.png) repeat-y top right; + width:3px; +} + +.darkX_sw { + background: transparent url(darkX/frame-bottom-left-focused.png) no-repeat 0 0; + width:5px; + height:3px; +} +.darkX_s { + background: transparent url(darkX/frame-bottom-mid-focused.png) repeat-x 0 0; + height:3px; +} +.darkX_se, .darkX_sizer { + background: transparent url(darkX/frame-bottom-right-focused.png) no-repeat 0 0; + width:5px; + height:3px; +} + +.darkX_sizer { + cursor:se-resize; +} + +.darkX_close { + width: 21px; + height: 21px; + background: transparent url(darkX/button-close-focused.png) no-repeat 0 0; + position:absolute; + top:0px; + right:5px; + cursor:pointer; + z-index:1000; +} + +.darkX_minimize { + width: 21px; + height: 21px; + background: transparent url(darkX/button-minimize-focused.png) no-repeat 0 0; + position:absolute; + top:0px; + right:26px; + cursor:pointer; + z-index:1000; +} + +.darkX_maximize { + width: 21px; + height: 21px; + background: transparent url(darkX/button-maximize-focused.png) no-repeat 0 0; + position:absolute; + top:0px; + right:47px; + cursor:pointer; + z-index:1000; +} + + +.darkX_title { + float:left; + height:14px; + font-size:12px; + text-align:center; + margin-top:2px; + width:100%; + color:#FFF; +} + +.darkX_content { + overflow:auto; + color: #E6DF2A; + font-family: Tahoma, Arial, sans-serif; + font-size: 14px; + background:#5E5148; +} + + +/* FOR IE */ +* html .darkX_minimize { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/darkX/button-minimize-focused.png", sizingMethod="crop"); +} + +* html .darkX_maximize { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/darkX/button-maximize-focused.png", sizingMethod="scale"); +} + +* html .darkX_close { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/darkX/button-close-focused.png", sizingMethod="crop"); +} diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX/button-close-focused.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX/button-close-focused.png new file mode 100644 index 000000000..da5a8ac43 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX/button-close-focused.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX/button-maximize-focused.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX/button-maximize-focused.png new file mode 100644 index 000000000..b0bd9cd6f Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX/button-maximize-focused.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX/button-minimize-focused.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX/button-minimize-focused.png new file mode 100644 index 000000000..b04e18f59 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX/button-minimize-focused.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX/frame-bottom-left-focused.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX/frame-bottom-left-focused.png new file mode 100644 index 000000000..7d89f7b0a Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX/frame-bottom-left-focused.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX/frame-bottom-mid-focused.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX/frame-bottom-mid-focused.png new file mode 100644 index 000000000..e50eacccc Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX/frame-bottom-mid-focused.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX/frame-bottom-right-focused.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX/frame-bottom-right-focused.png new file mode 100644 index 000000000..891565911 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX/frame-bottom-right-focused.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX/frame-left-focused.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX/frame-left-focused.png new file mode 100644 index 000000000..ff9f336f2 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX/frame-left-focused.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX/frame-right-focused.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX/frame-right-focused.png new file mode 100644 index 000000000..f69ea0069 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX/frame-right-focused.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX/titlebar-left-focused.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX/titlebar-left-focused.png new file mode 100644 index 000000000..1436e8410 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX/titlebar-left-focused.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX/titlebar-mid-focused.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX/titlebar-mid-focused.png new file mode 100644 index 000000000..f7be50b14 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX/titlebar-mid-focused.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX/titlebar-right-focused.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX/titlebar-right-focused.png new file mode 100644 index 000000000..ae23785d4 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/darkX/titlebar-right-focused.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/debug.css b/public/plugin_assets/redmine_code_review/stylesheets/window_js/debug.css new file mode 100644 index 000000000..69e3b7fc2 --- /dev/null +++ b/public/plugin_assets/redmine_code_review/stylesheets/window_js/debug.css @@ -0,0 +1,25 @@ +div.inspector div.inspectable { + padding: 0.25em 0 0.25em 1em; + background-color: Gray; + color: white; + border: outset 2px white; + cursor: pointer; +} + +div.inspector div.child { + margin: 0 0 0 1em; +} + +#debug_window_content { /* DIV container for debug sizing*/ + width:250px; + height:100px; + background-color:#000; +} + +#debug { /* DIV container for debug contents*/ + padding:3px; + color:#0f0; + font-family:monaco, Tahoma, Verdana, Arial, Helvetica, sans-serif; + font-size:10px; +} + diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/default.css b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default.css new file mode 100644 index 000000000..6ab13789d --- /dev/null +++ b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default.css @@ -0,0 +1,155 @@ +.overlay_dialog { + background-color: #666666; + filter:alpha(opacity=60); + -moz-opacity: 0.6; + opacity: 0.6; +} + +.overlay___invisible__ { + background-color: #666666; + filter:alpha(opacity=0); + -moz-opacity: 0; + opacity: 0; +} + +.dialog_nw { + width: 9px; + height: 23px; + background: transparent url(default/top_left.gif) no-repeat 0 0; +} + +.dialog_n { + background: transparent url(default/top_mid.gif) repeat-x 0 0; + height: 23px; +} + +.dialog_ne { + width: 9px; + height: 23px; + background: transparent url(default/top_right.gif) no-repeat 0 0; +} + +.dialog_e { + width: 2px; + background: transparent url(default/center_right.gif) repeat-y 0 0; +} + +.dialog_w { + width: 2px; + background: transparent url(default/center_left.gif) repeat-y 0 0; +} + +.dialog_sw { + width: 9px; + height: 19px; + background: transparent url(default/bottom_left.gif) no-repeat 0 0; +} + +.dialog_s { + background: transparent url(default/bottom_mid.gif) repeat-x 0 0; + height: 19px; +} + +.dialog_se { + width: 9px; + height: 19px; + background: transparent url(default/bottom_right.gif) no-repeat 0 0; +} + +.dialog_sizer { + width: 9px; + height: 19px; + background: transparent url(default/sizer.gif) no-repeat 0 0; + cursor:se-resize; +} + +.dialog_close { + width: 14px; + height: 14px; + background: transparent url(default/close.gif) no-repeat 0 0; + position:absolute; + top:5px; + left:8px; + cursor:pointer; + z-index:2000; +} + +.dialog_minimize { + width: 14px; + height: 15px; + background: transparent url(default/minimize.gif) no-repeat 0 0; + position:absolute; + top:5px; + left:28px; + cursor:pointer; + z-index:2000; +} + +.dialog_maximize { + width: 14px; + height: 15px; + background: transparent url(default/maximize.gif) no-repeat 0 0; + position:absolute; + top:5px; + left:49px; + cursor:pointer; + z-index:2000; +} + +.dialog_title { + float:left; + height:14px; + font-family: Tahoma, Arial, sans-serif; + font-size:12px; + text-align:center; + width:100%; + color:#000; +} + +.dialog_content { + overflow:auto; + color: #DDD; + font-family: Tahoma, Arial, sans-serif; + font-size: 10px; + background-color:#123; +} + +.top_draggable, .bottom_draggable { + cursor:move; +} + +.status_bar { + font-size:12px; +} +.status_bar input{ + font-size:12px; +} + +.wired_frame { + display: block; + position: absolute; + border: 1px #000 dashed; +} + +/* DO NOT CHANGE THESE VALUES*/ +.dialog { + display: block; + position: absolute; +} + +.dialog table.table_window { + border-collapse: collapse; + border-spacing: 0; + width: 100%; + margin: 0px; + padding:0px; +} + +.dialog table.table_window td , .dialog table.table_window th { + padding: 0; +} + +.dialog .title_window { + -moz-user-select:none; +} + diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/bottom_left.gif b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/bottom_left.gif new file mode 100644 index 000000000..4c73d3563 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/bottom_left.gif differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/bottom_mid.gif b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/bottom_mid.gif new file mode 100644 index 000000000..9205d3019 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/bottom_mid.gif differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/bottom_right.gif b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/bottom_right.gif new file mode 100644 index 000000000..8d002eeb8 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/bottom_right.gif differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/bottom_right_resize.gif b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/bottom_right_resize.gif new file mode 100644 index 000000000..649b0d870 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/bottom_right_resize.gif differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/center_left.gif b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/center_left.gif new file mode 100644 index 000000000..79e7a1cca Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/center_left.gif differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/center_right.gif b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/center_right.gif new file mode 100644 index 000000000..554c55c86 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/center_right.gif differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/clear.gif b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/clear.gif new file mode 100644 index 000000000..c10b16694 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/clear.gif differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/close.gif b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/close.gif new file mode 100644 index 000000000..31ef5a394 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/close.gif differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/inspect.gif b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/inspect.gif new file mode 100644 index 000000000..ebeeb02f6 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/inspect.gif differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/maximize.gif b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/maximize.gif new file mode 100644 index 000000000..892a0f08c Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/maximize.gif differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/minimize.gif b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/minimize.gif new file mode 100644 index 000000000..a7214167b Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/minimize.gif differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/overlay.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/overlay.png new file mode 100644 index 000000000..648e71ed6 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/overlay.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/resize.gif b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/resize.gif new file mode 100644 index 000000000..c44070259 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/resize.gif differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/sizer.gif b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/sizer.gif new file mode 100644 index 000000000..649b0d870 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/sizer.gif differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/top_left.gif b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/top_left.gif new file mode 100644 index 000000000..774538ac6 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/top_left.gif differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/top_mid.gif b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/top_mid.gif new file mode 100644 index 000000000..6124e78bd Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/top_mid.gif differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/top_right.gif b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/top_right.gif new file mode 100644 index 000000000..fbc94bf2b Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/default/top_right.gif differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/iefix/blank.gif b/public/plugin_assets/redmine_code_review/stylesheets/window_js/iefix/blank.gif new file mode 100644 index 000000000..75b945d25 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/iefix/blank.gif differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/iefix/iepngfix.css b/public/plugin_assets/redmine_code_review/stylesheets/window_js/iefix/iepngfix.css new file mode 100644 index 000000000..257a1b1e3 --- /dev/null +++ b/public/plugin_assets/redmine_code_review/stylesheets/window_js/iefix/iepngfix.css @@ -0,0 +1,3 @@ +/* PNG fix for all themes that uses PNG images on IE */ +td, div { behavior: url(../themes/iefix/iepngfix.htc) } + diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/iefix/iepngfix.htc b/public/plugin_assets/redmine_code_review/stylesheets/window_js/iefix/iepngfix.htc new file mode 100644 index 000000000..a6c683b9f --- /dev/null +++ b/public/plugin_assets/redmine_code_review/stylesheets/window_js/iefix/iepngfix.htc @@ -0,0 +1,54 @@ + + + + + \ No newline at end of file diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting.css b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting.css new file mode 100644 index 000000000..95ec287a9 --- /dev/null +++ b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting.css @@ -0,0 +1,960 @@ +.overlay___invisible__ { + background-color: #666; + filter:alpha(opacity=0); + -moz-opacity: 0; + opacity: 0; +} + +.top_draggable, .bottom_draggable { + cursor:move; +} + +.status_bar { + font-size:12px; +} +.status_bar input{ + font-size:12px; +} + +.wired_frame { + display:block; + position:absolute; + border:1px #000 dashed; +} + + + +.overlay_bluelighting { + background-color:#FFF; + filter:alpha(opacity=60); + -moz-opacity:0.6; + opacity:0.6; +} + +.bluelighting_wired_frame { + background:#FFF; + filter:alpha(opacity=60); + -moz-opacity:0.6; + opacity:0.6; +} + +.bluelighting_nw { + background:transparent url(lighting/top-left-blue.png) no-repeat 0 0; + width:9px; + height:28px; +} + +.bluelighting_n { + background:transparent url(lighting/top-middle-blue.png) repeat-x 0 0; + height:28px; +} + +.bluelighting_ne { + background:transparent url(lighting/top-right-blue.png) no-repeat 0 0; + width:15px; + height:28px; +} + +.bluelighting_w { + background:transparent url(lighting/left-blue.png) repeat-y top left; + width:9px; +} + +.bluelighting_e { + background:transparent url(lighting/right-blue.png) repeat-y top right; + width:15px; +} + +.bluelighting_sw { + background:transparent url(lighting/bottom-left-blue.png) no-repeat 0 0; + width:9px; + height:15px; +} + +.bluelighting_s { + background:transparent url(lighting/bottom-middle-blue.png) repeat-x 0 0; + height:15px; +} + +.bluelighting_se, .bluelighting_sizer { + background:transparent url(lighting/bottom-right-blue.png) no-repeat 0 0; + width:15px; + height:15px; +} + +.bluelighting_sizer { + cursor:se-resize; +} + +.bluelighting_close { + width:15px; + height:9px; + background:transparent url(lighting/button-close-blue.png) no-repeat 0 0; + position:absolute; + top:11px; + right:10px; + cursor:pointer; + z-index:1000; +} + +.bluelighting_maximize { + width:15px; + height:9px; + background:transparent url(lighting/button-maximize-blue.png) no-repeat 0 0; + position:absolute; + top:11px; + right:25px; + cursor:pointer; + z-index:1000; +} + +.bluelighting_minimize { + width:15px; + height:9px; + background:transparent url(lighting/button-minimize-blue.png) no-repeat 0 0; + position:absolute; + top:11px; + right:40px; + cursor:pointer; + z-index:1000; +} + +.bluelighting_title { + float:left; + height:14px; + font-size:14px; + font-weight:bold; + font-family:Verdana, Arial, sans-serif; + text-align:center; + margin-top:2px; + width:100%; + color:#17385B; +} + +.bluelighting_content { + overflow:auto; + color:#000; + font-family:Verdana, Arial, sans-serif; + font-size:12px; + background:#BFDBFF; +} + +/* For alert/confirm dialog */ +.bluelighting_window { + border:1px solid #F00; + background:#FFF; + padding:20px; + margin-left:auto; + margin-right:auto; + width:400px; +} + +.bluelighting_message { + font-size:12px; + text-align:center; + width:100%; + padding-bottom:10px; +} + +.bluelighting_buttons { + text-align:center; + width:100%; +} + +.bluelighting_buttons input { + border:1px solid #999; + border-top-color:#CCC; + border-left-color:#CCC; + padding:2px; + background-color:#FFF; + color:#333; + background-image:url(lighting/background_buttons.gif); + background-repeat:repeat-x; + font-family:Verdana, Arial, sans-serif; + font-size:10px; + font-weight:bold; + text-align:center; +} + +.bluelighting_progress { + float:left; + margin:auto; + text-align:center; + width:100%; + height:16px; + background:transparent url('lighting/spinner.gif') no-repeat center center +} + +/* FOR IE */ +* html .bluelighting_nw { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-left-blue.png", sizingMethod="crop"); +} + +* html .bluelighting_n { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-middle-blue.png", sizingMethod="scale"); +} + +* html .bluelighting_ne { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-right-blue.png", sizingMethod="crop"); +} + +* html .bluelighting_w { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/left-blue.png", sizingMethod="scale"); +} + +* html .bluelighting_e { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/right-blue.png", sizingMethod="scale"); +} + +* html .bluelighting_sw { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-left-blue.png", sizingMethod="crop"); +} + +* html .bluelighting_s { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-middle-blue.png", sizingMethod="scale"); +} + +* html .bluelighting_se, * html .bluelighting_sizer { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-right-blue.png", sizingMethod="crop"); +} + +* html .bluelighting_close { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-close-blue.png", sizingMethod="crop"); +} + +* html .bluelighting_minimize { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-minimize-blue.png", sizingMethod="crop"); +} + +* html .bluelighting_maximize { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-maximize-blue.png", sizingMethod="crop"); +} + +* html .bluelighting_content { + background:#B8D7FF; +} + + + +.overlay_greylighting { + background-color:#FFF; + filter:alpha(opacity=60); + -moz-opacity:0.6; + opacity:0.6; +} + +.greylighting_wired_frame { + background:#FFF; + filter:alpha(opacity=60); + -moz-opacity:0.6; + opacity:0.6; +} + +.greylighting_nw { + background:transparent url(lighting/top-left-grey.png) no-repeat 0 0; + width:9px; + height:28px; +} + +.greylighting_n { + background:transparent url(lighting/top-middle-grey.png) repeat-x 0 0; + height:28px; +} + +.greylighting_ne { + background:transparent url(lighting/top-right-grey.png) no-repeat 0 0; + width:15px; + height:28px; +} + +.greylighting_w { + background:transparent url(lighting/left-grey.png) repeat-y top left; + width:9px; +} + +.greylighting_e { + background:transparent url(lighting/right-grey.png) repeat-y top right; + width:15px; +} + +.greylighting_sw { + background:transparent url(lighting/bottom-left-grey.png) no-repeat 0 0; + width:9px; + height:15px; +} + +.greylighting_s { + background:transparent url(lighting/bottom-middle-grey.png) repeat-x 0 0; + height:15px; +} + +.greylighting_se, .greylighting_sizer { + background:transparent url(lighting/bottom-right-grey.png) no-repeat 0 0; + width:15px; + height:15px; +} + +.greylighting_sizer { + cursor:se-resize; +} + +.greylighting_close { + width:15px; + height:9px; + background:transparent url(lighting/button-close-grey.png) no-repeat 0 0; + position:absolute; + top:11px; + right:10px; + cursor:pointer; + z-index:1000; +} + +.greylighting_maximize { + width:15px; + height:9px; + background:transparent url(lighting/button-maximize-grey.png) no-repeat 0 0; + position:absolute; + top:11px; + right:25px; + cursor:pointer; + z-index:1000; +} + +.greylighting_minimize { + width:15px; + height:9px; + background:transparent url(lighting/button-minimize-grey.png) no-repeat 0 0; + position:absolute; + top:11px; + right:40px; + cursor:pointer; + z-index:1000; +} + +.greylighting_title { + float:left; + height:14px; + font-size:14px; + font-weight:bold; + font-family:Verdana, Arial, sans-serif; + text-align:center; + margin-top:2px; + width:100%; + color:#525252; +} + +.greylighting_content { + overflow:auto; + color:#000; + font-family:Verdana, Arial, sans-serif; + font-size:12px; + background:#CDCDCD; +} + +/* For alert/confirm dialog */ +.greylighting_window { + border:1px solid #F00; + background:#FFF; + padding:20px; + margin-left:auto; + margin-right:auto; + width:400px; +} + +.greylighting_message { + font-size:12px; + text-align:center; + width:100%; + padding-bottom:10px; +} + +.greylighting_buttons { + text-align:center; + width:100%; +} + +.greylighting_buttons input { + border:1px solid #999; + border-top-color:#CCC; + border-left-color:#CCC; + padding:2px; + background-color:#FFF; + color:#333; + background-image:url(lighting/background_buttons.gif); + background-repeat:repeat-x; + font-family:Verdana, Arial, sans-serif; + font-size:10px; + font-weight:bold; + text-align:center; +} + +.greylighting_progress { + float:left; + margin:auto; + text-align:center; + width:100%; + height:16px; + background:transparent url('lighting/spinner.gif') no-repeat center center +} + +/* FOR IE */ +* html .greylighting_nw { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-left-grey.png", sizingMethod="crop"); +} + +* html .greylighting_n { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-middle-grey.png", sizingMethod="scale"); +} + +* html .greylighting_ne { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-right-grey.png", sizingMethod="crop"); +} + +* html .greylighting_w { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/left-grey.png", sizingMethod="scale"); +} + +* html .greylighting_e { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/right-grey.png", sizingMethod="scale"); +} + +* html .greylighting_sw { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-left-grey.png", sizingMethod="crop"); +} + +* html .greylighting_s { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-middle-grey.png", sizingMethod="scale"); +} + +* html greylighting_se, * html .greylighting_sizer { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-right-grey.png", sizingMethod="crop"); +} + +* html .greylighting_close { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-close-grey.png", sizingMethod="crop"); +} + +* html .greylighting_minimize { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-minimize-grey.png", sizingMethod="crop"); +} + +* html .greylighting_maximize { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-maximize-grey.png", sizingMethod="crop"); +} + +* html .greylighting_content { + background:#C7C7C7; +} + + + +.overlay_greenlighting { + background-color:#FFF; + filter:alpha(opacity=60); + -moz-opacity:0.6; + opacity:0.6; +} + +.greenlighting_wired_frame { + background:#FFF; + filter:alpha(opacity=60); + -moz-opacity:0.6; + opacity:0.6; +} + +.greenlighting_nw { + background:transparent url(lighting/top-left-green.png) no-repeat 0 0; + width:9px; + height:28px; +} + +.greenlighting_n { + background:transparent url(lighting/top-middle-green.png) repeat-x 0 0; + height:28px; +} + +.greenlighting_ne { + background:transparent url(lighting/top-right-green.png) no-repeat 0 0; + width:15px; + height:28px; +} + +.greenlighting_w { + background:transparent url(lighting/left-green.png) repeat-y top left; + width:9px; +} + +.greenlighting_e { + background:transparent url(lighting/right-green.png) repeat-y top right; + width:15px; +} + +.greenlighting_sw { + background:transparent url(lighting/bottom-left-green.png) no-repeat 0 0; + width:9px; + height:15px; +} + +.greenlighting_s { + background:transparent url(lighting/bottom-middle-green.png) repeat-x 0 0; + height:15px; +} + +.greenlighting_se, .greenlighting_sizer { + background:transparent url(lighting/bottom-right-green.png) no-repeat 0 0; + width:15px; + height:15px; +} + +.greenlighting_sizer { + cursor:se-resize; +} + +.greenlighting_close { + width:15px; + height:9px; + background:transparent url(lighting/button-close-green.png) no-repeat 0 0; + position:absolute; + top:11px; + right:10px; + cursor:pointer; + z-index:1000; +} + +.greenlighting_maximize { + width:15px; + height:9px; + background:transparent url(lighting/button-maximize-green.png) no-repeat 0 0; + position:absolute; + top:11px; + right:25px; + cursor:pointer; + z-index:1000; +} + +.greenlighting_minimize { + width:15px; + height:9px; + background:transparent url(lighting/button-minimize-green.png) no-repeat 0 0; + position:absolute; + top:11px; + right:40px; + cursor:pointer; + z-index:1000; +} + +.greenlighting_title { + float:left; + height:14px; + font-size:14px; + font-weight:bold; + font-family:Verdana, Arial, sans-serif; + text-align:center; + margin-top:2px; + width:100%; + color:#2A6002; +} + +.greenlighting_content { + overflow:auto; + color:#000; + font-family:Verdana, Arial, sans-serif; + font-size:12px; + background:#ACFCAF; +} + +/* For alert/confirm dialog */ +.greenlighting_window { + border:1px solid #F00; + background:#FFF; + padding:20px; + margin-left:auto; + margin-right:auto; + width:400px; +} + +.greenlighting_message { + font-size:12px; + text-align:center; + width:100%; + padding-bottom:10px; +} + +.greenlighting_buttons { + text-align:center; + width:100%; +} + +.greenlighting_buttons input { + border:1px solid #999; + border-top-color:#CCC; + border-left-color:#CCC; + padding:2px; + background-color:#FFF; + color:#333; + background-image:url(lighting/background_buttons.gif); + background-repeat:repeat-x; + font-family:Verdana, Arial, sans-serif; + font-size:10px; + font-weight:bold; + text-align:center; +} + +.greenlighting_progress { + float:left; + margin:auto; + text-align:center; + width:100%; + height:16px; + background:transparent url('lighting/spinner.gif') no-repeat center center +} + +/* FOR IE */ +* html .greenlighting_nw { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-left-green.png", sizingMethod="crop"); +} + +* html .greenlighting_n { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-middle-green.png", sizingMethod="scale"); +} + +* html .greenlighting_ne { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-right-green.png", sizingMethod="crop"); +} + +* html .greenlighting_w { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/left-green.png", sizingMethod="scale"); +} + +* html .greenlighting_e { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/right-green.png", sizingMethod="scale"); +} + +* html .greenlighting_sw { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-left-green.png", sizingMethod="crop"); +} + +* html .greenlighting_s { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-middle-green.png", sizingMethod="scale"); +} + +* html greenlighting_se, * html .greenlighting_sizer { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-right-green.png", sizingMethod="crop"); +} + +* html .greenlighting_close { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-close-green.png", sizingMethod="crop"); +} + +* html .greenlighting_minimize { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-minimize-green.png", sizingMethod="crop"); +} + +* html .greenlighting_maximize { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-maximize-green.png", sizingMethod="crop"); +} + +* html .greenlighting_content { + background:#A4FCA7; +} + + + +.overlay_darkbluelighting { + background-color:#FFF; + filter:alpha(opacity=60); + -moz-opacity:0.6; + opacity:0.6; +} + +.darkbluelighting_wired_frame { + background:#FFF; + filter:alpha(opacity=60); + -moz-opacity:0.6; + opacity:0.6; +} + +.darkbluelighting_nw { + background:transparent url(lighting/top-left-darkblue.png) no-repeat 0 0; + width:9px; + height:28px; +} + +.darkbluelighting_n { + background:transparent url(lighting/top-middle-darkblue.png) repeat-x 0 0; + height:28px; +} + +.darkbluelighting_ne { + background:transparent url(lighting/top-right-darkblue.png) no-repeat 0 0; + width:15px; + height:28px; +} + +.darkbluelighting_w { + background:transparent url(lighting/left-darkblue.png) repeat-y top left; + width:9px; +} + +.darkbluelighting_e { + background:transparent url(lighting/right-darkblue.png) repeat-y top right; + width:15px; +} + +.darkbluelighting_sw { + background:transparent url(lighting/bottom-left-darkblue.png) no-repeat 0 0; + width:9px; + height:15px; +} + +.darkbluelighting_s { + background:transparent url(lighting/bottom-middle-darkblue.png) repeat-x 0 0; + height:15px; +} + +.darkbluelighting_se, .darkbluelighting_sizer { + background:transparent url(lighting/bottom-right-darkblue.png) no-repeat 0 0; + width:15px; + height:15px; +} + +.darkbluelighting_sizer { + cursor:se-resize; +} + +.darkbluelighting_close { + width:15px; + height:9px; + background:transparent url(lighting/button-close-darkblue.png) no-repeat 0 0; + position:absolute; + top:11px; + right:10px; + cursor:pointer; + z-index:1000; +} + +.darkbluelighting_maximize { + width:15px; + height:9px; + background:transparent url(lighting/button-maximize-darkblue.png) no-repeat 0 0; + position:absolute; + top:11px; + right:25px; + cursor:pointer; + z-index:1000; +} + +.darkbluelighting_minimize { + width:15px; + height:9px; + background:transparent url(lighting/button-minimize-darkblue.png) no-repeat 0 0; + position:absolute; + top:11px; + right:40px; + cursor:pointer; + z-index:1000; +} + +.darkbluelighting_title { + float:left; + height:14px; + font-size:14px; + font-weight:bold; + font-family:Verdana, Arial, sans-serif; + text-align:center; + margin-top:2px; + width:100%; + color:#E4EFFD; +} + +.darkbluelighting_content { + overflow:auto; + color:#FFF; + font-family:Verdana, Arial, sans-serif; + font-size:12px; + background:#0413C0; +} + +/* For alert/confirm dialog */ +.darkbluelighting_window { + border:1px solid #F00; + background:#FFF; + padding:20px; + margin-left:auto; + margin-right:auto; + width:400px; +} + +.darkbluelighting_message { + font-size:12px; + text-align:center; + width:100%; + padding-bottom:10px; +} + +.darkbluelighting_buttons { + text-align:center; + width:100%; +} + +.darkbluelighting_buttons input { + border:1px solid #999; + border-top-color:#CCC; + border-left-color:#CCC; + padding:2px; + background-color:#FFF; + color:#333; + background-image:url(lighting/background_buttons.gif); + background-repeat:repeat-x; + font-family:Verdana, Arial, sans-serif; + font-size:10px; + font-weight:bold; + text-align:center; +} + +.darkbluelighting_progress { + float:left; + margin:auto; + text-align:center; + width:100%; + height:16px; + background:transparent url('lighting/spinner.gif') no-repeat center center +} + +/* FOR IE */ +* html .darkbluelighting_nw { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-left-darkblue.png", sizingMethod="crop"); +} + +* html .darkbluelighting_n { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-middle-darkblue.png", sizingMethod="scale"); +} + +* html .darkbluelighting_ne { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-right-darkblue.png", sizingMethod="crop"); +} + +* html .darkbluelighting_w { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/left-darkblue.png", sizingMethod="scale"); +} + +* html .darkbluelighting_e { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/right-darkblue.png", sizingMethod="scale"); +} + +* html .darkbluelighting_sw { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-left-darkblue.png", sizingMethod="crop"); +} + +* html .darkbluelighting_s { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-middle-darkblue.png", sizingMethod="scale"); +} + +* html darkbluelighting_se, * html .darkbluelighting_sizer { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-right-darkblue.png", sizingMethod="crop"); +} + +* html .darkbluelighting_close { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-close-darkblue.png", sizingMethod="crop"); +} + +* html .darkbluelighting_minimize { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-minimize-darkblue.png", sizingMethod="crop"); +} + +* html .darkbluelighting_maximize { + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-maximize-darkblue.png", sizingMethod="crop"); +} + +* html .darkbluelighting_content { + background:#020EBA; +} + diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/background_buttons.gif b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/background_buttons.gif new file mode 100644 index 000000000..2fa58b29f Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/background_buttons.gif differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-left-blue.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-left-blue.png new file mode 100644 index 000000000..4592c19be Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-left-blue.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-left-darkblue.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-left-darkblue.png new file mode 100644 index 000000000..ce238f125 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-left-darkblue.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-left-green.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-left-green.png new file mode 100644 index 000000000..38f9e9e34 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-left-green.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-left-grey.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-left-grey.png new file mode 100644 index 000000000..2ace75e1b Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-left-grey.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-middle-blue.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-middle-blue.png new file mode 100644 index 000000000..439bcaa1d Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-middle-blue.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-middle-darkblue.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-middle-darkblue.png new file mode 100644 index 000000000..3fae972a1 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-middle-darkblue.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-middle-green.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-middle-green.png new file mode 100644 index 000000000..89a732f66 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-middle-green.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-middle-grey.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-middle-grey.png new file mode 100644 index 000000000..52bfee0de Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-middle-grey.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-right-blue.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-right-blue.png new file mode 100644 index 000000000..dffb75f08 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-right-blue.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-right-darkblue.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-right-darkblue.png new file mode 100644 index 000000000..62a4d8b8a Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-right-darkblue.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-right-green.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-right-green.png new file mode 100644 index 000000000..4aee20fc6 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-right-green.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-right-grey.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-right-grey.png new file mode 100644 index 000000000..caa27fe13 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/bottom-right-grey.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-close-blue.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-close-blue.png new file mode 100644 index 000000000..523e0dbc2 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-close-blue.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-close-darkblue.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-close-darkblue.png new file mode 100644 index 000000000..a7b8daa89 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-close-darkblue.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-close-green.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-close-green.png new file mode 100644 index 000000000..63f755b6c Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-close-green.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-close-grey.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-close-grey.png new file mode 100644 index 000000000..0c5375f42 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-close-grey.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-maximize-blue.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-maximize-blue.png new file mode 100644 index 000000000..2cdf404cf Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-maximize-blue.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-maximize-darkblue.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-maximize-darkblue.png new file mode 100644 index 000000000..4ef5758fa Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-maximize-darkblue.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-maximize-green.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-maximize-green.png new file mode 100644 index 000000000..d4c1e5787 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-maximize-green.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-maximize-grey.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-maximize-grey.png new file mode 100644 index 000000000..35da0e0fc Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-maximize-grey.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-minimize-blue.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-minimize-blue.png new file mode 100644 index 000000000..92db9a0db Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-minimize-blue.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-minimize-darkblue.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-minimize-darkblue.png new file mode 100644 index 000000000..e3d865464 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-minimize-darkblue.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-minimize-green.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-minimize-green.png new file mode 100644 index 000000000..4846e2f43 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-minimize-green.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-minimize-grey.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-minimize-grey.png new file mode 100644 index 000000000..310bcbbbc Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/button-minimize-grey.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/left-blue.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/left-blue.png new file mode 100644 index 000000000..30275bbb9 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/left-blue.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/left-darkblue.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/left-darkblue.png new file mode 100644 index 000000000..36c10e0d7 Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/left-darkblue.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/left-green.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/left-green.png new file mode 100644 index 000000000..c8aee739f Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/left-green.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/left-grey.png b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/left-grey.png new file mode 100644 index 000000000..acc2af03a Binary files /dev/null and b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/left-grey.png differ diff --git a/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/pngbehavior.htc b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/pngbehavior.htc new file mode 100644 index 000000000..36ea182e7 --- /dev/null +++ b/public/plugin_assets/redmine_code_review/stylesheets/window_js/lighting/pngbehavior.htc @@ -0,0 +1,67 @@ + + + +" => "

          <script>some script;</script>

          ", + # do not escape pre/code tags + "
          \nline 1\nline2
          " => "
          \nline 1\nline2
          ", + "
          \nline 1\nline2
          " => "
          \nline 1\nline2
          ", + "
          content
          " => "
          <div>content</div>
          ", + "HTML comment: " => "

          HTML comment: <!-- no comments -->

          ", + "