diff --git a/.gitignore b/.gitignore index 8aa87e9f..163982b7 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 1d827679..634af968 100644 --- a/Gemfile +++ b/Gemfile @@ -14,13 +14,27 @@ gem "i18n", "~> 0.6.0" gem "coderay", "~> 1.0.6" gem "fastercsv", "~> 1.5.0", :platforms => [:mri_18, :mingw_18, :jruby] gem "builder", "3.0.0" -gem 'acts-as-taggable-on' +gem 'acts-as-taggable-on', '2.4.1' group :development do gem 'better_errors', path: 'lib/better_errors' gem 'rack-mini-profiler', path: 'lib/rack-mini-profiler' + if ENV['PRY'] + gem 'pry' + gem 'pry-nav' + 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 @@ -28,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 @@ -38,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" @@ -63,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 6680070a..e52990e2 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,10 +83,14 @@ GEM mail (2.5.4) mime-types (~> 1.16) treetop (~> 1.4.8) + 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) rack (1.4.5) rack-cache (1.2) @@ -104,15 +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) + 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) @@ -124,9 +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) + json (>= 1.8.0) + websocket (1.0.7) + xpath (1.0.0) + nokogiri (~> 1.3) PLATFORMS x86-mingw32 @@ -134,20 +163,26 @@ PLATFORMS DEPENDENCIES activerecord-jdbc-adapter (= 1.2.5) activerecord-jdbcmysql-adapter - acts-as-taggable-on + 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) + 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/ReadMe.txt b/ReadMe.txt index e7444a6c..0fcba47c 100644 --- a/ReadMe.txt +++ b/ReadMe.txt @@ -1,11 +1,18 @@ patch: -ûIJ֣issues#655 -Ϊ޸ķ -alias - ֮ǰʾ ֮ +用户姓名的部分,根据issues#655。 +为了修改方便 +alias: +方法 之前显示 调整之后 name firstname+lastname login nickname xxx login realname xxx firstname+lastname + +User model经过修改,已经完全集成了user_extensions的功能 +例如 +user.gender=1 +user.save +user_extensions字段会自动保存 +不必要每次user.user_extensions.xxx以及判断是否为空 ================================================================================ app/models/setting.rb :165 # fixed domain url in development. tantantan's bug @@ -14,22 +21,22 @@ app/models/setting.rb :165 define_singleton_method m do; nil; end if m.to_s =~ /([a-zA-Z]+_domain)$/ end end - 򲿷ƶsubdomainʹڶת - Ϊ˿㣬ʹ֮developmentģʽʧЧ + 程序部分链接中制定了subdomain参数,使链接在二级域名中来回跳转。 + 为了开发方便,使之功能在development模式下失效。 # => nyan ================================================================================ app/controller/projects_controller.rb ===> projects#fake - fake filter: ޸˴ҳеCount׺ - Ϊȷɾfake + fake filter: 修改了传到页面中的Count后缀的数量 + 改为正确的数量,删掉fake过滤器即可 ================================================================================ -#ƥʾ͸ı +#导航栏匹配域名显示和改变 app\helper\application_helper.rb # rewrite navigation app\views\layouts\_base_header.html.erb # reset navigation by domain name and url through regular match ================================================================================ -#ҳƥ벻ͬҳ +#首页根据域名匹配进入不同的页面 app\controller\welcome_controller.rb def entry_select_user if request.original_url.match(/user\.trustie\.net/) @@ -37,4 +44,10 @@ app\controller\welcome_controller.rb return 0 end end -================================================================================ \ No newline at end of file +================================================================================ + +================================================================================ +0606:新坑 +user_scores表结构有问题,需要运行 +bundle exec rake db:migrate:down VERSION=20140410021724 +bundle exec rake db:migrate:up VERSION=20140410021724 \ No newline at end of file diff --git a/app/assets/javascripts/applied_project.js b/app/assets/javascripts/applied_project.js new file mode 100644 index 00000000..dee720fa --- /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 00000000..dee720fa --- /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/javascripts/contestnotifications.js b/app/assets/javascripts/contestnotifications.js new file mode 100644 index 00000000..dee720fa --- /dev/null +++ b/app/assets/javascripts/contestnotifications.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/notificationcomments.js.coffee b/app/assets/javascripts/notificationcomments.js.coffee new file mode 100644 index 00000000..76156794 --- /dev/null +++ b/app/assets/javascripts/notificationcomments.js.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ diff --git a/app/assets/stylesheets/applied_project.css b/app/assets/stylesheets/applied_project.css new file mode 100644 index 00000000..afad32db --- /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 00000000..afad32db --- /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/assets/stylesheets/contestnotifications.css b/app/assets/stylesheets/contestnotifications.css new file mode 100644 index 00000000..afad32db --- /dev/null +++ b/app/assets/stylesheets/contestnotifications.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/notificationcomments.css.scss b/app/assets/stylesheets/notificationcomments.css.scss new file mode 100644 index 00000000..aea714e4 --- /dev/null +++ b/app/assets/stylesheets/notificationcomments.css.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the notificationcomments controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/controllers/account_controller.rb b/app/controllers/account_controller.rb index af848786..0af388c5 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 a25b346c..e6efca1e 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -94,7 +94,7 @@ class ApplicationController < ActionController::Base Setting.check_cache # Find the current user User.current = find_current_user - logger.info(" Current user: " + (User.current.logged? ? "#{User.current.login} (id=#{User.current.id})" : "anonymous")) if logger + #logger.info(" Current user: " + (User.current.logged? ? "#{User.current.login} (id=#{User.current.id})" : "anonymous")) if logger end # Returns the current user or nil if no user is logged in @@ -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,7 +285,25 @@ 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 + end + + def find_contest_by_contest_id + @contest = Contest.find(params[:contest_id]) + rescue ActiveRecord::RecordNotFound + render_404 + end + + #���course_id��project + def find_project_by_course_id + @bid = Bid.find params[:course_id] + @project = @bid.courses[0] rescue ActiveRecord::RecordNotFound render_404 end @@ -274,11 +318,29 @@ class ApplicationController < ActionController::Base render_404 end + def find_optional_contest + @contest = Contest.find(params[:contest_id]) unless params[:contest_id].blank? + allowed = User.current.allowed_to?({:controller => params[:controller], :action => params[:action]}, @contest, :global => true) + allowed ? true : deny_access + rescue ActiveRecord::RecordNotFound + render_404 + end + # Finds and sets @project based on @object.project def find_project_from_association 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 + render_404 unless @object.present? + + @contest =@object.contest end def find_model_object @@ -291,6 +353,24 @@ 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 + # @object = model.find(params[:id]) + # self.instance_variable_set('@' + controller_name.singularize, @object) if @object + # end + # rescue ActiveRecord::RecordNotFound + # render_404 + # end + def self.model_object(model) self.model_object = model end diff --git a/app/controllers/attachments_controller.rb b/app/controllers/attachments_controller.rb index 2f642f54..0b2ae02b 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://" + (Setting.host_name.to_s) +"/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 @@ -139,9 +150,9 @@ class AttachmentsController < ApplicationController # Make sure association callbacks are called container = @attachment.container @attachment.container.attachments.delete(@attachment) - if container.attachments.empty? - container.delete - end + #if container.attachments.empty? + #container.delete + #end respond_to do |format| format.html { redirect_to_referer_or respond_path(@bid) } @@ -150,7 +161,13 @@ class AttachmentsController < ApplicationController end def autocomplete - @project = Project.find_by_id(params[:project_id]) + # modify by nwb + if params[:project_id] + @project = Project.find_by_id(params[:project_id]) + elsif params[:course_id] + @course = Course.find_by_id(params[:course_id]) + end + respond_to do |format| format.js end @@ -186,13 +203,47 @@ class AttachmentsController < ApplicationController end end + def add_exist_file_to_course + class_id = params[:class_id] + attachments = params[:attachment][:attach] + + obj = Course.find_by_id(class_id) + attachments.collect do |attach_id| + ori = Attachment.find_by_id(attach_id) + next if ori.blank? + attach_copied_obj = ori.copy + attach_copied_obj.tag_list.add(ori.tag_list) # tag关联 + attach_copied_obj.container = obj + attach_copied_obj.created_on = Time.now + attach_copied_obj.author_id = User.current.id + @obj = obj + @save_flag = attach_copied_obj.save + @save_message = attach_copied_obj.errors.full_messages + end + + respond_to do |format| + format.js + end + rescue NoMethodError + @save_flag = false + @save_message = [] << l(:error_attachment_empty) + respond_to do |format| + format.js + end + end + 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/avatar_controller.rb b/app/controllers/avatar_controller.rb index 3b43fec9..73c1dbd9 100644 --- a/app/controllers/avatar_controller.rb +++ b/app/controllers/avatar_controller.rb @@ -25,7 +25,7 @@ class AvatarController < ApplicationController end end end - if @temp_file && (@temp_file.size > 0) + if @temp_file && (@temp_file.size > 0) diskfile=disk_filename(@source_type,@source_id) @urlfile='/' << File.join("images","avatars",avatar_directory(@source_type),avatar_filename(@source_id,@image_file)) logger.info("Saving avatar '#{diskfile}' (#{@temp_file.size} bytes)") @@ -55,7 +55,7 @@ class AvatarController < ApplicationController # saved = @avatar.save begin f = Magick::ImageList.new(diskfile) - width = 300.0; + width = 300.0 proportion = (width/f[0].columns) height = (f[0].rows*proportion) f.resize_to_fill!(width,height) diff --git a/app/controllers/bids_controller.rb b/app/controllers/bids_controller.rb index d63f0cfb..76872d78 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 @@ -25,7 +26,14 @@ class BidsController < ApplicationController helper :projects helper :words helper :welcome - + + def find_project_by_bid_id + @bid = Bid.find(params[:id]) + @project = @bid.courses[0] + rescue ActiveRecord::RecordNotFound + render_404 + end + def homework_ajax_modal @bid = Bid.find_by_id(params[:id]) # find_bid @@ -176,12 +184,13 @@ class BidsController < ApplicationController @homework.budget = 0 @homework.author_id = User.current.id @homework.commit = 0 - @homework.homework_type = params[:bid][:homework_type] + @homework.homework_type = 1 + @homework.is_evaluation = params[:bid][:is_evaluation] @homework.parent_id = @bid.id @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) @@ -191,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 @@ -281,6 +288,7 @@ class BidsController < ApplicationController end #end + # 显示课程 def show_course bids = Bid.where('parent_id = ?', @bid.id) @courses = [] @@ -369,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 @@ -391,29 +399,31 @@ 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 @homework = HomeworkAttach.new - @homework_list = @bid.homeworks + #@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 + if /#{params[:student_id]}/ =~ pro.user.user_extensions.student_id + @temp << pro + end @temp end @homework_list = @temp @@ -422,22 +432,109 @@ 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") + @homework_list = HomeworkAttach.eager_load(:attachments,:user,:rate_averages).find_by_sql("SELECT homework_attaches.*, + (SELECT AVG(stars) FROM seems_rateable_rates WHERE rateable_type = 'HomeworkAttach' AND rateable_id = homework_attaches.id AND rater_id = #{@bid.author_id}) AS t_score, + (SELECT AVG(stars) FROM seems_rateable_rates WHERE rateable_type = 'HomeworkAttach' AND rateable_id = homework_attaches.id AND rater_id <> #{@bid.author_id}) AS s_score + FROM homework_attaches WHERE bid_id = #{@bid.id} ORDER BY + (CASE WHEN t_score IS NULL THEN 0 ELSE t_score * #{@bid.proportion * 1.0 / 100} END + CASE WHEN s_score IS NULL THEN 0 ELSE s_score * #{1 - @bid.proportion * 1.0 / 100} END) DESC,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] = "" @@ -523,6 +620,7 @@ class BidsController < ApplicationController message = params[:bid_message][:message] + "\n" + params[:reference_content] else message = params[:bid_message][:message] + @m = message end refer_user_id = params[:bid_message][:reference_user_id].to_i @bid.add_jour(User.current, message, refer_user_id) @@ -689,17 +787,19 @@ class BidsController < ApplicationController @bid = Bid.new @bid.name = params[:bid][:name] @bid.description = params[:bid][:description] + @bid.is_evaluation = params[:bid][:is_evaluation] + @bid.proportion = params[:bid][:proportion] @bid.reward_type = 3 # @bid.budget = params[:bid][:budget] @bid.deadline = params[:bid][:deadline] @bid.budget = 0 @bid.author_id = User.current.id @bid.commit = 0 - @bid.homework_type = params[:bid][:homework_type] + @bid.homework_type = 1 @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) @@ -709,19 +809,25 @@ 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 + #respond_to do |format| + # format.html { redirect_to new_homework_course_path(params[:course_id]),:layout => 'base_courses'} + # format.api { render_validation_errors(@bid) } + #end + 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' } @@ -733,11 +839,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' @@ -872,7 +978,7 @@ class BidsController < ApplicationController def find_bid if params[:id] - @bid = Bid.find(params[:id]) + @bid = Bid.find(params[:id], :include => [{:homeworks => :user}]) @user = @bid.author end rescue @@ -881,9 +987,10 @@ class BidsController < ApplicationController def memberAccess # 是课程,则判断当前用户是否参加了课程 - return 0 if @bid.courses.first.project_type == Project::ProjectType_project + return true if current_user.admin? + #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 b5e0b2d8..e0bd9582 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/comments_controller.rb b/app/controllers/comments_controller.rb index b2689d0c..90c034fd 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -18,7 +18,7 @@ class CommentsController < ApplicationController default_search_scope :news model_object News - before_filter :find_model_object + before_filter :find_model_object before_filter :find_project_from_association before_filter :authorize @@ -50,4 +50,6 @@ class CommentsController < ApplicationController @comment = nil @news end + + end diff --git a/app/controllers/contestnotifications_controller.rb b/app/controllers/contestnotifications_controller.rb new file mode 100644 index 00000000..6b05e8e4 --- /dev/null +++ b/app/controllers/contestnotifications_controller.rb @@ -0,0 +1,187 @@ +class ContestnotificationsController < ApplicationController + # GET /contestnotifications + # GET /contestnotifications.json + layout 'base_newcontest' + default_search_scope :contestnotifications + model_object Contestnotification + # before_filter :find_model_object, :except => [:new, :create, :index] + # before_filter :find_contest_from_association, :except => [:new, :create, :index] + before_filter :find_contest_by_contest_id, :only => [:new, :create] + before_filter :find_contest + before_filter :find_author + # before_filter :authorize, :except => [:index] + before_filter :find_optional_contest, :only => [:index] + accept_rss_auth :index + accept_api_auth :index + + before_filter :access_edit_destroy, only: [:edit ,:update, :destroy] + + def find_author + @user = @contest.author + render_404 if @user.nil? + end + def find_contest + @contest = Contest.find(params[:contest_id]) + render_404 if @contest.nil? + end + + + def index + + # @contestnotifications = Contestnotification.all + # + # respond_to do |format| + # format.html # index.html.erb + # format.json { render json: @contestnotifications } + # end + + ### begin ### + case params[:format] + when 'xml', 'json' + @offset, @limit = api_offset_and_limit + else + @limit = 10 + end + + scope = @contest ? @contest.contestnotifications.visible : Contestnotifications.visible + + @contestnotifications_count = scope.count + @contestnotifications_pages = Paginator.new @contestnotifications_count, @limit, params['page'] + @offset ||= @contestnotifications_pages.offset + @contestnotificationss = scope.all(:include => [:author, :contest], + :order => "#{Contestnotification.table_name}.created_at DESC", + :offset => @offset, + :limit => @limit) + + respond_to do |format| + format.html { + @contestnotification = Contestnotification.new # for adding news inline + render :layout => 'base_newcontest' + } + format.api + format.atom { render_feed(@contestnotificationss, :title => (@contest ? @contest.name : Setting.app_title) + ": #{l(:label_contest_notification)}") } + end + ### end ### + end + + # GET /contestnotifications/1 + # GET /contestnotifications/1.json + def show + @contestnotification = Contestnotification.find(params[:id]) + + # + # respond_to do |format| + # format.html # show.html.erb + # format.json { render json: @contestnotification } + # end + @notificationcomments = @contestnotification.notificationcomments + @notificationcomments.reverse! if User.current.wants_notificationcomments_in_reverse_order? + render :layout => 'base_newcontest' + + end + + # GET /contestnotifications/new + # GET /contestnotifications/new.json + def new + # @contestnotification = Contestnotification.new +# + # respond_to do |format| + # format.html # new.html.erb + # format.json { render json: @contestnotification } + # end + @contestnotification = Contestnotification.new(:contest => @contest, :author => User.current) + render :layout => 'base_newcontest' + end + + # GET /contestnotifications/1/edit + def edit + @contestnotification = Contestnotification.find(params[:id]) + end + + # POST /contestnotifications + # POST /contestnotifications.json + def create + # @contestnotification = Contestnotification.new(params[:contestnotification]) + # + # respond_to do |format| + # if @contestnotification.save + # format.html { redirect_to @contestnotification, notice: 'Contestnotification was successfully created.' } + # format.json { render json: @contestnotification, status: :created, location: @contestnotification } + # else + # format.html { render action: "new" } + # format.json { render json: @contestnotification.errors, status: :unprocessable_entity } + # end + # end + @contestnotification = Contestnotification.new(:contest => @contest, :author => User.current) + @contestnotification.safe_attributes = params[:contestnotification] + @contestnotification.save_attachments(params[:attachments]) + if @contestnotification.save + render_attachment_warning_if_needed(@contestnotification) + flash[:notice] = l(:notice_successful_create) + redirect_to contest_contestnotifications_path(@contest) + else + layout_file = 'base_newcontest' + render :action => 'new', :layout => layout_file + end + end + + # PUT /contestnotifications/1 + # PUT /contestnotifications/1.json + def update + # @contestnotification = Contestnotification.find(params[:id]) + # + # respond_to do |format| + # if @contestnotification.update_attributes(params[:contestnotification]) + # format.html { redirect_to @contestnotification, notice: 'Contestnotification was successfully updated.' } + # format.json { head :no_content } + # else + # format.html { render action: "edit" } + # format.json { render json: @contestnotification.errors, status: :unprocessable_entity } + # end + # end + @contestnotification = Contestnotification.find(params[:id]) + @contestnotification.safe_attributes = params[:contestnotification] + @contestnotification.save_attachments(params[:attachments]) + if @contestnotification.save + render_attachment_warning_if_needed(@contestnotification) + flash[:notice] = l(:notice_successful_update) + redirect_to contest_contestnotification_path(@contestnotification.contest, @contestnotification) + else + render :action => 'edit' + end + end + + # DELETE /contestnotifications/1 + # DELETE /contestnotifications/1.json + def destroy + # @contestnotification = Contestnotification.find(params[:id]) + # @contestnotification.destroy + # + # respond_to do |format| + # format.html { redirect_to contestnotifications_url } + # format.json { head :no_content } + # end + @contestnotification = Contestnotification.find(params[:id]) + @contestnotification.destroy + redirect_to contest_contestnotifications_path(@contest) + end + + private + + def find_optional_contest + return true unless params[:id] + @contest = Contest.find(params[:id]) + # authorize + rescue ActiveRecord::RecordNotFound + render_404 + end + + def access_edit_destroy + if (User.current.admin? && User.current.logged? )||(User.current == @contest.author && User.current.logged?) + return true + else + render_403 + end + end + +end diff --git a/app/controllers/contests_controller.rb b/app/controllers/contests_controller.rb index b51a1143..987881a8 100644 --- a/app/controllers/contests_controller.rb +++ b/app/controllers/contests_controller.rb @@ -4,9 +4,9 @@ class ContestsController < ApplicationController menu_item :respond menu_item :project, :only => :show_project menu_item :application, :only => :show_softapplication - menu_item :attendingcontest, :only => :show_attendingcontest - menu_item :contestnotification, :only => :show_notification - before_filter :find_contest, :only => [:show_contest, :show_project, :show_softapplication, :show_attendingcontest, :show_notification, :set_reward_project, :set_reward_softapplication, :create,:destroy,:more,:back,:add,:add_softapplication,:new,:show_results, :set_reward, + menu_item :attendingcontests, :only => :show_attendingcontest + menu_item :contestnotifications, :only => :index + before_filter :find_contest, :only => [:show_contest, :show_project, :show_softapplication, :show_attendingcontest, :index, :set_reward_project, :set_reward_softapplication, :create,:destroy,:more,:back,:add,:add_softapplication,:new,:show_results, :set_reward, :show_contest_project, :show_contest_user, :join_in_contest, :unjoin_in_contest, :new_join,:show_participator, :settings] # added by fq @@ -26,8 +26,11 @@ class ContestsController < ApplicationController # @contests = Contest.visible # @contests ||= [] @offset, @limit = api_offset_and_limit({:limit => 10}) - @contests = Contest.visible + @contests = Contest.visible @contests = @contests.like(params[:name]) if params[:name].present? + if params[:contests_search] + (redirect_to contests_path, :notice => l(:label_sumbit_empty);return) if params[:name].blank? + end @contest_count = @contests.count @contest_pages = Paginator.new @contest_count, @limit, params['page'] @@ -74,6 +77,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') @@ -210,11 +232,14 @@ class ContestsController < ApplicationController # @contesting_project_pages = Paginator.new @contesting_project_count, per_page_option, params['page'] @membership.each do |membership| unless(membership.project.project_type==1) - membership.member_roles.each{|role| - if(role.role_id == 3) - @option << membership.project - end - } + #membership.member_roles.each{|role| + # if(role.role_id == 3) + # @option << membership.project + # end + #} + if User.current.allowed_to?({:controller => "projects", :action => "edit"}, membership.project, :global => false) + @option << membership.project + end end end @user = @contest.author @@ -301,11 +326,15 @@ class ContestsController < ApplicationController # @contesting_project_pages = Paginator.new @contesting_project_count, per_page_option, params['page'] @membership.each do |membership| unless(membership.project.project_type==1) - membership.member_roles.each{|role| - if(role.role_id == 3) + #membership.member_roles.each{|role| + #if(role.role_id == 3) + #@option << membership.project + #end + #} + #拥有编辑项目权限的可将该项目参赛 + if User.current.allowed_to?({:controller => "projects", :action => "edit"}, membership.project, :global => false) @option << membership.project - end - } + end end end @user = @contest.author diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb index 215dd3a5..157de5ce 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,657 @@ 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 + name = params[:name] + (redirect_to courses_path, :notice => l(:label_sumbit_empty);return) if name.blank? + @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"). + 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}.school_id = ?", @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 + @homework = Bid.new + @homework.proportion + @homework.safe_attributes = params[:bid] + if (User.current.logged? && User.current.member_of_course?(Course.find params[:id] )) + 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/documents_controller.rb b/app/controllers/documents_controller.rb index 51486f25..464c4a2b 100644 --- a/app/controllers/documents_controller.rb +++ b/app/controllers/documents_controller.rb @@ -62,6 +62,7 @@ class DocumentsController < ApplicationController def create @document = @project.documents.build @document.safe_attributes = params[:document] + @document.user = User.current @document.save_attachments(params[:attachments]) if @document.save render_attachment_warning_if_needed(@document) diff --git a/app/controllers/files_controller.rb b/app/controllers/files_controller.rb index ed6f9937..b5c67478 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/forums_controller.rb b/app/controllers/forums_controller.rb index 991af015..f3ebfad8 100644 --- a/app/controllers/forums_controller.rb +++ b/app/controllers/forums_controller.rb @@ -129,6 +129,7 @@ class ForumsController < ApplicationController format.html { redirect_to @forum, notice: l(:label_forum_create_succ) } format.json { render json: @forum, status: :created, location: @forum } else + flash.now[:error] = "#{l :label_forum_create_fail}: #{@forum.errors.full_messages[0]}" format.html { render action: "new" } format.json { render json: @forum.errors, status: :unprocessable_entity } end @@ -165,6 +166,8 @@ class ForumsController < ApplicationController def search_forum # @forums = paginateHelper Forum.where("name LIKE '%#{params[:name]}%'") + name = params[:name] + (redirect_to forums_path, :notice => l(:label_sumbit_empty);return) if name.blank? @offset, @limit = api_offset_and_limit({:limit => 10}) @forums_all = Forum.where("name LIKE '%#{params[:name]}%'") @forums_count = @forums_all.count diff --git a/app/controllers/homework_attach_controller.rb b/app/controllers/homework_attach_controller.rb index 64bfe5c4..83a6aa05 100644 --- a/app/controllers/homework_attach_controller.rb +++ b/app/controllers/homework_attach_controller.rb @@ -1,5 +1,31 @@ class HomeworkAttachController < ApplicationController + include CoursesHelper ############################### + #判断当前角色权限时需先找到当前操作的project + 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_course_by_bid_id + @bid = Bid.find(params[:id]) + @course = @bid.courses[0] + rescue ActiveRecord::RecordNotFound + render_404 + end + + def find_course_by_hoemwork_id + @homework = HomeworkAttach.find(params[:id]) + @course = @homework.bid.courses[0] + end + + #获取作业的成员 + def get_homework_member homework + @hoemwork_users = users_for_homework(@homework) + @members = members_for_homework(@homework,@hoemwork_users,params[:q]) + @members = paginateHelper @members,10 + end + def index @homeworks = HomeworkAttach.all respond_to do |format| @@ -8,106 +34,236 @@ class HomeworkAttachController < ApplicationController end end - def add_users users - if users != nil && users.count > 0 - users.each do |user| - @homework.homework_users.build(:user_id => user.id) - @homework.save + #作业添加成员(参与人员) + def add_homework_users + 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] + attrs = params[:membership].dup + user_ids = attrs.delete(:user_ids) + user_ids.each do |user_id| + @homework.homework_users.build(:user_id => user_id) + end + end end + @homework.save + get_homework_member @homework + respond_to do |format| + format.js + end + else + render_403 :message => :notice_not_authorized + end + end + + #作业删除成员(参与人员) + def destory_homework_users + #@homework = HomeworkAttach.find(params[:id]) + 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 + respond_to do |format| + format.js + end + else + render_403 :message => :notice_not_authorized end end def create - 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) - user_id = params[:user_id] - bid_id = params[:bid_id] - sta = 0 - name = params[:new_form][:name] - description = params[:new_form][:description] - options = { - :user_id => user_id, - :state => sta, - :name => name, - :description => description, - :bid_id => bid_id - } - - @homework = HomeworkAttach.new(options) - @homework.save_attachments(params[:attachments]) - render_attachment_warning_if_needed(@homework) - - @homework.save - respond_to do |format| - if @homework.save - format.html { redirect_to @homework, notice: 'Post was successfully created.' } - format.json { render json: @homework, status: :created, location: @homework } + bid = Bid.find params[:bid_id] + 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 - format.html { render action: "new" } - format.json { render json: @homework.errors, status: :unprocessable_entity } + project_id = 0 end + sta = 0 + name = params[:new_form][:name] + description = params[:new_form][:description] + options = { + :user_id => user_id, + :state => sta, + :name => name, + :description => description, + :bid_id => bid_id, + :project_id => project_id + } + + + #@homework_list = @bid.homeworks + + @homework = HomeworkAttach.new(options) + @homework.save_attachments(params[:attachments]) + render_attachment_warning_if_needed(@homework) + + if @homework.save + respond_to do |format| + format.html { redirect_to course_for_bid_path @homework.bid } + format.json { head :no_content } + end + else + render_403 :message => :notice_not_authorized + end + else + render_403 :message => :notice_has_homework end + else + render_403 :message => :notice_not_authorized end end def new - @homework = HomeworkAttach.new @bid = Bid.find(params[:id]) + 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]}) - respond_to do |format| - format.html # new.html.erb - format.json { render json: @homework } + #@members = paginateHelper @members,10 + #@all_user = [] + #@bid.courses.first.members.each do |member| + # @all_user << member.user + #end + @homework = HomeworkAttach.new + #@homework_user = members_for_homework(@homework) + User.current + #@members = @all_user - @homework_user + respond_to do |format| + format.html # new.html.erb + format.json { render json: @homework } + end + else + render_403 :message => :notice_not_authorized end end + #获取作业成员的集合 + 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?(course) + get_homework_member @homework + else + raise "error" + end + respond_to do |format| + format.js + end + end + + #获取指定作业的所有成员 + def users_for_homework homework + homework.nil? ? [] : (homework.users + [homework.user]) + end + + #获取可选成员列表 + #homework:作业 + #users:该作业所有成员 + #q:模糊匹配的用户的昵称 + def members_for_homework homework,users,q + homework.bid.courses.first.members.joins(:member_roles).where("member_roles.role_id IN (:role_id) and user_id not in (:users)", {:role_id => [5, 10],:users => users}).joins(:user).where("users.login like '%#{q}%'") + end + def edit - @homework = HomeworkAttach.find(params[:id]) + #@homework = HomeworkAttach.find(params[:id]) + 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 + render_403 :message => :notice_not_authorized + end end def update - @homework = HomeworkAttach.find(params[:id]) - respond_to do |format| - if @post.update_attributes(params[:homework]) - format.html { redirect_to @homework, notice: 'Homework was successfully updated.' } - format.json { head :no_content } + #@homework = HomeworkAttach.find(params[:id]) + course = @homework.bid.courses.first + 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 - format.html { render action: "edit" } - format.json { render json: @homework.errors, status: :unprocessable_entity } + 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 course_for_bid_path @homework.bid } + format.json { head :no_content } + end + else + end + else + render_403 :message => :notice_not_authorized end end def destroy - @homework = HomeworkAttach.find(params([:id])) - @homework.destroy - respond_to do |format| - format.html {render @homework} - format.json {render json: @homework} + #@homework = HomeworkAttach.find(params[:id]) + if User.current.admin? || User.current == @homework.user + if @homework.destroy + respond_to do |format| + format.html { redirect_to course_for_bid_path @homework.bid } + format.json { head :no_content } + end + else + end + else + render_403 :message => :notice_not_authorized end end #显示作业信息 def show - @homework = HomeworkAttach.find(params[:id]) - # 打分统计 - stars_reates = @homework. - rates(:quality) - stars_reates_count = stars_reates.count == 0 ? 1 : stars_reates.count - stars_status = stars_reates.select("stars, count(*) as scount"). - group("stars") - @stars_status_map = Hash.new(0.0) - stars_status.each do |star_status| - percent = (star_status.scount * 1.0/ stars_reates_count) * 100.to_f - percent_m = format("%.2f", percent) - @stars_status_map["star#{star_status.stars.to_i}".to_sym] = - percent_m.to_s + "%" + #@homework = HomeworkAttach.find(params[:id]) + if User.current.admin? || User.current.member_of_course?(@homework.bid.courses.first) + # 打分统计 + stars_reates = @homework. + rates(:quality) + stars_reates_count = stars_reates.count == 0 ? 1 : stars_reates.count + stars_status = stars_reates.select("stars, count(*) as scount"). + group("stars") + @stars_status_map = Hash.new(0.0) + stars_status.each do |star_status| + percent = (star_status.scount * 1.0/ stars_reates_count) * 100.to_f + percent_m = format("%.2f", percent) + @stars_status_map["star#{star_status.stars.to_i}".to_sym] = + percent_m.to_s + "%" + end + #是否已经进行过评价 + @has_evaluation = stars_reates.where("rater_id = ?",User.current).count > 0 + #是否开启互评功能 + @is_evaluation = @homework.bid.is_evaluation == 1 || @homework.bid.is_evaluation == nil + @limit = 10 + @jours = @homework.journals_for_messages.where("is_comprehensive_evaluation is null").order("created_on DESC") + @feedback_count = @jours.count + @feedback_pages = Paginator.new @feedback_count, @limit, params['page'] + @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 - @limit = 10 - @jours = @homework.journals_for_messages.where("is_comprehensive_evaluation is null").order("created_on DESC") - @feedback_count = @jours.count - @feedback_pages = Paginator.new @feedback_count, @limit, params['page'] - @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") end #删除留言 @@ -136,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/homework_users_controller.rb b/app/controllers/homework_users_controller.rb index cb55d965..5f473b42 100644 --- a/app/controllers/homework_users_controller.rb +++ b/app/controllers/homework_users_controller.rb @@ -1,3 +1,14 @@ class HomeworkUsersController < ApplicationController - + #新增数据 + def create option + user = HomeworkUser.new option + user.save + user + end + #删除数据 + def destory homework_user + user = HomeworkUser.find homework_user + user.destroy + user + end end diff --git a/app/controllers/issue_categories_controller.rb b/app/controllers/issue_categories_controller.rb index a716653a..9803eb78 100644 --- a/app/controllers/issue_categories_controller.rb +++ b/app/controllers/issue_categories_controller.rb @@ -19,6 +19,7 @@ class IssueCategoriesController < ApplicationController menu_item :settings model_object IssueCategory before_filter :find_model_object, :except => [:index, :new, :create] + #before_filter :find_model_object_contest, :except => [:index, :new, :create] before_filter :find_project_from_association, :except => [:index, :new, :create] before_filter :find_project_by_project_id, :only => [:index, :new, :create] before_filter :authorize @@ -119,4 +120,10 @@ class IssueCategoriesController < ApplicationController super @category = @object end + + def find_model_object_contest + super + @category = @object + end + end diff --git a/app/controllers/mail_handler_controller.rb b/app/controllers/mail_handler_controller.rb index 3a4b219b..183a1ea5 100644 --- a/app/controllers/mail_handler_controller.rb +++ b/app/controllers/mail_handler_controller.rb @@ -29,6 +29,11 @@ class MailHandlerController < ActionController::Base end end + #取消邮件通知 + def cancel_mail_notify + + end + private def check_credential diff --git a/app/controllers/members_controller.rb b/app/controllers/members_controller.rb index 30c6c7e8..5ddebe70 100644 --- a/app/controllers/members_controller.rb +++ b/app/controllers/members_controller.rb @@ -17,19 +17,21 @@ class MembersController < ApplicationController model_object Member before_filter :find_model_object, :except => [:index, :create, :autocomplete] + #before_filter :find_model_object_contest, :except => [:index, :create, :autocomplete] before_filter :find_project_from_association, :except => [:index, :create, :autocomplete] 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| @@ -59,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 @@ -188,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/memos_controller.rb b/app/controllers/memos_controller.rb index b4de06fb..62f860a9 100644 --- a/app/controllers/memos_controller.rb +++ b/app/controllers/memos_controller.rb @@ -51,7 +51,10 @@ class MemosController < ApplicationController @memo_new = @memo.dup @memo = @memo.root # 取出楼主,防止输入帖子id让回复作为主贴显示 - @memo.update_column(:viewed_count, (@memo.viewed_count.to_i + 1)) + unless @memo.new_record? + @memo.update_column(:viewed_count, (@memo.viewed_count.to_i + 1)) + end + page = params[:page] if params[:r] && page.nil? @@ -68,10 +71,14 @@ class MemosController < ApplicationController limit(@reply_pages.per_page). offset(@reply_pages.offset). all + if @memo.new_record? + format.html { redirect_to back_url, error: "#{l :label_memo_create_fail}: #{@memo.errors.full_messages[0]}" } + else + format.html { render action: :show }#, error: "#{l :label_memo_create_fail}: #{@memo.errors.full_messages[0]}" } + # format.html { redirect_to back_memo_or_forum_url}#, error: "#{l :label_memo_create_fail}: #{@memo.errors.full_messages[0]}" } + format.json { render json: @memo.errors, status: :unprocessable_entity } + end - format.html { render action: :show }#, error: "#{l :label_memo_create_fail}: #{@memo.errors.full_messages[0]}" } - # format.html { redirect_to back_memo_or_forum_url}#, error: "#{l :label_memo_create_fail}: #{@memo.errors.full_messages[0]}" } - format.json { render json: @memo.errors, status: :unprocessable_entity } end end end diff --git a/app/controllers/messages_controller.rb b/app/controllers/messages_controller.rb index 150071b4..2915ff8f 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 @@ -84,8 +87,11 @@ class MessagesController < ApplicationController call_hook(:controller_messages_reply_after_save, { :params => params, :message => @reply}) attachments = Attachment.attach_files(@reply, params[:attachments]) render_attachment_warning_if_needed(@reply) + else + #render file: 'messages#show', layout: 'base_courses' end redirect_to board_message_path(@board, @topic, :r => @reply) + end # Edit a message @@ -138,8 +144,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 a87df4fe..9b169cb8 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 ee3db741..8bce84f9 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/notificationcomments_controller.rb b/app/controllers/notificationcomments_controller.rb new file mode 100644 index 00000000..80500ab1 --- /dev/null +++ b/app/controllers/notificationcomments_controller.rb @@ -0,0 +1,27 @@ +class NotificationcommentsController < ApplicationController + # default_search_scope :contestnotifications + # model_object Contestnotifications + # before_filter :authorize + + def create + #raise Unauthorized unless @contestnotifications.notificationcommentable? + @contest = Contest.find(params[:contest_id]) + @contestnotification = Contestnotification.find(params[:contestnotification_id]) + + # @notificaioncomment = Notificationcomment.new + # @notificaioncomment.safe_attributes = params[:notificationcomment] + # @notificaioncomment.author = User.current + comment = @contestnotification.notificationcomments.new(params[:notificationcomment].merge(author_id: User.current.id)) + if comment.save + flash[:notice] = l(:label_comment_added) + end + + redirect_to contest_contestnotification_path(@contest, @contestnotification) + end + + def destroy + @contestnotifications.notificaioncomments.find(params[:notificaioncomment_id]).destroy + redirect_to contest_contestnotification_path(@contestnotifications) + end + +end diff --git a/app/controllers/praise_tread_controller.rb b/app/controllers/praise_tread_controller.rb index 53df54e9..acfd785d 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 @@ -71,6 +79,10 @@ class PraiseTreadController < ApplicationController @obj = Bid.find_by_id(id) when 'Contest' @obj = Contest.find_by_id(id) + when 'Memo' + @obj = Memo.find_by_id(id) + when 'Message' + @obj = Message.find_by_id(id) end return @obj end diff --git a/app/controllers/previews_controller.rb b/app/controllers/previews_controller.rb index 0083116d..579f8caa 100644 --- a/app/controllers/previews_controller.rb +++ b/app/controllers/previews_controller.rb @@ -16,10 +16,11 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. class PreviewsController < ApplicationController - before_filter :find_project, :find_attachments + before_filter :find_project, :find_attachments, :find_contest, except: [:contestnotification] def issue @issue = @project.issues.find_by_id(params[:id]) unless params[:id].blank? + @issue = @contest.issues.find_by_id(params[:id]) unless params[:id].blank? if @issue @description = params[:issue] && params[:issue][:description] if @description && @description.gsub(/(\r?\n|\n\r?)/, "\n") == @issue.description.to_s.gsub(/(\r?\n|\n\r?)/, "\n") @@ -41,6 +42,12 @@ class PreviewsController < ApplicationController render :partial => 'common/preview' end + def contestnotification + @previewed = Contestnotification.find(params[:id]) + @text = (params[:contestnotification] ? params[:contestnotification][:description] : nil) + render :partial => 'common/preview' + end + private def find_project @@ -50,4 +57,20 @@ class PreviewsController < ApplicationController render_404 end + def contestnotifications + if params[:id].present? && contestnotifications = Contestnotifications.visible.find_by_id(params[:id]) + @previewed = contestnotifications + end + @text = (params[:contestnotifications] ? params[:contestnotifications][:description] : nil) + render :partial => 'common/preview' + end + + private + def find_contest + contest_id = (params[:issue] && params[:issue][:contest_id]) || params[:contest_id] + @contest = Contest.find(contest_id) + rescue ActiveRecord::RecordNotFound + render_404 + end + end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 16d9d71d..9639c9d0 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -37,11 +37,12 @@ class ProjectsController < ApplicationController # before_filter :authorize, :except => [:new_join, :new_homework, :homework, :statistics, :search, :watcherlist, :index, :list, :new, :create, :copy, :archive, :unarchive, :destroy, :member, :focus, :file, # :statistics, :feedback, :course, :enterprise_course, :course_enterprise, :project_respond, :share, # :show_projects_score, :issue_score_index, :news_score_index, :file_score_index, :code_submit_score_index, :projects_topic_score_index] + #此条勿删 课程相关权限 ,:new_homework,:homework,:feedback,,:member before_filter :authorize, :only => [:show, :settings, :edit, :sort_project_members, :update, :modules, :close, :reopen,:view_homework_attaches,:course] before_filter :authorize_global, :only => [:new, :create,:view_homework_attaches] before_filter :require_admin, :only => [ :copy, :archive, :unarchive, :destroy, :calendar] before_filter :file, :statistics, :watcherlist - + before_filter :find_project_repository, :only => [:show] # 除非项目内人员,不可查看成员, TODO: 完了写报表里去 before_filter :memberAccess, only: :member @@ -77,6 +78,14 @@ class ProjectsController < ApplicationController ### added by william include ActsAsTaggableOn::TagsHelper + def find_project_repository + unless @project.repositories.nil? + @project.repositories.each do |repository| + repository.fetch_changesets if Setting.autofetch_changesets? + end + end + end + def enterprise_course session[:enterprise_college] = 2 respond_to do |format| @@ -352,27 +361,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 @@ -721,6 +716,9 @@ class ProjectsController < ApplicationController @teachers= searchTeacherAndAssistant(@project) @canShowRealName = isCourseTeacher(User.current.id) end + + #勿删 real_name action为虚拟的该方法并不存在,用来辅助判断真名权限 + #勿删 @canShowRealName = User.current.allowed_to?({:controller => "projects", :action => "real_name"}, @project || @projects, :global => false) respond_to do |format| format.html{render :layout => 'base_courses' if @base_courses_tag==1} format.api @@ -916,11 +914,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 70f7572a..3b97802f 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/controllers/school_controller.rb b/app/controllers/school_controller.rb index ec14ba5c..c8b495fe 100644 --- a/app/controllers/school_controller.rb +++ b/app/controllers/school_controller.rb @@ -105,7 +105,7 @@ class SchoolController < ApplicationController end options = "" @school.each do |s| - options << "
  • #{s.name}
  • " + options << "
  • #{s.name}
  • " end render :text => options diff --git a/app/controllers/softapplications_controller.rb b/app/controllers/softapplications_controller.rb index b8d81b10..362a04f5 100644 --- a/app/controllers/softapplications_controller.rb +++ b/app/controllers/softapplications_controller.rb @@ -108,11 +108,16 @@ class SoftapplicationsController < ApplicationController # @contesting_project_pages = Paginator.new @contesting_project_count, per_page_option, params['page'] @membership.each do |membership| unless(membership.project.project_type==1) - membership.member_roles.each{|role| - if(role.role_id == 3) + #membership.member_roles.each{|role| + # if(role.role_id == 3) + # @option << membership.project + # end + #} + + #拥有编辑项目权限的可操作该项目 + if User.current.allowed_to?({:controller => "projects", :action => "edit"}, membership.project, :global => false) @option << membership.project - end - } + end end end diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index 84c3aff0..ba01aa99 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 @@ -62,14 +64,18 @@ class TagsController < ApplicationController @forum_tags_num, @attachments_tags_num, @open_source_projects_num = get_tags_size # 获取搜索结果 - @obj,@obj_pages,@results_count,@users_results, + @obj, + @obj_pages, + @results_count, + @users_results, @projects_results, @issues_results, @bids_results, - @forums_results, - @attachments_results, - @contests_tags, - @open_source_projects_results = refresh_results(@obj_id,@obj_flag,@selected_tags) + @forums_results, + attachments_results, + @contests_results, + @courses_results, + @open_source_projects_results= refresh_results(@obj_id,@obj_flag,@selected_tags) # 这里是做tag推荐用的, 用来生产推荐的tags unless @obj.nil? @@ -94,13 +100,18 @@ class TagsController < ApplicationController $related_tags.delete(@tag) # 获取搜索结果 - @obj,@obj_pages,@results_count,@users_results, + @obj, + @obj_pages, + @results_count, + @users_results, @projects_results, @issues_results, @bids_results, - @forums_results, - @attachments_results, - @contests_results = refresh_results(@obj_id,@show_flag) + @forums_results, + attachments_results, + @contests_results, + @courses_results, + @open_source_projects_results= refresh_results(@obj_id,@show_flag) end # 删除已选tag @@ -112,13 +123,18 @@ class TagsController < ApplicationController $selected_tags.delete(@tag) # 获取搜索结果 - @obj,@obj_pages,@results_count,@users_results, + @obj, + @obj_pages, + @results_count, + @users_results, @projects_results, @issues_results, @bids_results, @forums_results, - @attachments_results, - @contests_results = refresh_results(@obj_id,@show_flag) + attachments_results, + @contests_results, + @courses_results, + @open_source_projects_results= refresh_results(@obj_id,@show_flag) end def show_all @@ -188,6 +204,7 @@ class TagsController < ApplicationController @obj_pages = nil @obj = nil @result = nil + @courses_results = nil # 这里为了提高系统的响应速度 把搜索结果放到case中去了 case obj_flag @@ -219,6 +236,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 +252,7 @@ class TagsController < ApplicationController @forums_results, attachments_results, @contests_results, + @courses_results, @open_source_projects_results] end @@ -246,14 +267,14 @@ class TagsController < ApplicationController # 获取有某类对象的tag总数 def get_tags_size - @issues_tags_num = Issue.tag_counts.size - @projects_tags_num = Project.tag_counts.size - @users_tags_num = User.tag_counts.size - @bids_tags_num = Bid.tag_counts.size - forum_tags_num = Forum.tag_counts.size - attachment_tags_num = Attachment.tag_counts.size - @open_source_projects_num = OpenSourceProject.tag_counts.size - @contests_tags_num = Contest.tag_counts.size + @issues_tags_num = ActsAsTaggableOn::Tagging.where(taggable_type:"Issue").count + @projects_tags_num = ActsAsTaggableOn::Tagging.where(taggable_type:"Project").count + @users_tags_num = ActsAsTaggableOn::Tagging.where(taggable_type:"User").count + @bids_tags_num = ActsAsTaggableOn::Tagging.where(taggable_type:"Bid").count + forum_tags_num = ActsAsTaggableOn::Tagging.where(taggable_type:"Forum").count + attachment_tags_num = ActsAsTaggableOn::Tagging.where(taggable_type:"Attachment").count + @open_source_projects_num = ActsAsTaggableOn::Tagging.where(taggable_type:"OpenSourceProject").count + @contests_tags_num = ActsAsTaggableOn::Tagging.where(taggable_type:"Contest").count return @users_tags_num,@projects_tags_num,@issues_tags_num,@bids_tags_num, forum_tags_num, attachment_tags_num, @contests_tags_num, @open_source_projects_num end @@ -279,6 +300,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 6452bcc8..1c2db7f7 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 @@ -50,6 +52,7 @@ class UsersController < ApplicationController helper :custom_fields include CustomFieldsHelper include AvatarHelper + include WordsHelper # added by liuping 关注 @@ -92,7 +95,11 @@ class UsersController < ApplicationController # added by bai def show_score - + + end + + def show_new_score + render :layout => false end # end @@ -200,19 +207,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 @@ -229,7 +236,10 @@ class UsersController < ApplicationController def user_newfeedback @jours = @user.journals_for_messages.where('m_parent_id IS NULL').order('created_on DESC') @jours.update_all(:is_readed => true, :status => false) - + @jours.each do |journal| + fetch_user_leaveWord_reply(journal).update_all(:is_readed => true, :status => false) + end + @limit = 10 @feedback_count = @jours.count @feedback_pages = Paginator.new @feedback_count, @limit, params['page'] @@ -363,7 +373,7 @@ class UsersController < ApplicationController def search sort_init 'login', 'asc' sort_update %w(login firstname lastname mail admin created_on last_login_on) - + (redirect_to users_path, :notice => l(:label_sumbit_empty);return) if params[:name].blank? case params[:format] when 'xml', 'json' @offset, @limit = api_offset_and_limit({:limit => 15}) @@ -669,6 +679,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 +722,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 +781,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/versions_controller.rb b/app/controllers/versions_controller.rb index 49e32ba1..0bbbd1bd 100644 --- a/app/controllers/versions_controller.rb +++ b/app/controllers/versions_controller.rb @@ -20,6 +20,7 @@ class VersionsController < ApplicationController menu_item :roadmap model_object Version before_filter :find_model_object, :except => [:index, :new, :create, :close_completed] + #before_filter :find_model_object_contest, :except => [:index, :new, :create] before_filter :find_project_from_association, :except => [:index, :new, :create, :close_completed] before_filter :find_project_by_project_id, :only => [:index, :new, :create, :close_completed] before_filter :authorize @@ -154,6 +155,13 @@ class VersionsController < ApplicationController redirect_to settings_project_path(@project, :tab => 'versions') end + def close_completed_contest + if request.put? + @contest.close_completed_versions + end + redirect_to settings_contest_path(@contest, :tab => 'versions') + end + def destroy if @version.fixed_issues.empty? @version.destroy diff --git a/app/controllers/watchers_controller.rb b/app/controllers/watchers_controller.rb index b1fbfb8e..50bb2ccd 100644 --- a/app/controllers/watchers_controller.rb +++ b/app/controllers/watchers_controller.rb @@ -122,7 +122,9 @@ class WatchersController < ApplicationController end def find_watchables + #根据参数获取关注对象的类型(user、project) klass = Object.const_get(params[:object_type].camelcase) rescue nil + #判断获取的对象类型能否响应‘watched_by’方法 if klass && klass.respond_to?('watched_by') @watchables = klass.find_all_by_id(Array.wrap(params[:object_id])) raise Unauthorized if @watchables.any? {|w| w.respond_to?(:visible?) && !w.visible?} diff --git a/app/controllers/welcome_controller.rb b/app/controllers/welcome_controller.rb index c662c44f..3e708b94 100644 --- a/app/controllers/welcome_controller.rb +++ b/app/controllers/welcome_controller.rb @@ -18,16 +18,10 @@ class WelcomeController < ApplicationController caches_action :robots # before_filter :fake, :only => [:index, :course] - before_filter :entry_select_course, :entry_select_contest, :entry_select_user, :only => [:index] + before_filter :entry_select, :only => [:index] def index - projectActive = Project.project_entities.active - @projectCount = projectActive.count - @projectPublicCount = projectActive.all_public.count - @projectHidenCount = @projectCount - @projectPublicCount - @developerCount = User.developer.count - @allUsercount = User.count end def robots @@ -36,10 +30,12 @@ class WelcomeController < ApplicationController end def course - @courseCount = Project.course_entities.count - @teacherCount = User.teacher.count - @studentCount = User.student.count - @logoLink = logolink() + if params[:school_id] + @school_id = params[:school_id] + elsif User.current.logged? && User.current.user_extensions.school + @school_id = User.current.user_extensions.school.try(:id) + end + @logoLink ||= logolink() end @@ -84,8 +80,7 @@ class WelcomeController < ApplicationController redirect_to projects_search_path(:name => search_condition, :project_type => Project::ProjectType_project) when :courses - redirect_to projects_search_path(:name => search_condition, - :project_type => Project::ProjectType_course) + redirect_to courses_search_path(:name => search_condition) when :users redirect_to users_search_path(:name => search_condition) when :users_teacher @@ -93,7 +88,8 @@ class WelcomeController < ApplicationController when :users_student redirect_to users_search_path(:name => search_condition, :role => :student) else - redirect_to home_path, :alert => l(:label_sumbit_empty) + #redirect_to home_path, :alert => l(:label_sumbit_empty) + (redirect_to home_path, :notice => l(:label_sumbit_empty);return) #if params[:name].blank? end } end @@ -101,9 +97,28 @@ class WelcomeController < ApplicationController private + def entry_select + url = request.original_url + if url.include?("course.trustie.net") + course + render :course + return 0 + elsif url.include?("contest.trustie.net") + contest + render :contest + return 0 + elsif url.include?("user.trustie.net") + redirect_to(:controller => "users", :action => "index") + end + + + end + # 判断网站的入口,是课程 course 则跳过index去渲染 course 方法 def entry_select_course - (course() and render :course and return 0) if request.original_url.match(/course\.trustie\.net/) + if request.original_url.match(/course\.trustie\.net/) + (course() and render :course and return 0) + end end def entry_select_contest @@ -121,25 +136,25 @@ class WelcomeController < ApplicationController end end - def render(*args) - _fake if @fake_filter - super - end + # def render(*args) + # _fake if @fake_filter + # super + # end - private + # private - def fake - @fake_filter = true - end + # def fake + # @fake_filter = true + # end - # 骗子方法 - def _fake - instance_variables.map { |variable| - if variable.to_s =~ /Count$/ - self.instance_variable_set(variable.to_sym, - ("1" + (self.instance_variable_get(variable.to_sym).to_s)).to_i) - end - } - end + # # 骗子方法 + # def _fake + # instance_variables.map { |variable| + # if variable.to_s =~ /Count$/ + # self.instance_variable_set(variable.to_sym, + # ("1" + (self.instance_variable_get(variable.to_sym).to_s)).to_i) + # end + # } + # end end diff --git a/app/controllers/words_controller.rb b/app/controllers/words_controller.rb index bfc1eacb..a4f53c10 100644 --- a/app/controllers/words_controller.rb +++ b/app/controllers/words_controller.rb @@ -56,7 +56,8 @@ class WordsController < ApplicationController reply_user_id = params[:reference_user_id] reply_id = params[:reference_message_id] # 暂时不实现 content = params[:user_notes] - options = {:user_id => author_id, + options = {:user_id => author_id, + :status => true, :m_parent_id => parent_id, :m_reply_id => reply_id, :reply_id => reply_user_id, @@ -163,6 +164,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 +197,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 +222,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 57078a43..33a569f5 100644 --- a/app/controllers/zipdown_controller.rb +++ b/app/controllers/zipdown_controller.rb @@ -1,7 +1,21 @@ class ZipdownController < ApplicationController + #查找项目(课程) + before_filter :find_project_by_bid_id, :only => [:assort] + #检查权限 + #勿删 before_filter :authorize, :only => [:assort,:download_user_homework] SAVE_FOLDER = "#{Rails.root}/files" OUTPUT_FOLDER = "#{Rails.root}/tmp/archiveZip" + #通过作业Id找到项目(课程) + def find_project_by_bid_id + obj_class = params[:obj_class] + obj_id = params[:obj_id] + obj = obj_class.constantize.find(obj_id) + case obj.class.to_s.to_sym + when :Bid + @project = obj.courses[0] + end + end def assort obj_class = params[:obj_class] obj_id = params[:obj_id] @@ -13,15 +27,39 @@ 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}" #@error = e end + #下载某一学生的作业的所有文件 + def download_user_homework + homework = HomeworkAttach.find params[:homework] + 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+".zip", :type => detect_content_type(zipfile) if zipfile + else + render_403 :message => :notice_not_authorized + end + end + private + def zip_user_bid(bid,user_id) + # Todo: User Access Controll + + homeattaches = bid.homeworks.where("user_id = ?",user_id) + # 得到每一个人所有文件打包的zip文件 + # 并将每一个人的zip打包为一个并返回路径 + user_zip_paths = homeattaches.map do |homeattach| + zip_homework_by_user homeattach + end + #zipping "#{Time.now.to_i}_#{bid.name}.zip", user_zip_paths, OUTPUT_FOLDER + user_zip_paths + end + def zip_bid(bid) # Todo: User Access Controll @@ -50,7 +88,8 @@ class ZipdownController < ApplicationController #length = attach.storage_path.length homeworks_attach_path << attach.diskfile#.to_s.slice((length+1)..-1) end - zipping "#{Time.now.to_i}_#{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 7bfe9512..c9dc4fa2 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -39,7 +39,9 @@ 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 @@ -47,6 +49,15 @@ module ApplicationHelper 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) + end + # Display a link if user is authorized # # @param [String] name Anchor text (passed to link_to) @@ -57,6 +68,9 @@ module ApplicationHelper link_to(name, options, html_options, *parameters_for_method_reference) if authorize_for(options[:controller] || params[:controller], options[:action]) end + def link_to_if_authorized_contest(name, options = {}, html_options = nil, *parameters_for_method_reference) + link_to(name, options, html_options, *parameters_for_method_reference) if authorize_for_contest(options[:controller] || params[:controller], options[:action]) + end # Displays a link to user's account page if active def link_to_user(user, canShowRealName = false, options={}) if user.is_a?(User) @@ -170,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? @@ -186,9 +212,8 @@ module ApplicationHelper end def thumbnail_tag(attachment) - imagepath = named_attachment_path(attachment, attachment.filename) - link_to image_tag(imagepath), - imagepath , + link_to image_tag(thumbnail_path(attachment)), + named_attachment_path(attachment, attachment.filename), :title => attachment.filename end @@ -297,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 = '' @@ -414,7 +473,11 @@ module ApplicationHelper def principals_check_box_tags_ex(name, principals) s = '' principals.each do |principal| - s << "\n" + if principal.has_attribute?(:userInfo) + s << "\n" + else + s << "\n" + end end s.html_safe end @@ -1639,9 +1702,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/attachments_helper.rb b/app/helpers/attachments_helper.rb index aa6a5f7f..3e61b2a4 100644 --- a/app/helpers/attachments_helper.rb +++ b/app/helpers/attachments_helper.rb @@ -115,7 +115,7 @@ module AttachmentsHelper s = content_tag('div', attachments_check_box_tags('attachment[attach][]', searched_attach), :id => 'attachments') links = pagination_links_full(@obj_pages, @obj_count, :per_page_links => false) {|text, parameters, options| - link_to text, attachments_autocomplete_path( parameters.merge(:q => params[:q], :format => 'js')), :remote => true } + link_to text, attachments_autocomplete_path( parameters.merge(:project_id=>project.id,:q => params[:q], :format => 'js')), :remote => true } return s + content_tag('div', content_tag('ul', links), :class => 'pagination') @@ -133,6 +133,35 @@ module AttachmentsHelper # return searched_attach.to_json end + # add by nwb + def render_attachments_for_new_course(course, limit=nil) + # 查询条件 + params[:q] ||= "" + filename_condition = params[:q].strip + + attachAll = Attachment.scoped + + # 除去当前课程的所有资源 + nobelong_attach = Attachment.where("!(container_type = '#{course.class}' and container_id = #{course.id})") unless course.blank? + + # 搜索域确定 + domain = course.nil? ? attachAll : nobelong_attach + + # 搜索到的资源 + searched_attach = domain.where("filename LIKE :like ", like:"%#{filename_condition}%").limit(limit).order('created_on desc') + searched_attach = private_filter searched_attach + searched_attach = paginateHelper(searched_attach, 10) + + #testattach = Attachment.public_attachments + + s = content_tag('div', attachments_check_box_tags('attachment[attach][]', searched_attach), :id => 'attachments') + links = pagination_links_full(@obj_pages, @obj_count, :per_page_links => false) {|text, parameters, options| + link_to text, attachments_autocomplete_path( parameters.merge(:course_id=>course.id,:q => params[:q], :format => 'js')), :remote => true } + + return s + content_tag('div', content_tag('ul', links), :class => 'pagination') + + end + def attachments_check_box_tags(name, attachs) s = '' attachs.each do |attach| @@ -144,18 +173,22 @@ module AttachmentsHelper def private_filter resultSet result = resultSet.to_a.dup + # modify by nwb + #添加对课程资源文件的判断 resultSet.map { |res| if(res.container.nil? || (res.container.class.to_s=="Project" && res.container.is_public == false) || - (res.container.has_attribute?(:project) && res.container.project.is_public == false) || + (res.container.has_attribute?(:project) && res.container.project && res.container.project.is_public == false) || (res.container.class.to_s=="HomeworkAttach" && res.container.bid.reward_type == 3) || - false + (res.container.class.to_s=="Course" && res.container.is_public == false) || + (res.container.has_attribute?(:course) && res.container.course && res.container.course.is_public == false) ) result.delete(res) end } result end + include Redmine::Pagination def paginateHelper obj, pre_size=10 @obj_count = obj.count diff --git a/app/helpers/avatar_helper.rb b/app/helpers/avatar_helper.rb index abaa7950..2ebdae0c 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/bids_helper.rb b/app/helpers/bids_helper.rb index 8b03d74c..a5c25ecb 100644 --- a/app/helpers/bids_helper.rb +++ b/app/helpers/bids_helper.rb @@ -155,16 +155,6 @@ module BidsHelper end people.include?(User.current) end - #当前用户是不是指定课程的学生 - def is_cur_course_student? course - people = [] - course.members.each do |member| - if [5,10].include? member.roles.first.id - people << member.user - end - end - people.include?(User.current) - end # def select_option_helper option # tmp = Hash.new diff --git a/app/helpers/boards_helper.rb b/app/helpers/boards_helper.rb index 84b979c4..341de893 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/contestnotifications_helper.rb b/app/helpers/contestnotifications_helper.rb new file mode 100644 index 00000000..ab17149d --- /dev/null +++ b/app/helpers/contestnotifications_helper.rb @@ -0,0 +1,2 @@ +module ContestnotificationsHelper +end diff --git a/app/helpers/contests_helper.rb b/app/helpers/contests_helper.rb index 8206a8ff..184fc7c4 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 959d36cb..80beea16 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,32 @@ 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 + + def proportion_option + type = [] + i = 0 + while i <= 100 + option = [] + option << i.to_s + "%" + option << i + type << option + i = i + 10 + end + type + end + + alias teacherCountOrigin teacherCount def teacherCount project count = teacherCountOrigin project @@ -45,11 +104,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 +156,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 +196,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 +242,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 @@ -122,8 +256,8 @@ module CoursesHelper people end # 截至到2014-03-17 这个是最终的判断课程是否过期的方法 - def course_endTime_timeout? project - end_time_str = Course.find_by_extra(project.try(:identifier)).try(:endup_time) + def course_endTime_timeout? course + end_time_str = course.try(:endup_time) begin cTime = Time.parse(end_time_str.to_s) rescue TypeError,ArgumentError @@ -137,24 +271,121 @@ module CoursesHelper Course.find_by_extra(try(extra)) end #判断制定用户是不是当前课程的老师 - def is_course_teacher user,course - people = [] - course.members.each do |member| - role_id = member.roles.first.id - if TeacherRoles.include? role_id - people << member.user - end - end - people.include?(user) + def is_course_teacher (user,course) + course.members.joins(:member_roles).where("member_roles.role_id IN (:role_id) and members.user_id = #{user.id}", {:role_id => TeacherRoles}).count != 0 + #修改为根据用户是否有发布任务的权限来判断用户是否是课程的老师 + #is_teacher = false + #@membership = user.memberships.all(:conditions => Project.visible_condition(User.current)) + #@membership.each do |membership| + # unless(membership.project.project_type==0) + # if user.allowed_to?({:controller => "projects", :action => "new_homework"}, membership.project, :global => false) + # is_teacher = true + # end + # end + #end + #is_teacher end #当前用户是不是指定课程的学生 - def is_cur_course_student? course - people = [] - course.members.each do |member| - if StudentRoles.include? member.roles.first.id - people << member.user + def is_cur_course_student course + course.members.joins(:member_roles).where("member_roles.role_id IN (:role_id) and members.user_id = #{User.current.id}", {:role_id => StudentRoles}).count != 0 + #修改:能新建占位且不能新建任务的角色判定为学生 + #is_student = false + #@membership = User.current.memberships.all(:conditions => Project.visible_condition(User.current)) + #@membership.each do |membership| + # unless(membership.project.project_type==0) + # if !User.current.allowed_to?({:controller => "projects", :action => "new_homework"}, membership.project, :global => false) && User.current.allowed_to?({:controller => "homework_attach", :action => "new"}, membership.project, :global => false) + # is_student = true + # end + # end + #end + #is_student + end + #获取当前用户在指定作业下提交的作业的集合 + def cur_user_homework_for_bid bid + cur_user_homework = HomeworkAttach.where("user_id = ? and bid_id = ?",User.current,bid.id) + cur_user_homework + end + + #判断当前用户对指定作业是否已经评价过 + def has_evaluation? homework + seem_count = homework.rates(:quality).where("rater_id = ?",User.current).count + seem_count > 0 + end + + #获取指定作业的所有成员 + 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",(homework.bid.proportion * 1.0 / 100) * (teacher_score_for_homework(homework).to_f) + (1 - homework.bid.proportion * 1.0 / 100) * (student_score_for_homework(homework).to_f)) + 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 - people.include?(User.current) + return homework_users end + + def get_courses_by_tag(tag_name) + Course.tagged_with(tag_name).order('updated_at desc') + end + end diff --git a/app/helpers/homework_attach_helper.rb b/app/helpers/homework_attach_helper.rb new file mode 100644 index 00000000..3510dc78 --- /dev/null +++ b/app/helpers/homework_attach_helper.rb @@ -0,0 +1,77 @@ +module HomeworkAttachHelper + #判断是否具有删除的权限 + def attach_delete(project) + if User.current.logged? && (User.current.admin? || (!Member.where('user_id = ? and project_id = ?', User.current.id, project.bid.courses.first.id).first.nil? && (Member.where('user_id = ? and project_id = ?', User.current.id, project.bid.courses.first.id).first.roles&Role.where('id = ? or id = ?', 3, 7)).size >0) || project.user_id == User.current.id) + true + else + false + end + end + #作业添加、编辑界面的tab页 + def homework_settings_tabs f + @f = f + tabs = [{:name => 'info', :partial => 'homework_attach/edit_homework', :label => :label_information_plural}, + {:name => 'members', :partial => 'homework_attach/homework_member', :label => :label_member_plural} + ] + end + + #作业可选成员列表分页 + def render_new_members_for_homework members + #scope = Principal.active.sorted.not_member_of(project).like(params[:q]) + #scope = project.members + #principals = paginateHelper members,10 + #principals = members + #principal_count = members.count + #limit = 10 + #principal_pages = Redmine::Pagination::Paginator.new principal_count, limit, params['page'] #by young + #offset ||= principal_pages.offset + #principals = members[offset, limit] + users = members.map(&:user) + s = content_tag('div', member_check_box_tags_ex('membership[user_ids][]', users), :id => 'principals') + links = pagination_links_full(@obj_pages, @obj_count, :per_page_links => false) {|text, parameters, options| + link_to text, get_homework_member_list_homework_attach_index_path( parameters.merge(:q => params[:q], bid_id: params[:id]||@homework)), :remote => true } + return s + content_tag('div', content_tag('ul', links), :class => 'pagination_new') + end + + #扩展的checkbox生成 + def member_check_box_tags_ex(name, principals) + s = '' + principals.each do |member| + s << "
    " + end + s.html_safe + end + + def paginateHelper obj, pre_size=20 + @obj_count = obj.count + @obj_pages = Redmine::Pagination::Paginator.new @obj_count, pre_size, params['page'] + if obj.kind_of? ActiveRecord::Base or obj.kind_of? ActiveRecord::Relation + obj.limit(@obj_pages.per_page).offset(@obj_pages.offset) + elsif obj.kind_of? Array + obj[@obj_pages.offset, @obj_pages.per_page] + else + logger.error "[ApplicationController] Error : application_controller#paginateHelper ===> unknow category: #{obj.class}" + 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 48052445..cfebb4d3 100644 --- a/app/helpers/journals_helper.rb +++ b/app/helpers/journals_helper.rb @@ -18,7 +18,7 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. module JournalsHelper - def render_notes(issue, journal, options={}) + def render_links(issue, journal, options={}) content = '' editable = User.current.logged? && (User.current.allowed_to?(:edit_issue_notes, issue.project) || (journal.user == User.current && User.current.allowed_to?(:edit_own_issue_notes, issue.project))) destroyable = User.current.logged? && ((journal.user == User.current) || (issue.author_id == User.current.id) || (User.current.admin == 1)) @@ -38,11 +38,39 @@ module JournalsHelper :title => l(:button_delete)) end end - content << content_tag('div', links.join(' ').html_safe, :class => 'contextual', :style => 'margin-top:-25px;') unless links.empty? + content << content_tag('div', links.join(' ').html_safe, :class => 'contextual') unless links.empty? + #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.html_safe + end + + def render_notes (issue, journal, options={}) + content = '' + editable = User.current.logged? && (User.current.allowed_to?(:edit_issue_notes, issue.project) || (journal.user == User.current && User.current.allowed_to?(:edit_own_issue_notes, issue.project))) + destroyable = User.current.logged? && ((journal.user == User.current) || (issue.author_id == User.current.id) || (User.current.admin == 1)) + links = [] + if !journal.notes.blank? + links << link_to(l(:button_quote), + {:controller => 'journals', :action => 'new', :id => issue.id, :journal_id => journal}, + :remote => true, + :method => 'post', + :title => l(:button_quote)) if options[:reply_links] + links << link_to_in_place_notes_editor(l(:button_edit), "journal-#{journal.id}-notes", + { :controller => 'journals', :action => 'edit', :id => journal, :format => 'js' }, + :title => l(:button_edit)) if editable + #Added by young + if destroyable + links << link_to(l(:button_delete), { :controller => 'journals', :action => 'destroy', :id => journal, :format => 'js' }, + :title => l(:button_delete)) + end + end + #content << content_tag('div', links.join(' ').html_safe, :class => 'contextual', :style => 'margin-top:-25px;') unless links.empty? 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 91e05d6a..134b7c00 100644 --- a/app/helpers/members_helper.rb +++ b/app/helpers/members_helper.rb @@ -33,10 +33,28 @@ 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]) - principal_count = scope.count + 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 diff --git a/app/helpers/notificationcomments_helper.rb b/app/helpers/notificationcomments_helper.rb new file mode 100644 index 00000000..2d90bfe3 --- /dev/null +++ b/app/helpers/notificationcomments_helper.rb @@ -0,0 +1,2 @@ +module NotificationcommentsHelper +end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index a42a626d..c859fec2 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -150,7 +150,6 @@ module ProjectsHelper {:name => 'members', :action => :manage_members, :partial => 'projects/settings/members', :label => :label_member_plural} ] tabs.select {|tab| User.current.allowed_to?(tab[:action], @project)} - end #Ended by young @@ -227,6 +226,19 @@ module ProjectsHelper type << option2 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 + # 用来判断用户是否是项目的管理员 # added by william def is_manager?(user_id,project_id) diff --git a/app/helpers/shares_helper.rb b/app/helpers/shares_helper.rb index f2cbc6ab..9e082813 100644 --- a/app/helpers/shares_helper.rb +++ b/app/helpers/shares_helper.rb @@ -4,11 +4,15 @@ def options_from_select_project(user) @option = [] @membership.each do |membership| unless(membership.project.project_type==1) - membership.member_roles.each{|role| - if(role.role_id == 3) + #membership.member_roles.each{|role| + # if(role.role_id == 3) + # @option << membership.project + # end + #} + #拥有编辑项目权限的可操作该项目 + if user.allowed_to?({:controller => "projects", :action => "edit"}, membership.project, :global => false) @option << membership.project - end - } + end end end options_for_select(@option) diff --git a/app/helpers/tags_helper.rb b/app/helpers/tags_helper.rb index 201a582f..8e9e6bbb 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/user_score_helper.rb b/app/helpers/user_score_helper.rb index d9ab8730..3101b823 100644 --- a/app/helpers/user_score_helper.rb +++ b/app/helpers/user_score_helper.rb @@ -228,12 +228,21 @@ module UserScoreHelper isManager = 0 members = Member.where('user_id = ?', user.id) members.each do |m| - roles = m.member_roles - roles.each do |r| - if r.role_id == 3 + #roles = m.member_roles + #roles.each do |r| + # if r.role_id == 3 + # isManager = 1 + # end + #end + @membership = m.memberships.all(:conditions => Project.visible_condition(User.current)) + @membership.each do |membership| + #拥有编辑项目权限的可操作该项目 + if m.allowed_to?({:controller => "projects", :action => "edit"}, membership.project, :global => false) isManager = 1 end end + + end level = 0 diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb index 87b495f0..e65fe174 100644 --- a/app/helpers/users_helper.rb +++ b/app/helpers/users_helper.rb @@ -247,4 +247,15 @@ module UsersHelper displayed_flag = %w|index| !displayed_flag.include?(params['action']) end + + #获取指定用户的未过期的课程列表 + def user_courses_list user + result = [] + user.coursememberships.map(&:course).each do |course| + if !course_endTime_timeout?(course) + result << course + end + end + return result + end end diff --git a/app/helpers/watchers_helper.rb b/app/helpers/watchers_helper.rb index 50170ee9..ea72e818 100644 --- a/app/helpers/watchers_helper.rb +++ b/app/helpers/watchers_helper.rb @@ -67,11 +67,38 @@ module WatchersHelper link_to text, url, :remote => true, :method => method, :class => css end + + # add by nwb + # 关注课程 + def new_course_watcher_link(objects, user, options=[]) + return '' unless user && user.logged? + objects = Array.wrap(objects) + + watched = objects.any? {|object| object.watched_by?(user)} + @watch_flag = (objects.first.instance_of?(User) or objects.first.instance_of?(Project) or (objects.first.instance_of?(Contest))) + css = @watch_flag ? ([watcher_css(objects), watched ? 'icon ' : 'icon '].join(' ') << options[0].to_s) : + ([watcher_css(objects), watched ? 'icon icon-fav ' : 'icon icon-fav-off '].join(' ') << options[0].to_s) + + text = @watch_flag ? + (watched ? l(:button_unfollow) : l(:button_follow)) : (watched ? l(:button_unwatch) : l(:button_watch)) + + url = watch_path( + :object_type => objects.first.class.to_s.underscore, + :object_id => (objects.size == 1 ? objects.first.id : objects.map(&:id).sort) + ) + method = watched ? 'delete' : 'post' + + link_to text, url, :remote => true, :method => method, :class => css + end + # added by fq, modify nyan # 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 +109,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 33001021..4ff5a48e 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) && @@ -56,7 +83,8 @@ module WelcomeHelper # # => 前7个项目为新课程,后面三个是参与人数最多的 # # Returns project&courses array - def find_miracle_course(sum=10, max_rate=7, school_id) + # 原来的取课程逻辑 + def find_miracle_course_base(sum=10, max_rate=7, school_id) if User.current.user_extensions.school.nil? and school_id.nil? Project.active.visible.course_entities. @@ -106,6 +134,51 @@ module WelcomeHelper # (c1.take(max)+c2).take(sum) end + #获取课程列表 + # add by nwb + def find_miracle_course(sum=10, max_rate=7, school_id) + if User.current.user_extensions.school.nil? and school_id.nil? + Course.active.visible. + joins(:memberships). + group('members.course_id'). + reorder("courses.created_at DESC, COUNT(members.course_id) DESC").take sum + else + if school_id.nil? + Course.active.visible. + joins(:memberships). + where("#{Course.table_name}.school_id = ?", User.current.user_extensions.school.id). + group('members.course_id'). + reorder("courses.created_at DESC, COUNT(members.course_id) DESC").take sum + else + if school_id == "0" + Course.active.visible. + joins(:memberships). + group('members.course_id'). + reorder("courses.created_at DESC, COUNT(members.course_id) DESC").take sum + else + Course.active.visible. + joins(:memberships). + where("#{Course.table_name}.school_id = ?", school_id). + group('members.course_id'). + reorder("courses.created_at DESC, COUNT(members.course_id) DESC").take sum + end + end + end +# else +# Project.active.visible.course_entities. +# joins(:course_extra). +# joins(:memberships). +# where("#{Course.table_name}.school_id = ?", school_id). +# group('members.project_id'). +# reorder("courses.time DESC, COUNT(members.project_id) DESC").take sum +# end +# max = sum*(max_rate.to_f/10) +# c1 = find_new_course(sum).to_a.dup +# c2 = find_all_hot_course(sum).to_a.dup +# c2 = c2 - c1 +# (c1.take(max)+c2).take(sum) + end + #查找所有学校按每个学校开设课程数量降序排序 #page 分页查询开始条数的编号,从0开始 #limit 分页查询的数量 @@ -131,10 +204,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 @@ -154,11 +228,18 @@ module WelcomeHelper sort_course_by_hot limit end + # modif by nwb def find_all_new_hot_course limit = 9 ,school_id = 0 #sort_project_by_hot_rails 1, 'course_ac_para DESC', limit time_now = Time.new.strftime("%Y"); - Project.visible.joins(:project_status).where("#{Project.table_name}.project_type = ? and #{Project.table_name}.created_on like '%#{time_now}%' and #{Project.table_name}.identifier not in - (select extra from courses where school_id = ?)", 1,school_id).order("course_ac_para DESC").limit(limit).all + if school_id + courses = Course.visible.joins(:course_status).where("#{Course.table_name}.created_at like '%#{time_now}%' and #{Course.table_name}.school_id <> + ?", school_id).order("course_ac_para DESC").limit(limit).all + else + courses = Course.visible.joins(:course_status).where("#{Course.table_name}.created_at like '%#{time_now}%' and #{Course.table_name}.school_id is not NULL + ").order("course_ac_para DESC").limit(limit).all + end + courses end def find_all_hot_bid @@ -207,6 +288,7 @@ module WelcomeHelper def show_grade project grade = 0 begin + #ActiveRecord::Base.connection.execute("CALL sp_project_status_cursor();")#执行存储过程速度慢 grade = project.project_status.grade if project && project.project_status rescue Exception => e logger.error "Logger.Error [WelcomeHelper] ===> #{e}" @@ -237,7 +319,7 @@ module WelcomeHelper content_tag('span', find_all_event_type(event)) << ': '.html_safe << link_to(truncate(event.event_title, length: 30, omission:'...'), event.event_url) << - link_to((' ['.html_safe+l(:label_downloads_list).to_s << ']'), project_files_path(event.container), :class => "attachments_list_color") + link_to((' ['.html_safe+l(:label_downloads_list).to_s << ']'), project_files_path(event.container.project), :class => "attachments_list_color") else str << content_tag("span", "更新了") << content_tag("span", find_all_event_type(event)) << @@ -305,7 +387,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| @@ -319,9 +401,10 @@ module WelcomeHelper "show_documents" => true, "show_messages" => true, "show_news" => true, - "show_bids" => true + "show_bids" => true, + "show_contest" => true } - activity.scope_select{|t| ['changesets', 'documents', 'memos', 'messages', 'journals_for_messages', 'bids', 'news'].include?(t) ? nil : 'You may think you know what the following code does, may be. but why don"t you close this file and go play with something else, Now?' } + activity.scope_select{|t| ['changesets', 'documents', 'memos', 'messages', 'journals_for_messages', 'bids', 'news', 'contestnotification'].include?(t) ? nil : 'You may think you know what the following code does, may be. but why don"t you close this file and go play with something else, Now?' } activity.events_welcome(nil, nil, {:limit => limit, :types => 'welcome'}) end diff --git a/app/models/attachment.rb b/app/models/attachment.rb index aff63439..116e2de9 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}.*", @@ -56,8 +65,109 @@ class Attachment < ActiveRecord::Base @@thumbnails_storage_path = File.join(Rails.root, "tmp", "thumbnails") before_save :files_to_final_location + before_save :be_user_score # user_score after_destroy :delete_from_disk + # add by nwb + # 获取所有可公开的资源文件列表 + scope :public_attachments, lambda { + #joins(Project.table_name).where("container_type = 'Project' and ") + joins("LEFT JOIN #{Project.table_name} ON #{Attachment.table_name}.container_type='Project' AND #{Project.table_name}.id = #{Attachment.table_name}.container_id and #{Project.table_name}.is_public=1 " + + " LEFT JOIN #{Document.table_name} ON #{Attachment.table_name}.container_type='Project' AND #{Document.table_name}.project_id in "+self.public_project_id + + " LEFT JOIN #{Issue.table_name} ON #{Attachment.table_name}.container_type='Project' AND #{Issue.table_name}.project_id in "+self.public_project_id + + " LEFT JOIN #{Version.table_name} ON #{Attachment.table_name}.container_type='Project' AND #{Version.table_name}.project_id in "+self.public_project_id + + " LEFT JOIN #{WikiPage.table_name} ON #{Attachment.table_name}.container_type='WikiPage' AND #{WikiPage.table_name}.parent_id in "+self.public_wiki_id + + " LEFT JOIN #{Message.table_name} ON #{Attachment.table_name}.container_type='Message' AND #{Message.table_name}.parent_id in "+self.public_board_id + + " LEFT JOIN #{Course.table_name} ON #{Attachment.table_name}.container_type='Course' AND #{Course.table_name}.is_public=1 " + + " LEFT JOIN #{News.table_name} ON #{Attachment.table_name}.container_type='News' AND (#{News.table_name}.project_id in "+self.public_project_id + " OR #{News.table_name}.course_id in " + self.public_course_id + ")" + + " LEFT JOIN #{HomeworkAttach.table_name} ON #{Attachment.table_name}.container_type='HomeworkAttach' AND #{HomeworkAttach.table_name}.bid_id in "+self.public_bid_id) + } + + # add by nwb + # 公开的项目id列表 + def self.public_project_id + idlist = "(" + projects=Project.all_public + count = projects.count + for i in 0...count + project = projects[i] + idlist+="'" + project.id.to_s + "'" + if i != count-1 + idlist+="," + end + end + idlist += ")" + idlist + end + + # add by nwb + # 公开的课程id列表 + def self.public_course_id + idlist = "(" + courses=Course.all_public + count = courses.count + for i in 0...count + course = courses[i] + idlist+="'" + course.id.to_s + "'" + if i != count-1 + idlist = idlist + "," + end + end + idlist += ")" + idlist + end + + # add by nwb + # 公开的wiki id列表 + def self.public_wiki_id + idlist = "(" + wikis=Wiki.where("project_id in " + public_project_id) + count = wikis.count + for i in 0...count + wiki = wikis[i] + idlist+="'" + wiki.id.to_s + "'" + if i != count-1 + idlist = idlist + "," + end + end + idlist += ")" + idlist + end + + # add by nwb + # 公开的board id列表 + def self.public_board_id + idlist = "(" + boards=Board.where("project_id in " + public_project_id + " or course_id in " + public_course_id) + count = boards.count + for i in 0...count + board = boards[i] + idlist+="'" + board.id.to_s + "'" + if i != count-1 + idlist = idlist + "," + end + end + idlist += ")" + idlist + end + + # add by nwb + # 公开的bid id列表 + def self.public_bid_id + idlist = "(" + bids=Bid.where("reward_type=3") + count = bids.count + for i in 0...count + bid = bids[i] + idlist+="'" + bid.id.to_s + "'" + if i != count-1 + idlist = idlist + "," + end + end + idlist += ")" + idlist + end + # Returns an unsaved copy of the attachment def copy(attributes=nil) copy = self.class.new @@ -119,7 +229,7 @@ class Attachment < ActiveRecord::Base nil end - def filename=(arg) + def filename=(arg) write_attribute :filename, sanitize_filename(arg.to_s) filename end @@ -169,6 +279,7 @@ class Attachment < ActiveRecord::Base File.join(self.class.storage_path, disk_directory.to_s, disk_filename.to_s) end + #标题 def title title = filename.to_s if description.present? @@ -185,6 +296,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) @@ -361,4 +476,17 @@ class Attachment < ActiveRecord::Base end "#{timestamp}_#{ascii}" end + + + # update user score + def be_user_score + if self.container_id_changed? + type = self.container_type + types = %w|Document News Version Project Issue Message WikiPage| + if types.include?(type) + UserScore.project(:push_file, User.current,self, { attachment_id: self.id }) + end + end + end + end diff --git a/app/models/bid.rb b/app/models/bid.rb index e58e640a..f65d71fa 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 cb81e0a5..b51790e1 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 e3e7ac70..a56dee69 100644 --- a/app/models/changeset.rb +++ b/app/models/changeset.rb @@ -18,6 +18,9 @@ class Changeset < ActiveRecord::Base belongs_to :repository belongs_to :user + + #after_save :be_user_score # user_score + has_many :filechanges, :class_name => 'Change', :dependent => :delete_all # fq has_many :acts, :class_name => 'Activity', :as => :act, :dependent => :destroy @@ -60,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 @@ -95,7 +98,9 @@ class Changeset < ActiveRecord::Base end def project - repository.project + unless repository.nil? + repository.project + end end def author @@ -292,4 +297,14 @@ class Changeset < ActiveRecord::Base def self.to_utf8(str, encoding) Redmine::CodesetUtil.to_utf8(str, encoding) end + + private + + # update user score + def be_user_score + UserScore.project(:push_code, self.user,self, { changeset_id: self.id }) + #更新用户等级 + UserLevels.update_user_level(self.user) + end + end diff --git a/app/models/contest.rb b/app/models/contest.rb index 9a326865..e1706b16 100644 --- a/app/models/contest.rb +++ b/app/models/contest.rb @@ -13,6 +13,7 @@ class Contest < ActiveRecord::Base has_many :join_in_competitions, foreign_key: 'competition_id', :dependent => :destroy has_many :join_in_contests, class_name: 'JoinInCompetition', foreign_key: 'competition_id', :dependent => :destroy has_many :praise_tread, as: :praise_tread_object, dependent: :destroy + has_many :contestnotifications, :dependent => :destroy, :include => :author @@ -23,8 +24,9 @@ class Contest < ActiveRecord::Base validates_length_of :name, :maximum => NAME_LENGTH_LIMIT validates_length_of :description, :maximum => DESCRIPTION_LENGTH_LIMIT - validates_presence_of :author_id, :name, :deadline - validates_format_of :deadline, :with => /^[\d]{4}[-][\d]{1,2}[-][\d]{1,2}$/ + validates_presence_of :author_id, :name, :budget + #validates_format_of :deadline, :with => /^[\d]{4}[-][\d]{1,2}[-][\d]{1,2}$/ + validates_format_of :deadline, :with =>/^[1-9][0-9]{3}\-0?[1-9]|1[12]\-0?[1-9]|[12]\d|3[01]$/ # validates_format_of :budget, :with => /^(\d+)$|^(\d+).([0-9]{2})|^(\d+).([0-9]{1})$/ validate :validate_user after_create :act_as_activity @@ -93,6 +95,17 @@ class Contest < ActiveRecord::Base end end + # Closes open and locked project versions that are completed + def close_completed_versions_contest + Version.transaction do + versions.where(:status => %w(open locked)).all.each do |version| + if version.completed? + version.update_attribute(:status, 'closed') + end + end + end + end + def set_commit(commit) self.update_attribute(:commit, commit) end diff --git a/app/models/contestnotification.rb b/app/models/contestnotification.rb new file mode 100644 index 00000000..0bda4954 --- /dev/null +++ b/app/models/contestnotification.rb @@ -0,0 +1,63 @@ +class Contestnotification < ActiveRecord::Base + #attr_accessible :author_id, :notificationcomments_count, :contest_id, :description, :summary, :title + + include Redmine::SafeAttributes + #Contestnotification::Notificationcomment + belongs_to :contest + belongs_to :author, :class_name => 'User', :foreign_key => 'author_id' + has_many :notificationcomments, as: :notificationcommented, :dependent => :delete_all, :order => "created_at" + # fq + has_many :acts, :class_name => 'Activity', :as => :act, :dependent => :destroy + + validates_presence_of :title, :description + validates_length_of :title, :maximum => 60 + validates_length_of :summary, :maximum => 255 + + acts_as_attachable :delete_permission => :manage_contestnotifications + acts_as_searchable :columns => ['title', 'summary', "#{table_name}.description"], :include => :contest + acts_as_event :url => Proc.new {|o| {:controller => 'contestnotifications', :action => 'show', :id => o.id}} + acts_as_activity_provider :find_options => {:include => [:contest, :author]}, + :author_key => :author_id + acts_as_watchable + + after_create :add_author_as_watcher + + after_create :act_as_activity + + + scope :visible, lambda {|*args| + nil + #includes(:contest).where(Contest.allowed_to_condition(args.shift || User.current, :view_contestnotifications, *args)) + } + + safe_attributes 'title', 'summary', 'description' + + def visible?(user=User.current) + !user.nil? && user.allowed_to?(:view_contestnotifications, contest) + end + + # Returns true if the news can be commented by user + def notificationcommentable?(user=User.current) + user.allowed_to?(:notificationcomment_contestnotifications, contest) + end + + def recipients + #contest.users.select {|user| user.notify_about?(self)}.map(&:mail) + end + + # returns latest news for contests visible by user + def self.latest(user = User.current, count = 5) + visible(user).includes([:author, :contest]).order("#{Contestnotification.table_name}.created_at DESC").limit(count).all + end + + private + + def add_author_as_watcher + #Watcher.create(:watchable => self, :user => author) + end + ## fq + def act_as_activity + self.acts << Activity.new(:user_id => self.author_id) + end + +end diff --git a/app/models/course.rb b/app/models/course.rb index de383a1f..5034ab0d 100644 --- a/app/models/course.rb +++ b/app/models/course.rb @@ -1,13 +1,47 @@ 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 + has_one :course_status, :class_name => "CourseStatus", :dependent => :destroy + + 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]+$/ + + before_save :self_validate + after_save :create_board_sync + before_destroy :delete_all_members + safe_attributes 'extra', 'time', 'name', @@ -17,12 +51,159 @@ class Course < ActiveRecord::Base 'tea_id', 'password', 'term', - 'password' + 'is_public', + 'description', + 'class_period' - #自定义验证 - def validate - if !class_period.match([0-9]) - errors.add_to_base("class period can only digital") + 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(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 self_validate + + 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 @@ -47,4 +228,54 @@ 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 + + #项目与课程分离后,很多课程的名称等信息为空,这些数据信息存储在项目表中!!就是数据兼容的问题 + def name + read_attribute('name') || Project.find_by_identifier(self.extra).try(:name) + end end diff --git a/app/models/course_infos.rb b/app/models/course_infos.rb new file mode 100644 index 00000000..6478b383 --- /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 00000000..b36661eb --- /dev/null +++ b/app/models/course_status.rb @@ -0,0 +1,7 @@ +class CourseStatus < ActiveRecord::Base + attr_accessible :changesets_count, :course_ac_para, :course_id, :grade, :watchers_count + + belongs_to :course + validates_presence_of :course_id + validates_uniqueness_of :course_id +end diff --git a/app/models/document.rb b/app/models/document.rb index 0c2ce173..7c273068 100644 --- a/app/models/document.rb +++ b/app/models/document.rb @@ -18,7 +18,12 @@ class Document < ActiveRecord::Base include Redmine::SafeAttributes belongs_to :project + belongs_to :user belongs_to :category, :class_name => "DocumentCategory", :foreign_key => "category_id" + + after_create :be_user_score # user_score + + acts_as_attachable :delete_permission => :delete_documents acts_as_searchable :columns => ['title', "#{table_name}.description"], :include => :project @@ -54,4 +59,9 @@ class Document < ActiveRecord::Base end @updated_on end + + # update user score + def be_user_score + UserScore.project(:push_document, self.user,self,{ document_id: self.id }) + end end diff --git a/app/models/forum.rb b/app/models/forum.rb index e6b16df3..cd9c210d 100644 --- a/app/models/forum.rb +++ b/app/models/forum.rb @@ -9,7 +9,7 @@ class Forum < ActiveRecord::Base 'memo_count', 'last_memo_id', 'creator_id' - validates_presence_of :name, :creator_id + validates_presence_of :name, :creator_id, :description validates_length_of :name, maximum: 50 validates_length_of :description, maximum: 255 validates :name, :uniqueness => true diff --git a/app/models/homework_attach.rb b/app/models/homework_attach.rb index ad59d107..99d540bd 100644 --- a/app/models/homework_attach.rb +++ b/app/models/homework_attach.rb @@ -7,14 +7,16 @@ class HomeworkAttach < ActiveRecord::Base belongs_to :bid has_many :journals_for_messages, :as => :jour, :dependent => :destroy 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" acts_as_attachable - def addjours user_id,message,status = 0,is_comprehensive_evaluation = 0 - jfm = self.journals_for_messages.build(:user_id => user_id,:notes =>message,:status => status,:is_comprehensive_evaluation => is_comprehensive_evaluation) + def addjours user_id,message,status = 0,is_comprehensive_evaluation = 0,reply_id = 0 + jfm = self.journals_for_messages.build(:user_id => user_id,:notes =>message,:status => status,:is_comprehensive_evaluation => is_comprehensive_evaluation,:reply_id => reply_id) jfm.save jfm end @@ -29,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 7a440449..59fd7ba1 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/homework_user.rb b/app/models/homework_user.rb index 0adef62c..df75ef82 100644 --- a/app/models/homework_user.rb +++ b/app/models/homework_user.rb @@ -1,6 +1,6 @@ class HomeworkUser < ActiveRecord::Base attr_accessible :homework_attach_id, :user_id - belongs_to :homework_attach + belongs_to :homework_attach, :foreign_key => :homework_attach_id belongs_to :user end diff --git a/app/models/issue.rb b/app/models/issue.rb index 7e899eaf..550e0dc5 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -76,7 +76,9 @@ class Issue < ActiveRecord::Base attr_reader :current_journal # fq - after_create :act_as_activity + after_create :act_as_activity,:be_user_score_new_issue + after_update :be_user_score + # after_create :be_user_score # end delegate :notes, :notes=, :private_notes, :private_notes=, :to => :current_journal, :allow_nil => true @@ -988,13 +990,9 @@ class Issue < ActiveRecord::Base end def to_s - "#{tracker} ##{id}: #{subject}" + "#{tracker} ##{project_index}: #{subject}" end - # 缺陷在项目中的序号 - def inProjectIndex - (self.project.issues.index(self).to_i + 1).to_s - end # Returns a string of css classes that apply to the issue def css_classes @@ -1158,9 +1156,22 @@ class Issue < ActiveRecord::Base "" << self.project.name.to_s << "#" << project_index end - + def project_index - (self.project.issues.index(self).to_i + 1).to_s + if self.project.issues.include?(self) + (self.project.issues.index(self).to_i + 1).to_s + else + issue_index = 1 + self.project.issues.each do |issue| + if self.id == nil + issue_index = self.project.issues.count +1 + break + elsif self.id > issue.id + issue_index = issue_index+1 + end + end + issue_index.to_s + end end private @@ -1484,4 +1495,22 @@ class Issue < ActiveRecord::Base and #{visible_condition(User.current, :project => project)} group by s.id, s.is_closed, j.id") end + + # update user score + def be_user_score + #缺陷完成度更新 + if self.done_ratio_changed? + UserScore.project(:update_issue_ratio, User.current,self,{ issue_id: self.id }) + end + #缺陷状态更改 + 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 0997640d..2e9363dd 100644 --- a/app/models/journal.rb +++ b/app/models/journal.rb @@ -29,7 +29,7 @@ class Journal < ActiveRecord::Base # end attr_accessor :indice - acts_as_event :title =>Proc.new {|o| status = ((s = o.new_status) ? " (#{s})" : nil); "#{o.issue.tracker} ##{o.issue.inProjectIndex}#{status}: #{o.issue.subject}" }, + acts_as_event :title =>Proc.new {|o| status = ((s = o.new_status) ? " (#{s})" : nil); "#{o.issue.tracker} ##{o.issue.project_index}#{status}: #{o.issue.subject}" }, :description =>:notes, :author => :user, :group => :issue, @@ -45,9 +45,12 @@ 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_destroy :down_user_score + scope :visible, lambda {|*args| user = args.shift || User.current @@ -151,4 +154,21 @@ class Journal < ActiveRecord::Base self.acts << Activity.new(:user_id => self.user_id) end # end + + # 更新用户分数 -by zjc + def be_user_score + #新建了缺陷留言且留言不为空,不为空白 + if !self.notes.nil? && self.notes.gsub(' ','') != '' + #协同得分加分 + UserScore.joint(:post_issue_message, User.current,self.issue.author,self, { message_id: self.id }) + end + end + # 减少用户分数 -by zjc + def down_user_score + #删除有效缺陷留言 + if !self.notes.nil? && self.notes.gsub(' ','') != '' + #协同得分减分 + 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 7356b737..9551ff28 100644 --- a/app/models/journals_for_message.rb +++ b/app/models/journals_for_message.rb @@ -15,9 +15,12 @@ class JournalsForMessage < ActiveRecord::Base "m_reply_id" # 回复某留言的留言id(a留言回复了b留言,这是b留言的id) acts_as_tree :foreign_key => 'm_parent_id', :counter_cache => :m_reply_count, :order => "#{JournalsForMessage.table_name}.created_on ASC" - belongs_to :project, - :foreign_key => 'jour_id', + 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,18 +33,30 @@ 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_destroy :down_user_score # default_scope { where('m_parent_id IS NULL') } @@ -87,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 @@ -99,4 +116,30 @@ class JournalsForMessage < ActiveRecord::Base count = find_all_by_m_parent_id(journals_for_messages.m_parent_id).count #(SELECT COUNT(*) FROM #{JournalsForMessage.table_name} WHERE m_parent_id = #{jfm_id} ) update_all("m_reply_count = #{count.to_i}", ["id = ?", journals_for_messages.m_parent_id]) end + + #如果是在项目中留言则返回该项目否则返回nil - zjc + def project + if self.jour_type == 'Project' + Project.find(self.jour_id) + else + nil + end + end + + # 更新用户分数 -by zjc + def be_user_score + #新建了留言回复 + if self.reply_id != 0 + #协同得分加分 + UserScore.joint(:reply_message, User.current,User.find(self.reply_id),self, { journals_for_messages_id: self.id }) + end + end + # 更新用户分数 -by zjc + def down_user_score + #删除了留言回复 + if self.reply_id != 0 + #协同得分减分 + UserScore.joint(:reply_message_delete, User.current,User.find(self.reply_id), { journals_for_messages_id: self.id }) + end + end end diff --git a/app/models/mailer.rb b/app/models/mailer.rb index e0ad5429..ef4996ea 100644 --- a/app/models/mailer.rb +++ b/app/models/mailer.rb @@ -46,26 +46,43 @@ class Mailer < ActionMailer::Base when :Project return -1 if journals_for_message.jour.project_type == Project::ProjectType_project project_feedback_url(journals_for_message.jour, anchor: "word_li_#{journals_for_message.id}") + when :Course + course_feedback_url(journals_for_message.jour, anchor: "word_li_#{journals_for_message.id}") when :Contest show_contest_contest_url(journals_for_message.jour, anchor: "word_li_#{journals_for_message.id}") when :User user_newfeedback_user_url(journals_for_message.jour, anchor: "word_li_#{journals_for_message.id}") else - logger.error "[Builds a Mail::Message ERROR] journalsForMessage's jour is unkown type, journalsForMessage.id = #{journals_for_message.id}" + Rails.logger.error "[Builds a Mail::Message ERROR] journalsForMessage's jour is unkown type, journalsForMessage.id = #{journals_for_message.id}" return -1 end - #如果是直接留言并且留言对象是Project并且Project类型是课程 - if !journals_for_message.at_user && journals_for_message.jour.class.to_s.to_sym == :Project && journals_for_message.jour.project_type == 1 - project = journals_for_message.jour + # modify by nwb + #如果是直接留言并且留言对象是课程 + if !journals_for_message.at_user && journals_for_message.jour.class.to_s.to_sym == :Course + course = journals_for_message.jour + @author = journals_for_message.user #课程的教师 @teachers = searchTeacherAndAssistant journals_for_message.jour #收件人邮箱 @recipients ||= [] @teachers.each do |teacher| - @recipients << teacher.user.mail + if teacher.user.notify_about? journals_for_message + @recipients << teacher.user.mail + end + end mail :to => @recipients, :subject => "#{l(:label_your_course)}#{journals_for_message.jour.name}#{l(:label_have_message)} " + elsif journals_for_message.jour.class.to_s.to_sym == :Bid + if !journals_for_message.jour.author.notify_about? journals_for_message + return -1 + end + mail :to => journals_for_message.jour.author.mail, :subject => @title + 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 @@ -79,8 +96,9 @@ class Mailer < ActionMailer::Base # issue_add(issue) => Mail::Message object # Mailer.issue_add(issue).deliver => sends an email to issue recipients def issue_add(issue) + issue_id = issue.project_index redmine_headers 'Project' => issue.project.identifier, - 'Issue-Id' => (issue.project.issues.index(issue).to_i + 1).to_s, + 'Issue-Id' => issue_id, 'Issue-Author' => issue.author.login redmine_headers 'Issue-Assignee' => issue.assigned_to.login if issue.assigned_to message_id issue @@ -91,7 +109,7 @@ class Mailer < ActionMailer::Base cc = issue.watcher_recipients - recipients mail :to => recipients, :cc => cc, - :subject => "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] (#{issue.status.name}) #{issue.subject}" + :subject => "[#{issue.project.name} - #{issue.tracker.name} ##{issue_id}] (#{issue.status.name}) #{issue.subject}" end # Builds a Mail::Message object used to email recipients of the edited issue. @@ -101,8 +119,9 @@ class Mailer < ActionMailer::Base # Mailer.issue_edit(journal).deliver => sends an email to issue recipients def issue_edit(journal) issue = journal.journalized.reload + issue_id = issue.project_index redmine_headers 'Project' => issue.project.identifier, - 'Issue-Id' => (issue.project.issues.index(issue).to_i + 1).to_s, + 'Issue-Id' => issue_id.to_s, 'Issue-Author' => issue.author.login redmine_headers 'Issue-Assignee' => issue.assigned_to.login if issue.assigned_to message_id journal @@ -111,7 +130,7 @@ class Mailer < ActionMailer::Base recipients = journal.recipients # Watchers in cc cc = journal.watcher_recipients - recipients - s = "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] " + s = "[#{issue.project.name} - #{issue.tracker.name} ##{issue_id}] " s << "(#{issue.status.name}) " if journal.new_value_for('status_id') s << issue.subject @issue = issue @@ -440,10 +459,7 @@ class Mailer < ActionMailer::Base headers[:to].delete(@author.mail) if headers[:to].is_a?(Array) headers[:cc].delete(@author.mail) if headers[:cc].is_a?(Array) end - if !User.current.nil? - #不给本人发邮件 - headers[:to].delete(User.current.mail) if headers[:to].is_a?(Array) - end + if @author && @author.logged? redmine_headers 'Sender' => @author.login end diff --git a/app/models/member.rb b/app/models/member.rb index de4d6768..46aefbd0 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 29ad6563..67122a63 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 a0581d94..feb10dec 100644 --- a/app/models/memo.rb +++ b/app/models/memo.rb @@ -3,15 +3,16 @@ class Memo < ActiveRecord::Base belongs_to :forum belongs_to :author, :class_name => "User", :foreign_key => 'author_id' - validates_presence_of :author_id, :forum_id, :subject + validates_presence_of :author_id, :forum_id, :subject,:content # 若是主题帖,则内容可以是空 - validates :content, presence: true, if: Proc.new{|o| !o.parent_id.nil? } + #validates :content, presence: true, if: Proc.new{|o| !o.parent_id.nil? } validates_length_of :subject, maximum: 50 validates_length_of :content, maximum: 3072 validate :cannot_reply_to_locked_topic, :on => :create 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 # scope :visible, lambda { |*args| # includes(:forum => ).where() # } @@ -140,5 +141,17 @@ class Memo < ActiveRecord::Base @forum.topic_count = 0 if @forum.topic_count.to_int < 0 end @forum.save - end + end + + #更新用户分数 -by zjc + def be_user_score + #新建memo且无parent的为发帖 + if self.parent_id.nil? + UserScore.joint(:post_message, User.current,nil,self ,{ memo_id: self.id }) + #新建memo且有parent的为回帖 + elsif !self.parent_id.nil? + UserScore.joint(:reply_posting, User.current,self.parent.author,self, { memo_id: self.id }) + end + end + end diff --git a/app/models/message.rb b/app/models/message.rb index 2421a7d4..faf7e5bd 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,13 +60,20 @@ class Message < ActiveRecord::Base after_destroy :reset_counters! # fq - after_create :act_as_activity + after_create :act_as_activity,:be_user_score + #before_save :be_user_score + #before_destroy :down_user_score # end scope :visible, lambda {|*args| 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| @@ -67,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 @@ -102,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 @@ -121,4 +143,25 @@ class Message < ActiveRecord::Base self.acts << Activity.new(:user_id => self.author_id) end # end + + #更新用户分数 -by zjc + def be_user_score + #新建message且无parent的为发帖 + if self.parent_id.nil? + UserScore.joint(:post_message, User.current,nil,self, { message_id: self.id }) + #新建message且有parent的为回帖 + elsif !self.parent_id.nil? + UserScore.joint(:reply_posting, User.current,self.parent.author,self, { message_id: self.id }) + end + end + #减少用户分数 + def down_user_score + #删除发帖 + if self.parent_id.nil? + UserScore.joint(:delete_message, User.current,nil, { message_id: self.id }) + #删除留言 + else + UserScore.joint(:reply_deleting, User.current,self.parent.author, { message_id: self.id }) + end + end end diff --git a/app/models/news.rb b/app/models/news.rb index f2dba2f8..9a0f8b75 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/notificationcomment.rb b/app/models/notificationcomment.rb new file mode 100644 index 00000000..9cc658f2 --- /dev/null +++ b/app/models/notificationcomment.rb @@ -0,0 +1,11 @@ +class Notificationcomment < ActiveRecord::Base + attr_accessible :author_id, :notificationcommented_id, :notificationcommented_type, :notificationcomments + + include Redmine::SafeAttributes + belongs_to :notificationcommented, :polymorphic => true#, :counter_cache => true + belongs_to :author, :class_name => 'User', :foreign_key => 'author_id' + + validates_presence_of :notificationcommented, :author, :notificationcomments + + # safe_attributes 'notificationcomments' +end diff --git a/app/models/praise_tread.rb b/app/models/praise_tread.rb index c27e1fc9..98253d83 100644 --- a/app/models/praise_tread.rb +++ b/app/models/praise_tread.rb @@ -2,5 +2,53 @@ 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 - + after_create :be_user_score + + def self.find_object_by_type_and_id(type,id) + @obj = nil + case type + when 'User' + @obj = User.find_by_id(id) + when 'Issue' + @obj = Issue.find_by_id(id) + when 'Project' + @obj = Project.find_by_id(id) + when 'Bid' + @obj = Bid.find_by_id(id) + when 'Contest' + @obj = Contest.find_by_id(id) + when 'Memo' + @obj = Memo.find_by_id(id) + when 'Message' + @obj = Message.find_by_id(id) + end + 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.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,self, { praise_tread_id: self.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,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 15cebdf5..02448063 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 b8e11d99..5efaf10a 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,9 +39,9 @@ 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 :issues, :dependent => :destroy, :include => [:status, :tracker] , :order => "id ASC" has_many :issue_changes, :through => :issues, :source => :journals has_many :versions, :dependent => :destroy, :order => "#{Version.table_name}.effective_date DESC, #{Version.table_name}.name DESC" has_many :time_entries, :dependent => :delete_all @@ -112,6 +113,7 @@ class Project < ActiveRecord::Base validates_presence_of :name, :identifier validates_uniqueness_of :identifier + validates_uniqueness_of :name validates_associated :repository, :wiki # validates_length_of :description, :maximum => 255 validates_length_of :name, :maximum => 255 @@ -1129,17 +1131,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 c6edab81..d22bf7cf 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/repository.rb b/app/models/repository.rb index bcd3366c..57a81827 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -38,11 +38,11 @@ class Repository < ActiveRecord::Base validates_length_of :password, :maximum => 255, :allow_nil => true validates_length_of :identifier, :maximum => IDENTIFIER_MAX_LENGTH, :allow_blank => true - validates_presence_of :identifier, :unless => Proc.new { |r| r.is_default? || r.set_as_default? } + validates_presence_of :identifier#, :unless => Proc.new { |r| r.is_default? || r.set_as_default? } validates_uniqueness_of :identifier, :scope => :project_id, :allow_blank => true validates_exclusion_of :identifier, :in => %w(show entry raw changes annotate diff show stats graph) # donwcase letters, digits, dashes, underscores but not digits only - validates_format_of :identifier, :with => /\A(?!\d+$)[a-z0-9\-_]*\z/, :allow_blank => true + validates_format_of :identifier, :with => /^[a-zA-Z0-9_\-]+$/, :allow_blank => true # Checks if the SCM is enabled when creating a repository validate :repo_create_validation, :on => :create diff --git a/app/models/role.rb b/app/models/role.rb index 2902325d..cba219d0 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 597d74da..6958cfe7 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 edf70387..257681cb 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -73,7 +73,8 @@ class User < Principal ['none', :label_user_mail_option_none] ] - belongs_to :homework_user + has_many :homework_users + has_many :homework_attaches, :through => :homework_users has_and_belongs_to_many :groups, :after_add => Proc.new {|user, group| group.user_added(user)}, :after_remove => Proc.new {|user, group| group.user_removed(user)} @@ -86,8 +87,6 @@ class User < Principal ## added by xianbo for delete has_many :biding_projects, :dependent => :destroy has_many :contesting_projects, :dependent => :destroy - has_many :contesting_softapplications, :dependent => :destroy - has_many :projecting_softapplications, :dependent => :destroy belongs_to :softapplication, :foreign_key => 'id', :dependent => :destroy ##ended by xianbo @@ -102,18 +101,21 @@ 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'" #### # added by bai has_many :join_in_contests, :dependent => :destroy has_many :news, :foreign_key => 'author_id' + has_many :contestnotification, :foreign_key => 'author_id' has_many :comments, :foreign_key => 'author_id' + has_many :notificationcomments, :foreign_key => 'author_id' has_many :wiki_contents, :foreign_key => 'author_id' has_many :journals has_many :messages, :foreign_key => 'author_id' has_one :user_score, :dependent => :destroy + has_many :documents # 项目中关联的文档再次与人关联 # end ######added by nie @@ -122,6 +124,10 @@ class User < Principal ##### has_many :shares ,:dependent => :destroy + # add by zjc + has_one :level, :class_name => 'UserLevels', :dependent => :destroy + has_many :memos , :foreign_key => 'author_id' + ##### scope :logged, lambda { where("#{User.table_name}.status <> #{STATUS_ANONYMOUS}") } scope :status, lambda {|arg| where(arg.blank? ? nil : {:status => arg.to_i}) } scope :visible, lambda {|*args| @@ -139,6 +145,7 @@ class User < Principal has_one :user_extensions,:dependent => :destroy ## end + # default_scope -> { includes(:user_extensions, :user_score) } scope :teacher, -> { joins(:user_extensions).where('user_extensions.identity = ?', UserExtensions::TEACHER) } @@ -157,7 +164,7 @@ class User < Principal # Prevents unauthorized assignments attr_protected :login, :admin, :password, :password_confirmation, :hashed_password - LOGIN_LENGTH_LIMIT = 60 + LOGIN_LENGTH_LIMIT = 25 MAIL_LENGTH_LIMIT = 60 validates_presence_of :login, :firstname, :mail, :if => Proc.new { |user| !user.is_a?(AnonymousUser) } @@ -195,10 +202,71 @@ class User < Principal where(nil) else pattern = "%#{arg.to_s.strip.downcase}%" - where(" LOWER(concat(lastname, firstname)) LIKE :p ", :p => pattern) + #where(" LOWER(concat(lastname, firstname)) LIKE :p ", :p => pattern) + where(" LOWER(login) LIKE :p ", :p => pattern) end } + + # ====================================================================== + # 集中处理 User 扩展表为空的问题 + # 合并 user_score 属性 + validate :valid_user_extensions + after_save :save_user_extensions + + def extensions + self.user_extensions ||= UserExtensions.new + end + + def user_score_attr + self.user_score ||= UserScore.new + end + + alias_method :ori_respond_to?, :respond_to? + def respond_to?(m, include_private = false) + flag = false + flag = ori_respond_to? m.to_sym unless flag + flag = UserExtensions.new.respond_to? m.to_sym unless flag + flag = UserScore.new.respond_to? m.to_sym unless flag + + flag + end + + def method_missing m, *args, &block + if extensions.respond_to? m.to_sym + self.class.send(:define_method, "_meta_#{m}".to_sym) do |*args, &block| + self.extensions.__send__ m.to_sym, *args + end + __send__ "_meta_#{m}".to_sym, *args, &block + + elsif user_score_attr.respond_to? m.to_sym + self.class.send(:define_method, "_meta_#{m}".to_sym) do |*args, &block| + self.user_score_attr.__send__ m.to_sym, *args + end + __send__ "_meta_#{m}".to_sym, *args, &block + + else + super + end + end + + def valid_user_extensions + if !self.extensions.valid? + self.extensions.errors.messages.each do |key, values| + values.each do |value| + self.errors.add key, value + end + end + end + end + + def save_user_extensions + self.extensions.save + self.user_score_attr.save + end + # 集中处理 User 扩展表为空的问题 < end + # ====================================================================== + #选择项目成员时显示的用户信息文字 def userInfo info=self.nickname + ' (' + self.realname + ')'; @@ -276,6 +344,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 @@ -459,6 +528,9 @@ class User < Principal self.pref[:comments_sorting] == 'desc' end + def wants_notificationcomments_in_reverse_order? + self.pref[:notificationcomments_sorting] == 'desc' + end # Return user's RSS key (a 40 chars long string), used to access feeds def rss_key if rss_token.nil? @@ -505,15 +577,16 @@ class User < Principal # Find a user account by matching the exact login and then a case-insensitive # version. Exact matches will be given priority. #通过用户名查找相应的用户,若没有匹配到,则不区分大小写进行查询 + #修改:不再匹配不区分大小写情况 -zjc def self.find_by_login(login) if login.present? login = login.to_s # First look for an exact match user = where(:login => login).all.detect {|u| u.login == login} - unless user - # Fail over to case-insensitive if none was found - user = where("LOWER(login) = ?", login.downcase).first - end + #unless user + # # Fail over to case-insensitive if none was found + # user = where("LOWER(login) = ?", login.downcase).first + #end user end end @@ -588,6 +661,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 = [] @@ -609,11 +691,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 @@ -634,6 +741,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) @@ -645,6 +771,7 @@ class User < Principal end end + # Return true if the user is allowed to do the specified action on a specific context # Action can be: # * a parameter-like Hash (eg. :controller => 'projects', :action => 'edit') @@ -667,7 +794,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 @@ -680,6 +820,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) && @@ -748,10 +891,39 @@ class User < Principal when News # always send to project members except when mail_notification is set to 'none' true + #判定用户是否接受留言提醒邮件 + when JournalsForMessage + ##如果是直接留言并且留言对象是Project并且Project类型是课程(课程留言) + if !object.at_user && object.jour.class.to_s.to_sym == :Project && object.jour.project_type == 1 + #根据用户设置邮件接收模式判定当前用户是否接受邮件提醒 + is_notified_project object.jour + end + end end end + #用户是否接收project的消息提醒 + def is_notified_project arg + if arg.is_a?(Project) + case mail_notification + when 'selected' + notified_projects_ids.include?(arg.id) + when 'only_my_events' + projects.include?(arg) + when 'only_assigned' + false + when 'only_owner' + course = Course.find_by_extra(arg.identifier) + course.teacher == self + end + #勾选的项目或用户的项目 TODO:需改 + #notified_projects_ids.include?(arg) || projects.include?(arg) + else + false + end + end + def self.current=(user) Thread.current[:current_user] = user end @@ -793,7 +965,6 @@ class User < Principal errors.add(:password, :too_short, :count => Setting.password_min_length.to_i) end end - private def act_as_activity @@ -808,6 +979,7 @@ class User < Principal substitute = User.anonymous Attachment.update_all ['author_id = ?', substitute.id], ['author_id = ?', id] Comment.update_all ['author_id = ?', substitute.id], ['author_id = ?', id] + Notificationcomment.update_all ['author_id = ?', substitute.id], ['author_id = ?', id] Issue.update_all ['author_id = ?', substitute.id], ['author_id = ?', id] Issue.update_all 'assigned_to_id = NULL', ['assigned_to_id = ?', id] Journal.update_all ['user_id = ?', substitute.id], ['user_id = ?', id] @@ -835,6 +1007,8 @@ class User < Principal Redmine::Utils.random_hex(16) end + + end class AnonymousUser < User diff --git a/app/models/user_grade.rb b/app/models/user_grade.rb index ea951ead..074aa516 100644 --- a/app/models/user_grade.rb +++ b/app/models/user_grade.rb @@ -2,4 +2,37 @@ class UserGrade < ActiveRecord::Base # attr_accessible :title, :body attr_accessible :user_id, :project_id, :grade belongs_to :project + before_save :correct_score + validates_uniqueness_of :user_id, :scope => [:project_id] + #validate :my_validation + + #修正分数 + #分数小于0时修正为0 + #分数大于等于0时不修正 -by zjc + def correct_score + if !self.grade.nil? && self.grade < 0 + self.grade = 0 + end + end + + #def self.exit_user_and_project(user,project) + # unless user.nil? || project.nil? + # if user.class.to_s == 'User' && project.class.to_s == 'Project' + # user_grade = UserGrade.find_by_user_id_and_project_id(user.id,project.id) + # user_grade + # else + # nil + # end + # else + # nil + # end + #end + + #def my_validation + # if user_id.nil? || project_id.nil? + # errors[:Base] << "用户和项目不能为空" + # elsif UserGrade.exit_user_and_project(user_id,project_id) + # errors[:Base] << "当前记录已存在" + # end + #end end diff --git a/app/models/user_levels.rb b/app/models/user_levels.rb new file mode 100644 index 00000000..a24738a2 --- /dev/null +++ b/app/models/user_levels.rb @@ -0,0 +1,68 @@ +#用户等级类 - by zjc +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_preference.rb b/app/models/user_preference.rb index 5b95386b..e0a54180 100644 --- a/app/models/user_preference.rb +++ b/app/models/user_preference.rb @@ -54,6 +54,9 @@ class UserPreference < ActiveRecord::Base def comments_sorting; self[:comments_sorting] end def comments_sorting=(order); self[:comments_sorting]=order end + def notificationcomments_sorting; self[:notificationcomments_sorting] end + def notificationcomments_sorting=(order); self[:notificationcomments_sorting]=order end + def warn_on_leaving_unsaved; self[:warn_on_leaving_unsaved] || '1'; end def warn_on_leaving_unsaved=(value); self[:warn_on_leaving_unsaved]=value; end end diff --git a/app/models/user_score.rb b/app/models/user_score.rb new file mode 100644 index 00000000..6371fc12 --- /dev/null +++ b/app/models/user_score.rb @@ -0,0 +1,413 @@ +# Redmine - project management software +# Copyright (C) 2006-2013 Jean-Philippe Lang +# +# 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. + +class UserScore < ActiveRecord::Base + belongs_to :user + + before_save :correct_score + + def self.find_max_file + self.maximum(:file) + end + + def self.find_min_file + self.minimum(:file) + end + + def self.find_max_issue + self.maximum(:issue) + end + + def self.find_min_issue + self.minimum(:file) + end + # 以上类方法目测没用,反正也报错 + # =============================================================================== + + # 前略·协同得分 + # operate - 更新操作 类型 symbol + # user - 计分用户 + # + # Examples + # + # UserScore.joint(:post_message, User.current, nil) + # # => true #当前用户发帖计分操作成功 + # + # Returns boolean. 返回积分保存结果 + 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_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_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_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})" + else + Rails.logger.error "[UserScore#joint] ===> #{operate} is not define." + return false + end + rescue => e + Rails.logger.error "[UserScore#joint] ===> Exception: #{e}." + end + + # 前略·影响力得分 + # operate - 更新操作 类型 symbol + # user - 计分用户 + # + # Examples + # + # UserScore.influence(:followed_by, user) + # # => true #当前被关注用户记分成功 + # + # Returns boolean. 返回积分保存结果 + 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 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的关注 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." + return false + end + rescue => e + Rails.logger.error "[UserScore#influence] ===> Exception: #{e}." + end + + # 前略·技术得分 + # operate - 更新操作 类型 symbol + # user - 计分用户 + # + # Examples + # + # UserScore.skill(:followed_by, current_user, target_user) + # # => true #当前current_user对target_user用户帖子的记分成功 + # + # Returns boolean. 返回积分保存结果 + 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分 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 = UserLevels.get_level(current_user) + if level == 1 + 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分 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分 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 = UserLevels.get_level(current_user) + if level == 1 + 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分 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分 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." + return false + end + rescue => e + Rails.logger.error "[UserScore#skill] ===> Exception: #{e}." + end + + # 前略·项目得分 + # operate - 更新操作 类型 symbol + # user - 计分用户 + # + # Examples + # + # UserScore.project(:pull_code, current_user) + # # => true #当前current_user对项目贡献积分成功 + # + # Returns boolean. 返回积分保存结果 + 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 提交了代码 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 提交了文档 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 提交了附件 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 更新了缺陷完成度 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 发布了缺陷 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." + return false + end + rescue => e + 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) + cUser = (current_user.kind_of?User) ? current_user : User.find_by_id(current_user) + tUser = (target_user.kind_of?User) ? target_user : User.find_by_id(target_user) + + [cUser, tUser] + end + + #修正分数 + #分数小于0时修正为0 + #分数大于等于0时不修正 -by zjc + def correct_score + if !self.collaboration.nil? && self.collaboration < 0 + self.collaboration = 0 + end + if !self.influence.nil? && self.influence < 0 + self.influence = 0 + end + if !self.skill.nil? && self.skill < 0 + self.skill = 0 + end + if !self.active.nil? && self.active < 0 + self.active = 0 + end + end +end diff --git a/app/models/user_score_details.rb b/app/models/user_score_details.rb new file mode 100644 index 00000000..61d5d098 --- /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 f700e62a..e2e255a1 100644 --- a/app/models/watcher.rb +++ b/app/models/watcher.rb @@ -22,6 +22,8 @@ class Watcher < ActiveRecord::Base has_one :project_status has_one :users_status #end + after_create :be_user_score + before_destroy :down_user_score validates_presence_of :user validates_uniqueness_of :user_id, :scope => [:watchable_type, :watchable_id] @@ -70,4 +72,22 @@ class Watcher < ActiveRecord::Base end pruned end + + # 更新用户分数 -by zjc + def be_user_score + #添加了关注 + if self.watchable_type == 'Principal' + #影响力得分 + UserScore.influence(:followed_by, self.user,self.watchable,self, { watcher_id: self.id }) + end + + end + #减分操作 -by zjc + def down_user_score + #取消关注 + if self.watchable_type == 'Principal' + UserScore.influence(:cancel_followed, self.user,self.watchable,self, { watcher_id: self.id }) + end + + end end diff --git a/app/views/account/register.html.erb b/app/views/account/register.html.erb index cc7a26ad..fac05e6d 100644 --- a/app/views/account/register.html.erb +++ b/app/views/account/register.html.erb @@ -1,409 +1,447 @@ -

    <%=l(:label_register)%> <%=link_to l(:label_login_with_open_id_option), signin_url if Setting.openid? %>

    +

    <%= l(:label_register) %> <%= link_to l(:label_login_with_open_id_option), signin_url if Setting.openid? %>

    <%= labelled_form_for @user, :url => register_path do |f| %> -<%= error_messages_for 'user' %> + <%= error_messages_for 'user' %> -
    -

    - - + +
    <%= l(:label_identity) %> * - -
    +

    + <% if @user.auth_source_id.nil? %> +

    <%= f.text_field :login, :size => 25, :required => true %> + <%= l(:label_max_number) %>

    -<% if @user.auth_source_id.nil? %> -

    <%= f.text_field :login, :size => 25, :required => true %> - <%= l(:label_max_number) %>

    -

    <%= f.password_field :password, :size => 25, :required => true %> - <%= l(:text_caracters_minimum, :count => Setting.password_min_length) %>

    +

    <%= f.password_field :password, :size => 25, :required => true %> + <%= l(:text_caracters_minimum, :count => Setting.password_min_length) %>

    -

    <%= f.password_field :password_confirmation, :size => 25, :required => true %>

    -<% end %> -
    +

    + + + + + + +
    + <%= l(:label_location) %> * + + + + +
    +

    + + -

    <%= submit_tag l(:button_submit) %>

    +

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

    <% end %> <% if Setting.openid? %> -

    <%= f.text_field :identity_url %>

    +

    <%= f.text_field :identity_url %>

    <% end %> -<% @user.custom_field_values.select {|v| v.editable? || v.required?}.each do |value| %> -

    <%= custom_field_tag_with_label :user, value %>

    +<% @user.custom_field_values.select { |v| v.editable? || v.required? }.each do |value| %> +

    <%= custom_field_tag_with_label :user, value %>

    <% end %> \ No newline at end of file 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 00000000..f0bebaf8 --- /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 f73df8fb..52b090bd 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 %> @@ -33,7 +34,7 @@ <% if images.any? %>
    <% images.each do |attachment| %> -
    <%= thumbnail_small_tag(attachment) %>
    +
    <%= thumbnail_tag(attachment) %>
    <% end %>
    <% end %> diff --git a/app/views/attachments/_temp.html.erb b/app/views/attachments/_temp.html.erb new file mode 100644 index 00000000..c5a3661d --- /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/add_exist_file_to_course.js.erb b/app/views/attachments/add_exist_file_to_course.js.erb new file mode 100644 index 00000000..58e5690e --- /dev/null +++ b/app/views/attachments/add_exist_file_to_course.js.erb @@ -0,0 +1,17 @@ +<% if @save_flag %> + window.location.reload(); +<% else %> + // alert('添加文件失败:\n<%=@save_message[0]%>'); + $('#ajax-modal').html('

    添加文件失败

    <%=@save_message.join(', ')%>'); + + var el = $('#ajax-modal').first(); + var title = el.find('h3.title').text(); + el.dialog({ + width: '200px', + modal: true, + resizable: false, + dialogClass: 'modal', + title: title + }); + +<% end %> diff --git a/app/views/attachments/autocomplete.js.erb b/app/views/attachments/autocomplete.js.erb index 784128ea..404ad9a6 100644 --- a/app/views/attachments/autocomplete.js.erb +++ b/app/views/attachments/autocomplete.js.erb @@ -1,2 +1,7 @@ $('#relation_file_form').show(); +<% if @project%> $('#relation_file').html('<%=render_attachments_for_new_project(@project, nil)%>'); +<% elsif @course%> +$('#relation_file').html('<%=render_attachments_for_new_course(@course, nil)%>'); +<% end%> + diff --git a/app/views/attachments/upload.js.erb b/app/views/attachments/upload.js.erb index 63600619..24256cca 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/avatar/_avatar_form.html.erb b/app/views/avatar/_avatar_form.html.erb index fc55bd2e..272397c6 100644 --- a/app/views/avatar/_avatar_form.html.erb +++ b/app/views/avatar/_avatar_form.html.erb @@ -42,17 +42,17 @@
    - - <%= l(:button_upload_photo) %> + + <%= l(:button_upload_photo) %> - + <%= file_field_tag 'avatar[image]', :id => nil, :class => 'file_selector', :style => 'width:70px;',#added by young :size => "1", :multiple => false, - :onchange => 'addInputAvatar(this);', + :onchange => 'addInputAvatar(this);', :data => { :max_file_size => Setting.attachment_max_size.to_i.kilobytes, :max_file_size_message => l(:error_attachment_too_big, :max_size => number_to_human_size(Setting.attachment_max_size.to_i.kilobytes)), @@ -61,7 +61,7 @@ :description_placeholder => nil ,# l(:label_optional_description) :source_type => source.class.to_s, :source_id => source.id.to_s - } %> + } %> <% content_for :header_tags do %> diff --git a/app/views/bids/_app_link.html.erb b/app/views/bids/_app_link.html.erb new file mode 100644 index 00000000..d61f4ef8 --- /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 00000000..6bccc08f --- /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 3ef55c56..d452b6d5 100644 --- a/app/views/bids/_bid_homework_show.html.erb +++ b/app/views/bids/_bid_homework_show.html.erb @@ -13,14 +13,20 @@ <%= 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)) %> <%# 提交作业按钮 %> - <%= link_to l(:label_commit_homework), '#OpenWindow', rel: 'leanModal', onclick: "showSubH(#{bid.id}, '#{bid.name}');" if User.current.member_of?(@project) %> + + <% 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) %> + <% else %> + <%= l(:lable_has_commit_homework)%> + <% end %> <% end %> <% 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( @@ -35,19 +41,19 @@ - <% @bidding_project = bid.biding_projects.all - @temp = [] - @bidding_project.each do |pro| + <% bidding_project = bid.biding_projects.all + temp = [] + bidding_project.each do |pro| if pro.project && pro.project.project_status - @temp << pro + temp << pro end - @temp + temp 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) %>) @@ -64,11 +70,11 @@ - <% 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%> <% elsif bid.reward_type == 2 %> <%= l(:label_bids_reward_method) %><%= bid.budget%> + <% 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%> <% elsif bid.reward_type == 2 %> <%= l(:label_bids_reward_method) %><%= bid.budget%> <% else %> - <% end %> + <% end %> @@ -77,18 +83,18 @@ - <%= l(:label_create_time) %> :  <%=format_time bid.created_on %> <%= l(:field_deadline) %> :  <%=bid.deadline %> - - + + + <%= l(:label_create_time) %> :  <%=format_time bid.created_on %> <%= l(:field_deadline) %> :  <%=bid.deadline %> + + + <% end %> <% end %> - \ No newline at end of file diff --git a/app/views/bids/_bid_show.html.erb b/app/views/bids/_bid_show.html.erb index 8d3ffec1..47f1560d 100644 --- a/app/views/bids/_bid_show.html.erb +++ b/app/views/bids/_bid_show.html.erb @@ -13,7 +13,34 @@ - + <% if bid.reward_type == 3 %> @@ -60,6 +87,6 @@ diff --git a/app/views/bids/_fork_form.html.erb b/app/views/bids/_fork_form.html.erb index ea110473..3fcf0f02 100644 --- a/app/views/bids/_fork_form.html.erb +++ b/app/views/bids/_fork_form.html.erb @@ -15,9 +15,11 @@ <%= f.text_field :budget, :required => true, :size => 60, :style => "width:350px;", :placeholder => l(:label_bids_reward_what) %>

    -->

    <%= f.text_field :deadline, :value => nil,:required => true, :size => 60, :style => "width:150px;" %><%= calendar_for('bid_deadline')%> -

    + +

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

    <%= l(:label_attachment_plural) %>

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

    \ No newline at end of file diff --git a/app/views/bids/_homework.html.erb b/app/views/bids/_homework.html.erb index eb6b9bbf..f3578e71 100644 --- a/app/views/bids/_homework.html.erb +++ b/app/views/bids/_homework.html.erb @@ -13,27 +13,56 @@ <% end %> -<% 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? && 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_commit_homework), new_submit_homework_path, :onclick => "$('#put-bid-form').slideToggle(); this.blur(); return false;" %> + <%#= 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 bid.reward_type.nil? or bid.reward_type == 1%> <%= l(:label_bids_reward_method) %><%= l(:label_call_bonus) %> <%= l(:label_RMB_sign) %><%= bid.budget%> <% elsif bid.reward_type == 2%> <%= l(:label_bids_reward_method) %><%= bid.budget%> <% else %> <% end %> + <% 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%> + + + <% elsif bid.reward_type == 2%> + + <%= l(:label_bids_reward_method) %> + <%= bid.budget%> + + <% else %> + <% end %> +
    + + + + + + + + +
    + <% if @homework_list.empty? %> +
    + 暂无学生提交作业! +
    + <% end %> +
    + +
    + + + +
    <%= render :partial => 'homework_list', :locals => {:homework => @homework_list} %> diff --git a/app/views/bids/_homework_form.html.erb b/app/views/bids/_homework_form.html.erb index 5aa3462f..92b16203 100644 --- a/app/views/bids/_homework_form.html.erb +++ b/app/views/bids/_homework_form.html.erb @@ -32,8 +32,11 @@

    -->

    <%= f.text_field :deadline, :required => true, :size => 60, :style => "width:150px;" %><%= calendar_for('bid_deadline')%>

    + +

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

    <%= hidden_field_tag 'course_id', @project_id %>

    <%= l(:label_attachment_plural) %> diff --git a/app/views/bids/_homework_list.html.erb b/app/views/bids/_homework_list.html.erb index aa4140f9..9f6b45db 100644 --- a/app/views/bids/_homework_list.html.erb +++ b/app/views/bids/_homework_list.html.erb @@ -1,102 +1,153 @@ -<% is_student = is_cur_course_student? @bid.courses.first %> -<% is_teacher = is_course_teacher User.current,@bid.courses.first %> - -<%= form_tag(:controller => 'bids', :action => "show_project", :method => :get) do %> +<% is_student = is_cur_course_student(@bid.courses.first) %> +<% 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_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?) %> - -
    <% end %> <% display_id = im_watching_student_id? @bid%> <% @homework_list.each do |homework|%> - <% if homework.attachments.any?%> - +
    - - diff --git a/app/views/bids/show_courseEx.html.erb b/app/views/bids/show_courseEx.html.erb new file mode 100644 index 00000000..039de6b7 --- /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? %> + + +
    <%= image_tag(url_to_avatar(homework.user), :class => "avatar")%> - - - +
    -   作业   :  - <% attachments = homework.attachments.map %> - <% for attachment in attachments %> - <% if attachments.count > 1 && attachment != attachments.first %> -
    - <% for item in 1..7 %> -   - <% end %> - <% end %> - <%= link_to_attachment attachment , :download => true -%> +
    + + + + + + + + + - - + <% end %> + + +
    <%= 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_student %> - <%= link_to "互评>>" , homework_attach_path(homework)%> - <% else %> - <% if is_teacher %> - <%= link_to "综评>>" , homework_attach_path(homework)%> - <% end %> - <% end %> -
    + +
    + + + + + + + + + + + + + + + + - - - - - - - - - + +
    + 作品名称:  + <% 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 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 %> + +
      - 发布人:  <%= link_to ( is_teacher ? homework.user.realname : homework.user ), user_path(homework.user)%> - - 作业评分: - <% stars_reates = homework.rates(:quality) %> - <% sum = 0 %> - <% stars_reates.each do |star_reates| %> - <% sum = sum + star_reates.stars %> - <% end %> - <% stars_reates_count = stars_reates.count == 0 ? 1 : stars_reates.count %> - <%= format("%.2f", sum * 1.0 / stars_reates_count) %> - - <% if Time.parse(@bid.deadline.to_s) < Time.parse(homework.attachments[0].created_on.to_s) %> - 迟交 - <% end %> -
      - <% if is_cur_course_user? @bid %> - <%= l(:label_bidding_user_studentcode) %>  : <%= homework.user.user_extensions.student_id%> - <% end %> -
    - <% if (User.current == homework.user) || (!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 =?',3,7, 9)).size >0) %> -

    - <% options = {:author => true, :deletable => attach_delete(homework)} %> - <%= render :partial => 'attachments/links', - :locals => {:attachments => homework.attachments, :options => options} %> -

    - <% 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 %> + +
    -
    - <% end %> -<% end %> +
    +<% end %> \ No newline at end of file diff --git a/app/views/bids/contest.html.erb b/app/views/bids/contest.html.erb index dd10f7b1..bd069c8c 100644 --- a/app/views/bids/contest.html.erb +++ b/app/views/bids/contest.html.erb @@ -32,13 +32,13 @@ diff --git a/app/views/bids/show.html.erb b/app/views/bids/show.html.erb index 8b7e0d8e..96ed4ea7 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 574bd117..aacc011e 100644 --- a/app/views/bids/show_course.html.erb +++ b/app/views/bids/show_course.html.erb @@ -8,10 +8,10 @@

    - @@ -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/bids/show_project.html.erb b/app/views/bids/show_project.html.erb index c14d2e14..039de6b7 100644 --- a/app/views/bids/show_project.html.erb +++ b/app/views/bids/show_project.html.erb @@ -1,8 +1,9 @@ <% if @bid.homework_type == Bid::HomeworkFile %> + <%= render :partial => 'homework' %> <% else %> - + + + \ No newline at end of file diff --git a/app/views/contestnotifications/new.html.erb b/app/views/contestnotifications/new.html.erb new file mode 100644 index 00000000..30d5f010 --- /dev/null +++ b/app/views/contestnotifications/new.html.erb @@ -0,0 +1,9 @@ + +<%= labelled_form_for @contestnotification, :url => contest_contestnotifications_path(@contest), :html => { :id => 'contestnotifications-form', :multipart => true } do |f| %> + <%= render :partial => 'contestnotifications/form', :locals => { :f => f } %> + <%= submit_tag l(:button_create), :class => "whiteButton m3p10 h30" %> + <%= submit_tag l(:button_cancel), :class => "whiteButton m3p10 h30",:onclick => "cancel();" %> + + +<% end %> +
    diff --git a/app/views/contestnotifications/show.html.erb b/app/views/contestnotifications/show.html.erb new file mode 100644 index 00000000..eea4cc20 --- /dev/null +++ b/app/views/contestnotifications/show.html.erb @@ -0,0 +1,91 @@ + +
    + <%= link_to(l(:button_edit), + edit_contest_contestnotification_path(@contest, @contestnotification), + :class => 'icon icon-edit', + :accesskey => accesskey(:edit), + :onclick => '$("#edit-contestnotifications").show(); return true;') if (User.current.admin? && User.current.logged? )||(User.current == @contest.author && User.current.logged?)%> + <%= delete_link contest_contestnotification_path(@contest, @contestnotification) if (User.current.admin? && User.current.logged? )||(User.current == @contest.author && User.current.logged?) %> +
    + +

    <%=h @contestnotification.title %>

    + + + +
    + +
    + <%= textilizable(@contestnotification, :description) %> +
    + <%#= link_to_attachments @contestnotification %> +
    + + + <% if User.current.logged? %> +

    + <%= toggle_link l(:label_comment_add), "add_notificationcomment_form", :focus => "notificationcomment_notificationcomments" %> +

    + <% else %> + <%= l(:label_user_login_notificationcomment) %> + <%= link_to l(:label_user_login_new), signin_path %> + <% end %> + + <%= form_tag( contest_contestnotification_notificationcomments_path(@contest, @contestnotification) , :id => "add_notificationcomment_form", :style => "display:none;") do %> +
    + <%= text_area 'notificationcomment', 'notificationcomments', :cols => 80, :rows => 15, :class => 'wiki-edit' %> + <%= wikitoolbar_for 'notificationcomment_notificationcomments' %> +
    +

    + <%= submit_tag l(:button_add) %> + <%= submit_tag l(:button_cancel), :onclick => "cancel();" %> +

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

    <%= l(:label_comment_plural) %>

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

    + <%= textilizable(notificationcomment.notificationcomments) %> +

    <%= format_time(notificationcomment.created_at) %><%#= link_to_if_authorized_contest image_tag('delete.png'), {:controller => 'notificationcomments', :action => 'destroy', :id => @contestnotifications, :notificationcomment_id => notificationcomment}, + :data => {:confirm => l(:text_are_you_sure)}, :method => :delete, :title => l(:button_delete) %>
    + <% end if @notificationcomments.any? %> +
    + + diff --git a/app/views/contests/_list_projects.html.erb b/app/views/contests/_list_projects.html.erb index 48a5ed32..10086e5a 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/index.html.erb b/app/views/contests/index.html.erb index 670ba27c..8c999f94 100644 --- a/app/views/contests/index.html.erb +++ b/app/views/contests/index.html.erb @@ -15,7 +15,7 @@ diff --git a/app/views/contests/show_attendingcontest.html.erb b/app/views/contests/show_attendingcontest.html.erb index 8a567bd5..ecdfd5ac 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,13 +296,17 @@ <%= 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 %>
    + <% score = c_softapplication.softapplication.average(:quality).try(:avg).try(:round, 2).to_f %> <%= l(:label_final_scores) %> - :<%= c_softapplication.softapplication.average(:quality).try(:avg).try(:round, 2).to_i.to_s %> + :<%= format("%.2f" , score) %> 分 diff --git a/app/views/contests/show_contest.html.erb b/app/views/contests/show_contest.html.erb index 67414b0c..c379bc66 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 00000000..ef8f3756 --- /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.teacher.user_extensions.school.nil? %> + <%= link_to @course.teacher.user_extensions.school.try(:name), school_course_list_path(@course.teacher.user_extensions.school) %> + <% 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 84% rename from app/views/projects/_course_form.html.erb rename to app/views/courses/_course_form.html.erb index 017c4e6e..2e7607bb 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 %> -

    +

    - @@ -94,7 +93,8 @@ - ".html_safe %>

    + ".html_safe %> +

    <% elsif @course.time == 2009 %>

    @@ -237,7 +237,8 @@ ".html_safe %>
    <%= l(:label_term) %> *  

    <% end %> - <% end %> + <% end %> + <% unless @course.nil? %> <% if @course.term == l(:label_spring) %> @@ -277,7 +278,8 @@ <% end %> - <% end %>

    + <% end %> +

    @@ -292,48 +294,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 00000000..92f59f85 --- /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 63% rename from app/views/projects/_homework_form.html.erb rename to app/views/courses/_homework_form.html.erb index e4a47136..41c05960 100644 --- a/app/views/projects/_homework_form.html.erb +++ b/app/views/courses/_homework_form.html.erb @@ -21,20 +21,22 @@ <%= 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 %>

    <%= f.text_area :description, :rows => 8, :class => 'wiki-edit', :style => "font-size:small;width:490px;margin-left:10px;", :maxlength => Bid::DESCRIPTION_LENGTH_LIMIT %>

    - -

    <%= f.text_field :deadline, :required => true, :size => 60, :style => "width:150px;" %><%= calendar_for('bid_deadline')%> +<% time = (Time.now + 3600 * 24).strftime('%Y-%m-%d') %> +

    <%= f.text_field(:deadline, :required => true, :size => 60, :style => "width:150px;",:value => "#{time}") %><%= calendar_for('bid_deadline')%>

    -

    <%= f.select :homework_type, homework_type_option %> +

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

    -

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

    <%= f.select :proportion, proportion_option %> +

    +

    <%= 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 00000000..a8a9e808 --- /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 7f2b629c..384b07df 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 00000000..90803fdd --- /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 00000000..3ea34516 --- /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 00000000..75c2b774 --- /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 0f3d2213..acbbaeb4 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 00000000..db94cf6c --- /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_all) %><%= 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()+"/courses", :controller => 'courses', :action => 'index' %> <%=link_to l(:field_homepage), home_path %> > <%=link_to l(:label_course_all), :controller => 'courses', :action => 'index' %>
    + <% 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 00000000..3d3076bc --- /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 00000000..81e6ec37 --- /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 76% rename from app/views/projects/new_homework.html.erb rename to app/views/courses/new_homework.html.erb index e1fd553b..b3fff9e5 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 => "#{params[:id] || params[: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 00000000..c0a6f4a5 --- /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 00000000..25b45e0d --- /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 request.host() + "/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 00000000..c2030ffe --- /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 00000000..0879b795 --- /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 00000000..f0cc6214 --- /dev/null +++ b/app/views/courses/show.html.erb @@ -0,0 +1,103 @@ +<% 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.id) %> <%= l(:label_comments_count, :count => e.journals.count) %> +
    +
    +
    + + <% end %> +
    + + <% end -%> + + + +
    +<% end %> +
    + + + + + +
    <%= 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_create_time %> + : <%= format_time(@course.created_at) %> +
    +
    +
    + + + + + + diff --git a/app/views/documents/show.html.erb b/app/views/documents/show.html.erb index 38ed8819..d626fe30 100644 --- a/app/views/documents/show.html.erb +++ b/app/views/documents/show.html.erb @@ -1,3 +1,5 @@ +
    +
    <% if User.current.allowed_to?(:edit_documents, @project) %> <%= link_to l(:button_edit), edit_document_path(@document), :class => 'icon icon-edit', :accesskey => accesskey(:edit) %> @@ -7,26 +9,15 @@ <% end %>
    - - - - - - - -

    <%=h @document.title %>

    -
    - <%= textilizable @document.description, :attachments => @document.attachments %> -
    -

    <%= format_date @document.created_on %>

    - +<%= textilizable @document, :description, :attachments => @document.attachments %> +
    +

    <%= l(:label_attachment_plural) %>

    <%= link_to_attachments @document %> @@ -42,3 +33,4 @@ <% end %> <% html_title @document.title -%> +
    diff --git a/app/views/files/_course_file.html.erb b/app/views/files/_course_file.html.erb new file mode 100644 index 00000000..d9913539 --- /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 00000000..960b2d39 --- /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 00000000..1a8a8ca6 --- /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 00000000..f73cac07 --- /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 a1cfb37e..bd66d93b 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,16 +13,25 @@ <%= select_tag "version_id", content_tag('option', '') + options_from_collection_for_select(versions, "id", "name"), {style: 'width:100px'} %> + <% if attachmenttypes.any? %> + + + <% end %> + <% else %> +

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

    <% end %> - <% if attachmenttypes.any? %> - - - <% end %>
    <%= l(:attachment_type) %> + <%= select_tag "attachment_type", + options_from_collection_for_select(attachmenttypes, "id", + "typeName", 2), {style: 'width:100px'} %> + <%= l(:attachment_type) %> - <%= select_tag "attachment_type", - options_from_collection_for_select(attachmenttypes, "id", - "typeName", 2), {style: 'width:100px'} %> -
    diff --git a/app/views/files/_project_file.html.erb b/app/views/files/_project_file.html.erb new file mode 100644 index 00000000..1212db05 --- /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 00000000..0eca9c1e --- /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 3bc9863b..88722073 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 9fc430e3..b086b90d 100644 --- a/app/views/files/index.html.erb +++ b/app/views/files/index.html.erb @@ -1,74 +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/forums/_form.html.erb b/app/views/forums/_form.html.erb index b14df7b1..f67aa118 100644 --- a/app/views/forums/_form.html.erb +++ b/app/views/forums/_form.html.erb @@ -3,15 +3,15 @@
    <%= labelled_form_for(@forum) do |f| %> <% if @forum.errors.any? %> -
    -

    <%= pluralize(@forum.errors.count, "error") %> prohibited this forum from being saved:

    + <% end %>
    diff --git a/app/views/forums/show.html.erb b/app/views/forums/show.html.erb index 72e7ce22..34fc953d 100644 --- a/app/views/forums/show.html.erb +++ b/app/views/forums/show.html.erb @@ -3,17 +3,17 @@

    <%=l(:label_memo_new)%>

    <% if User.current.logged? %> <%= labelled_form_for(@memo, :url => create_memo_forum_path(@forum), :html => {:multipart => true} ) do |f| %> - <% if @memo.errors.any? %> +

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

    <%= f.text_area :content, :required => true, :id => 'editor02' %>

    diff --git a/app/views/git_usage/ch_usage.html.erb b/app/views/git_usage/ch_usage.html.erb index 5fca6b15..330ab9b5 100644 --- a/app/views/git_usage/ch_usage.html.erb +++ b/app/views/git_usage/ch_usage.html.erb @@ -143,7 +143,7 @@ body table tr td span6 {

    在桌面上点击鼠标右键,选择TortoiseGit的Settings进行设置

    - Name和Email是用来设置自己的用户名和联系方式的(user.name和user.email必须填写,这些将在版本库提交时用到, 其中的name和email要和forge.trustie.net上的登陆名和邮箱保持一致 + Name和Email是用来设置自己的用户名和联系方式的(user.name和user.email必须填写,这些将在版本库提交时用到, 其中的name和email要和<%= Setting.host_name %>上的登陆名和邮箱保持一致 ,方便代码贡献统计 )。 @@ -313,7 +313,7 @@ body table tr td span6 {

    $git config --global user.name “your_name”

    $git config --global user.email “your_email” 

    Name和Email是用来设置自己的用户名和联系方式的(user.name和user.email必须填写,这些将在版本库提交时用到, - 其中的name和email要和forge.trustie.net上的登陆名和密码保持一致 + 其中的name和email要和<%= Setting.host_name %>上的登陆名和密码保持一致 ,方便代码贡献统计 )。

    diff --git a/app/views/git_usage/en_usage.html.erb b/app/views/git_usage/en_usage.html.erb index ce202c79..237895d2 100644 --- a/app/views/git_usage/en_usage.html.erb +++ b/app/views/git_usage/en_usage.html.erb @@ -143,7 +143,7 @@ body table tr td span6 {

    Right-click on the desktop and select the "Settings" in the "TortoiseGit"

    -

    User name and email are used to set your own user name and contact information( user.name and user.email must be completed because these will be used when submitting the repository, the name and email must be the same with login name and email you registed in the forge.trustie.net +

    User name and email are used to set your own user name and contact information( user.name and user.email must be completed because these will be used when submitting the repository, the name and email must be the same with login name and email you registed in the <%= Setting.host_name %> ).

    Then you can customize the "Context Menu":

    Please check the "Clone","Sync" and "Commit" options in the "Context Menu",

    @@ -306,7 +306,7 @@ body table tr td span6 {

    $git config --global user.name “your_name”M

    $git config --global user.email “your_email” 

    User name and email are used to set your own user name and contact information( user.name and user.email must be completed because these will be used when submitting the repository, - the name and email must be the same with login name and email you registed in the forge.trustie.net + the name and email must be the same with login name and email you registed in the <%= Setting.host_name %> ).

    diff --git a/app/views/homework_attach/_add_jour_reply.html.erb b/app/views/homework_attach/_add_jour_reply.html.erb index 1e202e6a..7a51b0ed 100644 --- a/app/views/homework_attach/_add_jour_reply.html.erb +++ b/app/views/homework_attach/_add_jour_reply.html.erb @@ -1,4 +1,3 @@ - <%= form_tag({:controller => 'homework_attach', :action => 'add_jour_reply'}, :remote => true) do %> <%= text_area_tag 'user_notes', "", :class => 'noline', :style => "resize: none;", :rows => 4, diff --git a/app/views/homework_attach/_addjour.html.erb b/app/views/homework_attach/_addjour.html.erb index 6cb35bcc..fb64a099 100644 --- a/app/views/homework_attach/_addjour.html.erb +++ b/app/views/homework_attach/_addjour.html.erb @@ -1,4 +1,3 @@ - + + + +<%= 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/_homework_member.html.erb b/app/views/homework_attach/_homework_member.html.erb new file mode 100644 index 00000000..9dfe170b --- /dev/null +++ b/app/views/homework_attach/_homework_member.html.erb @@ -0,0 +1,44 @@ +<%= error_messages_for 'member' %> +
    + + + + + + + + + + + + + + + + <% hoemwork_users.each do |user| %> + + <% if homework.user != user %> + + + + <% end %> + + <% end %> + +
    <%= l(:label_user) %><%= l(:label_role_plural) %>
    <%= link_to_user homework.user %> 发布人员
    <%= link_to_user user %> 参与人员 <%= link_to l(:button_delete),destory_homework_users_homework_attach_path(:user_id=>user),:remote => true, :method => :post %>
    +
    + +
    + <%= form_for(hoemwork_users, {:url => add_homework_users_homework_attach_path(homework), :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 get_homework_member_list_homework_attach_index_path(:q => params[:q], :bid_id => params[:id]||homework, :format => 'js') }')" %> +
    + <%= render_new_members_for_homework(members) %> +
    +

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

    +
    + <% end %> +
    diff --git a/app/views/homework_attach/_member_list_partial.html.erb b/app/views/homework_attach/_member_list_partial.html.erb new file mode 100644 index 00000000..ca422f0d --- /dev/null +++ b/app/views/homework_attach/_member_list_partial.html.erb @@ -0,0 +1,3 @@ +
    + <%= render_new_members_for_homework(members) %> +
    \ No newline at end of file diff --git a/app/views/homework_attach/_new_homework.html.erb b/app/views/homework_attach/_new_homework.html.erb new file mode 100644 index 00000000..de749d18 --- /dev/null +++ b/app/views/homework_attach/_new_homework.html.erb @@ -0,0 +1,22 @@ +
    +

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

    +

    + 描 述: + + <%= f.text_area "description", :rows => 8, :class => 'wiki-edit', :style => "font-size:small;width:490px;margin-left:10px;" %> + +

    +

    +

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

    + <%= render :partial => 'attachments/form' %> +

    +
    +

    +
    \ No newline at end of file diff --git a/app/views/homework_attach/_pre_show.html.erb b/app/views/homework_attach/_pre_show.html.erb index 1fb64318..5f8f39fa 100644 --- a/app/views/homework_attach/_pre_show.html.erb +++ b/app/views/homework_attach/_pre_show.html.erb @@ -1,4 +1,3 @@ - <% unless content.nil?%> 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 00000000..7c2403e1 --- /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/add_homework_users.js.erb b/app/views/homework_attach/add_homework_users.js.erb new file mode 100644 index 00000000..dc4b0cc5 --- /dev/null +++ b/app/views/homework_attach/add_homework_users.js.erb @@ -0,0 +1 @@ +$('#content2').html('<%= escape_javascript(render(:partial => 'homework_member', :locals => {:members => @members,:hoemwork_users =>@hoemwork_users,:homework => @homework} )) %>'); \ 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 ed5887a7..e16609b6 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/destory_homework_users.js.erb b/app/views/homework_attach/destory_homework_users.js.erb new file mode 100644 index 00000000..dc4b0cc5 --- /dev/null +++ b/app/views/homework_attach/destory_homework_users.js.erb @@ -0,0 +1 @@ +$('#content2').html('<%= escape_javascript(render(:partial => 'homework_member', :locals => {:members => @members,:hoemwork_users =>@hoemwork_users,:homework => @homework} )) %>'); \ No newline at end of file diff --git a/app/views/homework_attach/edit.html.erb b/app/views/homework_attach/edit.html.erb index e69de29b..9a33ea99 100644 --- a/app/views/homework_attach/edit.html.erb +++ b/app/views/homework_attach/edit.html.erb @@ -0,0 +1,90 @@ + + +
    +
    + + + + + + + + + +
    高校课程实践社区<%= l(:label_user_location) %> :
    <%= 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)%>

    +
    + +

    <%=raw l(:label_edit_homework)%>

    + +
    + <%= 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;" %> + +

    +

    +

    +

    + <% options = {:author => true, :deletable => attach_delete(@homework)} %> + <%= render :partial => 'attachments/links', + :locals => {:attachments => @homework.attachments, :options => options} %> +

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

    + <%= render :partial => 'attachments/form' %> +

    +
    +

    +

    + + <%= submit_tag t(:label_button_ok), :sta => 0, :class => "enterprise"%> + +

    + <% end %> +
    + + diff --git a/app/views/homework_attach/get_homework_member_list.js.erb b/app/views/homework_attach/get_homework_member_list.js.erb new file mode 100644 index 00000000..64fa22cb --- /dev/null +++ b/app/views/homework_attach/get_homework_member_list.js.erb @@ -0,0 +1,2 @@ +$('#principals_for_new_member').replaceWith('<%= j(render :partial => "member_list_partial", locals:{members: @members})%>'); + diff --git a/app/views/homework_attach/new.html.erb b/app/views/homework_attach/new.html.erb index 073ab21b..9f0b69f5 100644 --- a/app/views/homework_attach/new.html.erb +++ b/app/views/homework_attach/new.html.erb @@ -1,33 +1,58 @@ -

    <%=raw l(:label_new_homework)%>

    -
    - <%= form_for('new_form', :remote => true, :method => :post, +
    + + + + + + + + + + +
    高校课程实践社区<%= l(:label_user_location) %> :
    <%= 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)%>

    +
    + +

    <%=h l(:label_new_homework)%>

    +
    + <%= form_for('new_form', :method => :post, :url => {:controller => 'homework_attach', :action => 'create', :user_id => User.current.id, :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;" %>

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

    - <%= render :partial => 'attachments/form' %> -

    -
    - - <%= submit_tag t(:label_new), :sta => 0, :class => "enterprise"%> - <%= submit_tag t(:label_memo_create), :sta => 1, :class => "enterprise"%> +

    +

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

    + <%= render :partial => 'attachments/form' %> +

    +
    +

    + +

    + + <%= submit_tag t(:label_button_ok), :sta => 0, :class => "enterprise"%>

    <% end %> -
    \ No newline at end of file +
    diff --git a/app/views/homework_attach/show.html.erb b/app/views/homework_attach/show.html.erb index 9c39e84f..87dcf60c 100644 --- a/app/views/homework_attach/show.html.erb +++ b/app/views/homework_attach/show.html.erb @@ -1,4 +1,4 @@ - +<%= render :partial => 'layouts/base_homework_attach', :locals => {:homework_attach => @homework} %> -<% is_student = is_cur_course_student? @homework.bid.courses.first %> +<% is_student = is_cur_course_student @homework.bid.courses.first %> <% is_teacher = is_course_teacher User.current,@homework.bid.courses.first %> -

    <%= notice %>

    @@ -24,24 +23,35 @@ 发布人员:<%= link_to @homework.user, user_path(@homework.user)%> - 发布时间:<%=format_time @homework.created_at %> - + + 所属任务:<%= link_to(@homework.bid.name, course_for_bid_path(@homework.bid))%> + 作业下载: - <% options = {:author => true } %> - <%= render :partial => 'app_link', :locals => {:attachments => @homework.attachments, :options => options} %> + <% if @is_evaluation || is_teacher%> + <% options = {:author => true } %> + <%= render :partial => 'app_link', :locals => {:attachments => @homework.attachments, :options => options} %> + <% else %> + <%= l(:label_cant_download) %> + <% end %> - - 所属任务:<%= link_to(@homework.bid.name, project_for_bid_path(@homework.bid))%> + + 参与人员: + <% @homework.users.each do |homework_user| %> + <%= link_to homework_user, user_path(homework_user)%> + <% if @homework.users.count > 1 && homework_user != @homework.users.last %> +
                     + <% end %> + <% end %> - - 平均评分: - <%= rating_for @homework, :static => true, dimension: :quality, class: 'rateable div_inline' %> + 平均评分: + <%= render :partial => 'show_score', :locals => {:stars => @totle_score} %> + 发布时间:<%=format_time @homework.created_at %> @@ -58,15 +68,19 @@
    作业描述:
    - <% @homework.attachments.map do |attachment| %> - <% if attachment.description != nil && attachment.description != "" %> - - -
    <%= attachment.description %>
    - - - <% end %> - <% end %> + + +
    + <% if @homework.description != nil && @homework.description != "" %> + <%= @homework.description %> + <% else %> +
    + 该作业无任何描述! +
    + <% end %> +
    + + @@ -91,22 +105,17 @@
    <%= @stars_status_map["star#{(star/20).to_s}".to_sym] %> -
    +
    <% end %>
    - <% 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} %>
    @@ -123,27 +132,41 @@
    - <%= 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} %>
    -
    -
    作业评论:
    - <% if is_student %> -
    评分: - <%= rating_for @homework, dimension: :quality, class: 'rateable div_inline' %> - (您可以重新打分,打分结果以最后一次打分为主!) -
    - <% end %> -
    + + +<% if !users_for_homework(@homework).include?(User.current) %> +
    +
    作业评论:
    + <% if is_student %> + <% if @is_evaluation %> + <% if @has_evaluation %> +
    + <%= l(:lable_has_evaluation)%> +
    + <% else %> + <%= render :partial => 'evaluation', :locals => {:homework => @homework} %> + <% end %> + <% else %> +
    + <%= l(:lable_close_evaluation)%> +
    + <% end %> + <% end %> +
    +<% end %> <% if !is_teacher %> - -
    - <%= render :partial => 'addjour', :locals => {:homework_attach => @homework, :sta => 0, :is_comprehensive_evaluation => nil} %> -
    + +
    + <%= render :partial => 'addjour', :locals => {:homework_attach => @homework, :sta => 0, :is_comprehensive_evaluation => nil} %> +
    <% end %> +
    <%= render :partial => 'showjour', :locals => {:jour => @jour,:homework => @homework} %> diff --git a/app/views/issues/_action_menu.html.erb b/app/views/issues/_action_menu.html.erb index 3f87eaab..61cea920 100644 --- a/app/views/issues/_action_menu.html.erb +++ b/app/views/issues/_action_menu.html.erb @@ -14,5 +14,5 @@ <%= watcher_link(@issue, User.current) %> <%= link_to l(:button_copy), project_copy_issue_path(@project, @issue), :class => 'icon icon-copy' if User.current.allowed_to?(:add_issues, @project) %> -<%= link_to l(:button_delete), issue_path(@issue), :data => {:confirm => issues_destroy_confirmation_message(@issue)}, :method => :delete, :class => 'icon icon-del' if User.current.allowed_to?(:delete_issues, @project) %> +<%= link_to l(:button_delete), issue_path(@issue.id), :data => {:confirm => issues_destroy_confirmation_message(@issue)}, :method => :delete, :class => 'icon icon-del' if User.current.allowed_to?(:delete_issues, @project) %>
    diff --git a/app/views/issues/_history.html.erb b/app/views/issues/_history.html.erb index fdc35f49..9823e30b 100644 --- a/app/views/issues/_history.html.erb +++ b/app/views/issues/_history.html.erb @@ -11,7 +11,8 @@ - + + diff --git a/app/views/issues/_list.html.erb b/app/views/issues/_list.html.erb index 2b17b4fb..b36c4b57 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") %> @@ -28,11 +28,12 @@
      <% unless issue.author.nil? || issue.author.name == "Anonymous" %>
        - <%= link_to issue.author.name, user_path(issue.author), :class => "bid_user_u" %><%= l(:label_post_on)%> <% a = [] %> + <%= link_to issue.author.name, user_path(issue.author), :class => "bid_user_u" %> + <%= l(:label_post_on)%> <% a = [] %> <% a << column_content[1] %> <%# a << "##{column_content[0]}" << "(#{raw column_content[2]}):" << column_content[4] %> <% a << "#{issue.source_from}" << "(#{raw column_content[2]}):" << column_content[4] %> - <%= link_to a.join(' '), issue_path(issue), :class => "issue-link" %> + <%= link_to a.join(' '), issue_path(issue.id), :class => "issue-link" , :target =>"_blank"%>
      <% end -%>
        @@ -46,7 +47,7 @@ <% end %> <%= l(:label_updated_time_on, format_date(issue.updated_on)).html_safe %>
        - <%= link_to l(:label_find_all_comments), issue_path(issue) %><%= l(:label_comments_count, :count => issue.journals.all.count) %> + <%= link_to l(:label_find_all_comments), issue_path(issue.id) %><%= l(:label_comments_count, :count => issue.journals.all.count) %>
    diff --git a/app/views/issues/_list_simple.html.erb b/app/views/issues/_list_simple.html.erb index 0e4aa073..3a33e6f5 100644 --- a/app/views/issues/_list_simple.html.erb +++ b/app/views/issues/_list_simple.html.erb @@ -12,12 +12,12 @@ <% end %> diff --git a/app/views/issues/show.html.erb b/app/views/issues/show.html.erb index d261957c..89fc862d 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? %> - -
    + + + +<% end %> diff --git a/app/views/layouts/_base_header.html.erb b/app/views/layouts/_base_header.html.erb index d340ea9e..983c83d2 100644 --- a/app/views/layouts/_base_header.html.erb +++ b/app/views/layouts/_base_header.html.erb @@ -41,10 +41,25 @@ <%=link_to_user(User.current)%>
  • @@ -77,11 +92,40 @@ }); } + function addProjectSlipMenu () { + var loggedas = $('#project_loggedas_li') + var project_sub_menu = $('.project_sub_menu') + var course_sub_menu = $('.course_sub_menu') + loggedas.mouseenter(function(event) { + course_sub_menu.hide(); + project_sub_menu.show(); + }); + project_sub_menu.mouseleave(function(event) { + project_sub_menu.hide(); + }); + } + function addCourseSlipMenu () { + var loggedas = $('#course_loggedas_li') + var project_sub_menu = $('.project_sub_menu') + var course_sub_menu = $('.course_sub_menu') + loggedas.mouseenter(function(event) { + project_sub_menu.hide(); + course_sub_menu.show(); + }); + course_sub_menu.mouseleave(function(event) { + course_sub_menu.hide(); + }); + } + $(document).ready(function () { addSlipMenu(); + addProjectSlipMenu (); + addCourseSlipMenu(); }); jQuery(document).ready(function($) { $('.sub_menu').find("a").attr('target', '_blank'); + $('.project_sub_menu').find("a").attr('target', '_blank'); + $('.course_sub_menu').find("a").attr('target', '_blank'); }); diff --git a/app/views/layouts/_base_homework_attach.html.erb b/app/views/layouts/_base_homework_attach.html.erb new file mode 100644 index 00000000..ad90e904 --- /dev/null +++ b/app/views/layouts/_base_homework_attach.html.erb @@ -0,0 +1,15 @@ +
    +
  • <%= authoring journal.created_on, journal.user, :label => :label_updated_time_by %>
    <%= authoring journal.created_on, journal.user, :label => :label_updated_time_by %>
    <%= render_links(issue, journal, :reply_links => reply_links) unless journal.notes.blank? %>
    <%= check_box_tag("ids[]", issue.id, false, :style => 'display:none;', :id => nil) %> - <%= link_to issue.id, issue_path(issue) %> + <%= link_to issue.id, issue_path(issue.id) %> <%= link_to_project(issue.project) %> <%=h issue.tracker %> - <%= link_to truncate(issue.subject, :length => 60), issue_path(issue) %> (<%=h issue.status %>) + <%= link_to truncate(issue.subject, :length => 60), issue_path(issue.id) %> (<%=h issue.status %>)
    + + + + + + + + + +
    高校课程实践社区<%= l(:label_user_location) %> :
    <%= 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_attach.bid.courses.first.name.to_s, homework_course_path(homework_attach.bid.courses.first)) if homework_attach.bid.courses.first%> > + <%=link_to(homework_attach.bid.name, course_for_bid_path(homework_attach.bid)) %> > <%= link_to homework_attach.name.nil? ? homework_attach.user.name + "提交的作业" : homework_attach.name,homework_attach_path(homework_attach)%>

    +
    \ No newline at end of file diff --git a/app/views/layouts/_base_softapplication_index_top_content.html.erb b/app/views/layouts/_base_softapplication_index_top_content.html.erb index d029d27e..7fa65bec 100644 --- a/app/views/layouts/_base_softapplication_index_top_content.html.erb +++ b/app/views/layouts/_base_softapplication_index_top_content.html.erb @@ -1,7 +1,7 @@
    - + -<% end; reset_cycle %> - -
    创新竞赛社区<%=l(:label_contest_innovate_community)%> <%= l(:label_user_location) %> : + + <% 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_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 %> +
    + <% end %> + <% end %> diff --git a/app/views/praise_tread/praise_minus.js.erb b/app/views/praise_tread/praise_minus.js.erb index 74f7d6bf..ab298ba2 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 c2584dcd..d56ff0e6 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 89efec2d..1104440e 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 6ea80203..6c4bfe9a 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/_form.html.erb b/app/views/projects/_form.html.erb index fa2e8da1..ec0bf7fb 100644 --- a/app/views/projects/_form.html.erb +++ b/app/views/projects/_form.html.erb @@ -5,7 +5,9 @@ <% end %>

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

    -

    <%= f.text_area :description, :rows => 8, :class => 'wiki-edit', :style => "font-size:small;width:490px;margin-left:10px;" %>

    +

    + <%= f.text_area :description, :rows => 8, :class => 'wiki-edit', :style => "font-size:small;width:490px;margin-left:10px;" %> +

    <%= f.text_field :identifier, :required => true, :size => 60, :style => "width:488px;", :disabled => @project.identifier_frozen?, :maxlength => Project::IDENTIFIER_MAX_LENGTH %> <% unless @project.identifier_frozen? %> <%= l(:text_length_between, :min => 1, :max => Project::IDENTIFIER_MAX_LENGTH) %> <%= l(:text_project_identifier_info).html_safe %> @@ -24,44 +26,44 @@ <%= call_hook(:view_projects_form, :project => @project, :form => f) %> - +<%# end %> +<%# end %> --> <% unless @project.identifier_frozen? %> diff --git a/app/views/projects/_show_projects_score.html.erb b/app/views/projects/_show_projects_score.html.erb index e9b21e57..d135cfbd 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/search.html.erb b/app/views/projects/search.html.erb index b1bd3d41..36117e0b 100644 --- a/app/views/projects/search.html.erb +++ b/app/views/projects/search.html.erb @@ -24,7 +24,7 @@
    <%= link_to "forge.trustie.net/projects", :controller => 'projects', :action => 'course', :project_type => 1 %> <%= link_to request.host() + "/projects", :controller => 'projects', :action => 'course', :project_type => 1 %> <%=link_to l(:field_homepage), home_path %> > <%=link_to l(:label_course_practice), :controller => 'projects', :action => 'course', :project_type => 1 %>
    diff --git a/app/views/projects/settings/_members.html.erb b/app/views/projects/settings/_members.html.erb index f97e9d0f..f69f9edf 100644 --- a/app/views/projects/settings/_members.html.erb +++ b/app/views/projects/settings/_members.html.erb @@ -1,125 +1,88 @@ <%= error_messages_for 'member' %> -<% roles = Role.find_all_givable - members = @project.member_principals.includes(:roles, :principal).all.sort %> +<% + roles = Role.givable.all + if @project.project_type == Project::ProjectType_course + roles = roles[3..5] + else + roles = roles[0..2] + end + members = @project.member_principals.includes(:roles, :principal).all.sort +%> +
    -<% if members.any? %> - - - - - + <% if members.any? %> +
    <%= l(:label_user) %><%= l(:label_role_plural) %>
    + + + + + <%= call_hook(:view_projects_settings_members_table_header, :project => @project) %> - - - <% members.each do |member| %> - <% next if member.new_record? %> - - - + + + <% members.each do |member| %> + <% next if member.new_record? %> + + + - - <%= error_messages_for 'member' %> -<% roles = Role.find_all_givable - members = @project.member_principals.includes(:roles, :principal).all.sort %> - <% if @project.project_type == 1 %> - <%if member.roles.first.to_s == "Manager" %> - - <% else %> - - <% end %> - <% else %> - + <%= 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 %> + + + <% if @project.project_type == 1 %> + <% if member.roles.first.to_s == "Manager" %> + + <% else %> + + <% end %> + <% else %> + + <% end %> + + <%= call_hook(:view_projects_settings_members_table_row, {:project => @project, :member => member}) %> + + <% end; reset_cycle %> + +
    <%= l(:label_user) %><%= l(:label_role_plural) %>
    <%= link_to_user member.principal %> - - - <% if @project.project_type == 1 %> - <% if member.roles.sort.collect(&:to_s).join(', ') =='Manager' %> - 老师 - <% else %> - <%=h member.roles.sort.collect(&:to_s).join(', ') %> - <% end %> - <% else %> - <%=h member.roles.sort.collect(&:to_s).join(', ') %> - <% end %> +
    <%= 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| %> - -<%= error_messages_for 'member' %> -<% if @project.project_type == 1 %> -<% r = [] %> -<% for i in 3..5 %> -<% roles = Role.givable.all[i] - members = @project.member_principals.includes(:roles, :principal).all.sort %> - <% r << roles %> - <% end %> -<% else %> -<% r = [] %> -<% for i in 0..2 %> -<% roles = Role.givable.all[i] - members = @project.member_principals.includes(:roles, :principal).all.sort %> - <% r << roles %> - <% end %> -<% end %> - -

    <% r.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? %> - - <%= 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? %> - + <%= 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? %> + + <%= 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 %> - - <%= call_hook(:view_projects_settings_members_table_row, { :project => @project, :member => member}) %> -
    -<% else %> -

    <%= l(:label_no_data) %>

    -<% end %>
    - -<%= error_messages_for 'member' %> -<% if @project.project_type == 1 %> -<% r = [] %> -<% for i in 3..5 %> -<% roles = Role.givable.all[i] - members = @project.member_principals.includes(:roles, :principal).all.sort %> - <% r << roles %> - <% end %> -<% else %> -<% r = [] %> -<% for i in 0..2 %> -<% roles = Role.givable.all[i] - members = @project.member_principals.includes(:roles, :principal).all.sort %> - <% r << roles %> - <% end %> -<% end %> - -
    -<% if r.any? %> + <% if roles.any? %> <% if @project.applied_projects.any? %>
    <%= form_for(@applied_members, {:as => :membership, :url => project_memberships_path(@project), :remote => true, :method => :post}) do |f| %> @@ -131,7 +94,7 @@

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

    @@ -144,24 +107,25 @@
    <% end %> - <%= form_for(@member, {:as => :membership, :url => project_memberships_path(@project), :remote => true, :method => :post}) do |f| %> -
    <%=l(:label_member_new)%> + <%= form_for(@member, {:as => :membership, :url => project_memberships_path(@project), :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_project_memberships_path(@project, :format => 'js') }')" %> +

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

    + <%= javascript_tag "observeSearchfield('principal_search', null, '#{ escape_javascript autocomplete_project_memberships_path(@project, :format => 'js') }')" %> -
    - <%= render_principals_for_new_members(@project) %> -
    - -

    <%= l(:label_role_plural) %>: - <% r.each do |role| %> - - - <% end %>

    +
    + <%= render_principals_for_new_members(@project) %> +
    + +

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

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

    -
    + + <% end %>

    + +

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

    +
    + <% end %> <% end %> -<% end %>
    diff --git a/app/views/projects/show.html.erb b/app/views/projects/show.html.erb index 173fc26a..04fb4eb7 100644 --- a/app/views/projects/show.html.erb +++ b/app/views/projects/show.html.erb @@ -1,103 +1,78 @@ <% 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.project) if @project.nil? || @project.id != e.project.id %> - - <%= 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) %>) - <%= l(:label_new_activity) %> - - <%= link_to "#{eventToLanguageCourse(e.event_type, @project)}: "<< format_activity_title(e.event_title), (e.event_type.eql?("attachment")&&e.container.kind_of?(Project)) ? project_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 @project.name %> !
    <%= l :label_update_time %>: <%= format_time(@project.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 @project.name %> !
    <%= l :label_update_time %>: <%= format_time(@project.created_on) %> -
    +
    +

    + <%= 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")%> +
    +
    + <%= h(e.project) if @project.nil? || @project.id != e.project.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, @project)}: "<< format_activity_title(e.event_title), (e.event_type.eql?("attachment")&&e.container.kind_of?(Project)) ? project_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) %> + <% if e.event_type == "issue" %> +
    + <%= link_to l(:label_find_all_comments), issue_path(e) %> <%= l(:label_comments_count, :count => e.journals.count)%> +
    + <% end %> +
    +
    +
    + + <% end %> + <% end -%> + <% if(@events_pages.page == @events_pages.last_page) %> +
    +
    + <%= 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_new_activity) %> + + <%= l(:label_user_create_project) %> <%= link_to @project.name %> ! +
    +
    +
    + <%= l :label_activity_time %>: <%= format_time(@project.created_on) %> +
    +
    +
    + <% end %> +
    +<%end%> + + + + + -<% end %> 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 00000000..95a7085d --- /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/school/index.html.erb b/app/views/school/index.html.erb index 755bd315..a42844ff 100644 --- a/app/views/school/index.html.erb +++ b/app/views/school/index.html.erb @@ -43,9 +43,9 @@ - + <% @tags = obj.reload.tag_list %> <% if non_list_all and (@tags.size > 0) %> @@ -51,14 +51,14 @@ <% when '2' %> - <% if (ProjectInfo.find_by_project_id(obj.id)).user_id == User.current.id %> + <% if (ProjectInfo.find_by_project_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 %> <% when '3' %> - <% if (ProjectInfo.find_by_project_id(obj.project_id)).user_id == User.current.id %> + <% if (ProjectInfo.find_by_project_id(obj.project_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 %> @@ -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/tags/_tag_search_results.html.erb b/app/views/tags/_tag_search_results.html.erb index 1ea452de..43048be5 100644 --- a/app/views/tags/_tag_search_results.html.erb +++ b/app/views/tags/_tag_search_results.html.erb @@ -26,6 +26,9 @@ <%#= l(:label_attachment)%> 开源项目:(<%= @results_count %>) <%= render :partial => "show_open_source_projects",:locals => {:projects_results => open_source_projects_results}%> + <% when show_flag == '9'%> + <%= l(:label_course)%>(<%= @results_count %>) + <%= render :partial => "show_courses",:locals => {:courses_results => courses_results}%> <% else %> <%= l(:label_tags_all_objects)%> diff --git a/app/views/tags/index.html.erb b/app/views/tags/index.html.erb index c74721c3..a5cda994 100644 --- a/app/views/tags/index.html.erb +++ b/app/views/tags/index.html.erb @@ -23,7 +23,7 @@ <%= l(:label_user_plural) %>(<%= @users_tags_num %>) | <%= l(:label_tags_call)%>(<%= @bids_tags_num %>) | <%= l(:field_filename)%>(<%= @attachments_tags_num %>) | - 开源项目(<%= @open_source_projects_num %>) + 开源项目(<%= @open_source_projects_num %>) | <%= l(:label_tags_contest)%>(<%= @contests_tags_num %>) |
    @@ -37,6 +37,7 @@ :attachments_results=> @attachments_results, :contests_results => @contests_results, :open_source_projects_results => @open_source_projects_results, + :courses_results => @courses_results, :show_flag => @obj_flag} %>
    diff --git a/app/views/users/_activity_new_score_index.html.erb b/app/views/users/_activity_new_score_index.html.erb new file mode 100644 index 00000000..0ceb8f15 --- /dev/null +++ b/app/views/users/_activity_new_score_index.html.erb @@ -0,0 +1,8 @@ +
    技术得分:
    +
        踩别人的帖子 -2
    +
        帖子被一级会员顶 +4
    +
        帖子被二级会员顶 +6
    +
        帖子被三级会员顶 +8
    +
        帖子被一级会员踩 -2
    +
        帖子被二级会员踩 -4
    +
        帖子被三级会员踩 -6
    \ No newline at end of file diff --git a/app/views/users/_course_form.html.erb b/app/views/users/_course_form.html.erb index 13ab819d..f5cada9a 100644 --- a/app/views/users/_course_form.html.erb +++ b/app/views/users/_course_form.html.erb @@ -1,44 +1,44 @@
    -
    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 00000000..ec06aa1f --- /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 00000000..74454d49 --- /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 00000000..13659325 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 00000000..5ff08181 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 00000000..625f376c --- /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 = $(''); + 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 = $('',{ + '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 00000000..e3cdc3d5 --- /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 00000000..11939ae7 --- /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 00000000..5bcdad1b --- /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 00000000..432d14e3 --- /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 00000000..9870f522 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 00000000..583f113f 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 00000000..230ba12b 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 00000000..4a3fab52 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 00000000..2f3344e5 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 00000000..529e72f4 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 00000000..85ba9e2a 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 00000000..8f619366 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 00000000..fabb33a1 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 00000000..9fec6fa2 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 00000000..c2ad538c --- /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 00000000..7d2790e7 --- /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 00000000..531acdc5 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 00000000..d4ce3be0 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 00000000..2164c22c 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 00000000..99f635c1 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 00000000..1708a1e0 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 00000000..ff69d1b2 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 00000000..543f13db 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 00000000..5d7afef9 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 00000000..8373aaae 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 00000000..77cf65ef 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 00000000..9cab17d5 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 00000000..437c5ec9 --- /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 00000000..2f83cfd4 --- /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 00000000..da5a8ac4 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 00000000..b0bd9cd6 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 00000000..b04e18f5 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 00000000..7d89f7b0 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 00000000..e50eaccc 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 00000000..89156591 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 00000000..ff9f336f 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 00000000..f69ea006 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 00000000..1436e841 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 00000000..f7be50b1 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 00000000..ae23785d 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 00000000..69e3b7fc --- /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 00000000..6ab13789 --- /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 00000000..4c73d356 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 00000000..9205d301 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 00000000..8d002eeb 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 00000000..649b0d87 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 00000000..79e7a1cc 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 00000000..554c55c8 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 00000000..c10b1669 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 00000000..31ef5a39 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 00000000..ebeeb02f 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 00000000..892a0f08 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 00000000..a7214167 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 00000000..648e71ed 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 00000000..c4407025 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 00000000..649b0d87 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 00000000..774538ac 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 00000000..6124e78b 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 00000000..fbc94bf2 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 00000000..75b945d2 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 00000000..257a1b1e --- /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 00000000..a6c683b9 --- /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 00000000..95ec287a --- /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 00000000..2fa58b29 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 00000000..4592c19b 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 00000000..ce238f12 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 00000000..38f9e9e3 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 00000000..2ace75e1 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 00000000..439bcaa1 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 00000000..3fae972a 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 00000000..89a732f6 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 00000000..52bfee0d 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 00000000..dffb75f0 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 00000000..62a4d8b8 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 00000000..4aee20fc 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 00000000..caa27fe1 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 00000000..523e0dbc 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 00000000..a7b8daa8 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 00000000..63f755b6 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 00000000..0c5375f4 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 00000000..2cdf404c 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 00000000..4ef5758f 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 00000000..d4c1e578 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 00000000..35da0e0f 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 00000000..92db9a0d 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 00000000..e3d86546 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 00000000..4846e2f4 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 00000000..310bcbbb 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 00000000..30275bbb 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 00000000..36c10e0d 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 00000000..c8aee739 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 00000000..acc2af03 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 00000000..36ea182e --- /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 00000000..2f83cfd4 --- /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 00000000..da5a8ac4 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 00000000..b0bd9cd6 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 00000000..b04e18f5 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 00000000..7d89f7b0 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 00000000..e50eaccc 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 00000000..89156591 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 00000000..ff9f336f 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 00000000..f69ea006 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 00000000..1436e841 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 00000000..f7be50b1 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 00000000..ae23785d 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 00000000..69e3b7fc --- /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 00000000..6ab13789 --- /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 00000000..4c73d356 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 00000000..9205d301 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 00000000..8d002eeb 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 00000000..649b0d87 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 00000000..79e7a1cc 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 00000000..554c55c8 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 00000000..c10b1669 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 00000000..31ef5a39 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 00000000..ebeeb02f 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 00000000..892a0f08 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 00000000..a7214167 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 00000000..648e71ed 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 00000000..c4407025 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 00000000..649b0d87 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 00000000..774538ac 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 00000000..6124e78b 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 00000000..fbc94bf2 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 00000000..75b945d2 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 00000000..257a1b1e --- /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 00000000..a6c683b9 --- /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 00000000..95ec287a --- /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 00000000..2fa58b29 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 00000000..4592c19b 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 00000000..ce238f12 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 00000000..38f9e9e3 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 00000000..2ace75e1 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 00000000..439bcaa1 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 00000000..3fae972a 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 00000000..89a732f6 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 00000000..52bfee0d 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 00000000..dffb75f0 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 00000000..62a4d8b8 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 00000000..4aee20fc 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 00000000..caa27fe1 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 00000000..523e0dbc 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 00000000..a7b8daa8 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 00000000..63f755b6 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 00000000..0c5375f4 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 00000000..2cdf404c 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 00000000..4ef5758f 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 00000000..d4c1e578 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 00000000..35da0e0f 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 00000000..92db9a0d 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 00000000..e3d86546 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 00000000..4846e2f4 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 00000000..310bcbbb 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 00000000..30275bbb 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 00000000..36c10e0d 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 00000000..c8aee739 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 00000000..acc2af03 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 00000000..36ea182e --- /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 -->

      ", + "