diff --git a/.gitignore b/.gitignore index 8aa87e9f2..163982b7c 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ /Gemfile.lock /db/schema.rb /Gemfile.lock +/lib/plugins/acts_as_versioned/test/debug.log diff --git a/Gemfile b/Gemfile index 1d8276799..634af9683 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 6680070a7..e52990e2a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -52,6 +52,15 @@ GEM rails (>= 3, < 5) arel (3.0.2) builder (3.0.0) + capybara (2.0.3) + mime-types (>= 1.16) + nokogiri (>= 1.3.3) + rack (>= 1.0.0) + rack-test (>= 0.5.4) + selenium-webdriver (~> 2.0) + xpath (~> 1.0.0) + childprocess (0.5.3) + ffi (~> 1.0, >= 1.0.11) coderay (1.0.9) coffee-rails (3.2.2) coffee-script (>= 2.2.0) @@ -59,11 +68,11 @@ GEM coffee-script (2.2.0) coffee-script-source execjs - coffee-script-source (1.6.1) + coffee-script-source (1.7.0) erubis (2.7.0) - execjs (1.4.0) - multi_json (~> 1.0) + execjs (2.0.2) fastercsv (1.5.0) + ffi (1.9.3-x86-mingw32) hike (1.2.3) i18n (0.6.1) journey (1.0.4) @@ -74,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 e7444a6c5..0fcba47c0 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 000000000..dee720fac --- /dev/null +++ b/app/assets/javascripts/applied_project.js @@ -0,0 +1,2 @@ +// Place all the behaviors and hooks related to the matching controller here. +// All this logic will automatically be available in application.js. diff --git a/app/assets/javascripts/attachment_type_edit.js b/app/assets/javascripts/attachment_type_edit.js new file mode 100644 index 000000000..dee720fac --- /dev/null +++ b/app/assets/javascripts/attachment_type_edit.js @@ -0,0 +1,2 @@ +// Place all the behaviors and hooks related to the matching controller here. +// All this logic will automatically be available in application.js. diff --git a/app/assets/javascripts/contestnotifications.js b/app/assets/javascripts/contestnotifications.js new file mode 100644 index 000000000..dee720fac --- /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 000000000..761567942 --- /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 000000000..afad32db0 --- /dev/null +++ b/app/assets/stylesheets/applied_project.css @@ -0,0 +1,4 @@ +/* + Place all the styles related to the matching controller here. + They will automatically be included in application.css. +*/ diff --git a/app/assets/stylesheets/attachment_type_edit.css b/app/assets/stylesheets/attachment_type_edit.css new file mode 100644 index 000000000..afad32db0 --- /dev/null +++ b/app/assets/stylesheets/attachment_type_edit.css @@ -0,0 +1,4 @@ +/* + Place all the styles related to the matching controller here. + They will automatically be included in application.css. +*/ diff --git a/app/assets/stylesheets/contestnotifications.css b/app/assets/stylesheets/contestnotifications.css new file mode 100644 index 000000000..afad32db0 --- /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 000000000..aea714e47 --- /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 af8487868..0af388c56 100644 --- a/app/controllers/account_controller.rb +++ b/app/controllers/account_controller.rb @@ -143,15 +143,18 @@ class AccountController < ApplicationController end #added by bai - unless @user.id.nil? - ue = UserExtensions.create(:identity => params[:identity].to_i,:technical_title => params[:technical_title], :gender => params[:gender].to_i, :user_id => @user.id, :student_id => params[:no]) - unless params[:province].nil? || params[:city].nil? - ue.location = params[:province] - ue.location_city = params[:city] - ue.save - end + if @user.id != nil + ue = @user.user_extensions ||= UserExtensions.new + #ue = UserExtensions.create(:identity => params[:identity].to_i,:technical_title => params[:technical_title], :gender => params[:gender].to_i, :user_id => @user.id, :student_id => ) + ue.identity = params[:identity].to_i + ue.technical_title = params[:technical_title] + ue.gender = params[:gender].to_i + ue.user_id = @user.id + ue.student_id = params[:no] + ue.location = params[:province] if params[:province] != nil + ue.location_city = params[:city] if params[:city] != nil + ue.save end - #end end end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index a25b346ca..e6efca1e8 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 2f642f544..0b2ae02b3 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 3b43fec9c..73c1dbd90 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 d63f0cfbb..76872d783 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 b5e0b2d85..e0bd9582d 100644 --- a/app/controllers/boards_controller.rb +++ b/app/controllers/boards_controller.rb @@ -28,17 +28,25 @@ class BoardsController < ApplicationController helper :watchers def index - @boards = @project.boards.includes(:last_message => :author).all - @boards = [] << @boards[0] if @boards.any? - if @boards.size == 1 - @board = @boards.first - show and return - end - if @project.project_type == 1 - render :layout => 'base_courses' - else - render :layout => false if request.xhr? + #modify by nwb + if @project + @boards = @project.boards.includes(:last_message => :author).all + @boards = [] << @boards[0] if @boards.any? + if @boards.size == 1 + @board = @boards.first + show and return + end + render :layout => false if request.xhr? + elsif @course + @boards = @course.boards.includes(:last_message => :author).all + @boards = [] << @boards[0] if @boards.any? + if @boards.size == 1 + @board = @boards.first + show and return + end + render :layout => 'base_courses' end + end def show @@ -60,10 +68,11 @@ class BoardsController < ApplicationController preload(:author, {:last_reply => :author}). all @message = Message.new(:board => @board) - if @project.project_type ==1 - render :action => 'show', :layout => 'base_courses' - else + #modify by nwb + if @project render :action => 'show', :layout => !request.xhr? + elsif @course + render :action => 'show', :layout => 'base_courses' end } format.atom { @@ -72,7 +81,12 @@ class BoardsController < ApplicationController includes(:author, :board). limit(Setting.feeds_limit.to_i). all - render_feed(@messages, :title => "#{@project}: #{@board}") + if @project + render_feed(@messages, :title => "#{@project}: #{@board}") + elsif @course + render_feed(@messages, :title => "#{@course}: #{@board}") + end + } end end diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index b2689d0c2..90c034fdb 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 000000000..6b05e8e4d --- /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 b51a11436..987881a83 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 215dd3a58..157de5ce7 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 51486f252..464c4a2b8 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 ed6f9937d..b5c67478c 100644 --- a/app/controllers/files_controller.rb +++ b/app/controllers/files_controller.rb @@ -32,14 +32,16 @@ class FilesController < ApplicationController 'filename' => "#{Attachment.table_name}.filename", 'size' => "#{Attachment.table_name}.filesize", 'downloads' => "#{Attachment.table_name}.downloads" - - @containers = [ Project.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").find(@project.id)] #modify by Long Jun - @containers += @project.versions.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").all.sort - - if @project.project_type == 1 + + if params[:project_id] + @isproject = true + @containers = [ Project.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").find(@project.id)] + @containers += @project.versions.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").all.sort + render :layout => !request.xhr? + elsif params[:course_id] + @isproject = false + @containers = [ Course.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").find(@course.id)] render :layout => 'base_courses' - else - render :layout => !request.xhr? end end @@ -60,37 +62,66 @@ class FilesController < ApplicationController respond_to do |format| format.js end - else - @addTag=false - container = (params[:version_id].blank? ? @project : @project.versions.find_by_id(params[:version_id])) - attachments = Attachment.attach_filesex(container, params[:attachments],params[:attachment_type]) - render_attachment_warning_if_needed(container) + else + #modify by nwb + if @project + @addTag=false + container = (params[:version_id].blank? ? @project : @project.versions.find_by_id(params[:version_id])) + attachments = Attachment.attach_filesex(container, params[:attachments], params[:attachment_type]) + render_attachment_warning_if_needed(container) - if !attachments.empty? && !attachments[:files].blank? && Setting.notified_events.include?('file_added') - Mailer.attachments_added(attachments[:files]).deliver - end + if !attachments.empty? && !attachments[:files].blank? && Setting.notified_events.include?('file_added') + Mailer.attachments_added(attachments[:files]).deliver + end - # TODO: 临时用 nyan - sort_init 'created_on', 'desc' - sort_update 'created_on' => "#{Attachment.table_name}.created_on", - 'filename' => "#{Attachment.table_name}.filename", - 'size' => "#{Attachment.table_name}.filesize", - 'downloads' => "#{Attachment.table_name}.downloads" + # TODO: 临时用 nyan + sort_init 'created_on', 'desc' + sort_update 'created_on' => "#{Attachment.table_name}.created_on", + 'filename' => "#{Attachment.table_name}.filename", + 'size' => "#{Attachment.table_name}.filesize", + 'downloads' => "#{Attachment.table_name}.downloads" - @containers = [ Project.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").find(@project.id)] #modify by Long Jun - @containers += @project.versions.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").all.sort + @containers = [Project.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").find(@project.id)] #modify by Long Jun + @containers += @project.versions.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").all.sort - @attachtype = 0 - @contenttype = 0 + @attachtype = 0 + @contenttype = 0 - respond_to do |format| - format.js - format.html { - redirect_to project_files_path(@project) - } - end + respond_to do |format| + format.js + format.html { + redirect_to project_files_path(@project) + } + end + elsif @course + @addTag=false + attachments = Attachment.attach_filesex(@course, params[:attachments], params[:attachment_type]) - end + if !attachments.empty? && !attachments[:files].blank? && Setting.notified_events.include?('file_added') + Mailer.attachments_added(attachments[:files]).deliver + end + + # TODO: 临时用 nyan + sort_init 'created_on', 'desc' + sort_update 'created_on' => "#{Attachment.table_name}.created_on", + 'filename' => "#{Attachment.table_name}.filename", + 'size' => "#{Attachment.table_name}.filesize", + 'downloads' => "#{Attachment.table_name}.downloads" + + @containers = [Course.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").find(@course.id)] + + @attachtype = 0 + @contenttype = 0 + + respond_to do |format| + format.js + format.html { + redirect_to course_files_path(@course) + } + end + end + + end end def tag_saveEx @@ -115,6 +146,8 @@ class FilesController < ApplicationController @obj = Contest.find_by_id(@obj_id) when '8' @obj = OpenSourceProject.find_by_id(@obj_id) + when '9' + @obj = Course.find_by_id(@obj_id) else @obj = nil end @@ -131,16 +164,21 @@ class FilesController < ApplicationController end # 返回制定资源类型的资源列表 + # added by nwb def getattachtype sort_init 'created_on', 'desc' sort_update 'created_on' => "#{Attachment.table_name}.created_on", 'filename' => "#{Attachment.table_name}.filename", 'size' => "#{Attachment.table_name}.filesize", 'downloads' => "#{Attachment.table_name}.downloads" - - @containers = [ Project.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").find(@project.id)] #modify by Long Jun - @containers += @project.versions.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").all.sort - + + if @project + @containers = [ Project.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").find(@project.id)] + @containers += @project.versions.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").all.sort + elsif @course + @containers = [ Course.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").find(@course.id)] + end + @attachtype = params[:type].to_i @contenttype = params[:contentType].to_s diff --git a/app/controllers/forums_controller.rb b/app/controllers/forums_controller.rb index 991af0154..f3ebfad88 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 64bfe5c40..83a6aa05f 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 cb55d965d..5f473b421 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 a716653a5..9803eb789 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 3a4b219bb..183a1ea52 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 30c6c7e80..5ddebe707 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 b4de06fb6..62f860a96 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 150071b41..2915ff8f8 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 a87df4fef..9b169cb81 100644 --- a/app/controllers/my_controller.rb +++ b/app/controllers/my_controller.rb @@ -61,7 +61,7 @@ class MyController < ApplicationController end end - @se = @user.user_extensions ||= UserExtensions.new + @se = @user.extensions @se.school_id = params[:occupation] if params[:occupation] @se.gender = params[:gender] @se.location = params[:province] if params[:province] diff --git a/app/controllers/news_controller.rb b/app/controllers/news_controller.rb index ee3db741d..8bce84f90 100644 --- a/app/controllers/news_controller.rb +++ b/app/controllers/news_controller.rb @@ -38,37 +38,62 @@ class NewsController < ApplicationController @limit = 10 end - scope = @project ? @project.news.visible : News.visible - - @news_count = scope.count - @news_pages = Paginator.new @news_count, @limit, params['page'] - @offset ||= @news_pages.offset - @newss = scope.all(:include => [:author, :project], - :order => "#{News.table_name}.created_on DESC", - :offset => @offset, - :limit => @limit) - - respond_to do |format| - format.html { - @news = News.new # for adding news inline - # huang - - if @project.project_type == 1 - render :layout => 'base_courses' - else - render :layout => false if request.xhr? - end - } - format.api - format.atom { render_feed(@newss, :title => (@project ? @project.name : Setting.app_title) + ": #{l(:label_news_plural)}") } + # modify by nwb + if params[:course_id] && @course==nil + @course = Course.find(params[:course_id]) end - end + if @project + scope = @project ? @project.news.visible : News.visible + + @news_count = scope.count + @news_pages = Paginator.new @news_count, @limit, params['page'] + @offset ||= @news_pages.offset + @newss = scope.all(:include => [:author, :project], + :order => "#{News.table_name}.created_on DESC", + :offset => @offset, + :limit => @limit) + + respond_to do |format| + format.html { + @news = News.new # for adding news inline + # huang + + render :layout => false if request.xhr? + } + format.api + format.atom { render_feed(@newss, :title => (@project ? @project.name : Setting.app_title) + ": #{l(:label_news_plural)}") } + end + elsif @course + scope = @course ? @course.news.course_visible : News.course_visible + + @news_count = scope.count + @news_pages = Paginator.new @news_count, @limit, params['page'] + @offset ||= @news_pages.offset + @newss = scope.all(:include => [:author, :course], + :order => "#{News.table_name}.created_on DESC", + :offset => @offset, + :limit => @limit) + + respond_to do |format| + format.html { + @news = News.new + render :layout => 'base_courses' + } + format.api + format.atom { render_feed(@newss, :title => (@course ? @course.name : Setting.app_title) + ": #{l(:label_news_plural)}") } + end + end + end def show @comments = @news.comments - @comments.reverse! if User.current.wants_comments_in_reverse_order? - if @project.project_type == 1 - render :layout => 'base_courses' + @comments.reverse! if User.current.wants_comments_in_reverse_order? + #modify by nwb + if @news.course_id + @course = Course.find(@news.course_id) + if @course + render :layout => 'base_courses' + end end end @@ -81,16 +106,31 @@ class NewsController < ApplicationController end def create - @news = News.new(:project => @project, :author => User.current) - @news.safe_attributes = params[:news] - @news.save_attachments(params[:attachments]) - if @news.save - render_attachment_warning_if_needed(@news) - flash[:notice] = l(:notice_successful_create) - redirect_to project_news_index_path(@project) - else - layout_file = (@project.project_type == 1) ? 'base_courses' : 'base_projects' - render :action => 'new', :layout => layout_file + #modify by nwb + if @project + @news = News.new(:project => @project, :author => User.current) + @news.safe_attributes = params[:news] + @news.save_attachments(params[:attachments]) + if @news.save + render_attachment_warning_if_needed(@news) + flash[:notice] = l(:notice_successful_create) + redirect_to project_news_index_path(@project) + else + layout_file = @project ? 'base_projects' : 'base_courses' + render :action => 'new', :layout => layout_file + end + elsif @course + @news = News.new(:course => @course, :author => User.current) + @news.safe_attributes = params[:news] + @news.save_attachments(params[:attachments]) + if @news.save + render_attachment_warning_if_needed(@news) + flash[:notice] = l(:notice_successful_create) + redirect_to course_news_index_path(@course) + else + layout_file = 'base_courses' + render :action => 'new', :layout => layout_file + end end end @@ -111,7 +151,13 @@ class NewsController < ApplicationController def destroy @news.destroy - redirect_to project_news_index_path(@project) + # modify by nwb + if @project + redirect_to project_news_index_path(@project) + elsif @course + redirect_to course_news_index_path(@course) + end + end private diff --git a/app/controllers/notificationcomments_controller.rb b/app/controllers/notificationcomments_controller.rb new file mode 100644 index 000000000..80500ab10 --- /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 53df54e9f..acfd785d9 100644 --- a/app/controllers/praise_tread_controller.rb +++ b/app/controllers/praise_tread_controller.rb @@ -9,8 +9,12 @@ class PraiseTreadController < ApplicationController if request.get? @obj_id = params[:obj_id] @obj_type = params[:obj_type] + @horizontal = params[:horizontal].downcase == "false" ? false:true @obj = find_object_by_type_and_id(@obj_type,@obj_id) - praise_tread_plus(@obj_type,@obj_id,1) + unless @obj.author_id == User.current.id + praise_tread_plus(@obj_type,@obj_id,1) + end + end end @@ -44,8 +48,12 @@ class PraiseTreadController < ApplicationController if request.get? @obj_id = params[:obj_id] @obj_type = params[:obj_type] + @horizontal = params[:horizontal].downcase == "false" ? false:true @obj = find_object_by_type_and_id(@obj_type,@obj_id) - praise_tread_plus(@obj_type,@obj_id,0) + unless @obj.author_id == User.current.id + praise_tread_plus(@obj_type,@obj_id,0) + end + end end @@ -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 0083116d2..579f8caa8 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 16d9d71d4..9639c9d00 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 70f7572a8..3b97802f5 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -568,7 +568,7 @@ class RepositoriesController < ApplicationController project = Project.find(params[:id]) if !User.current.member_of?(project) if project.hidden_repo - render_403 + #render_403 end end rescue ActiveRecord::RecordNotFound diff --git a/app/controllers/school_controller.rb b/app/controllers/school_controller.rb index ec14ba5c8..c8b495fe2 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 b8d81b108..362a04f57 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 84c3aff0f..ba01aa990 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 6452bcc81..1c2db7f79 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 49e32ba17..0bbbd1bd6 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 b1fbfb8ea..50bb2ccd8 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 c662c44f7..3e708b94a 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 bfc1eacb4..a4f53c100 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 57078a436..33a569f5d 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 7bfe95123..c9dc4fa26 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 aa6a5f7f5..3e61b2a44 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 abaa79504..2ebdae0c8 100644 --- a/app/helpers/avatar_helper.rb +++ b/app/helpers/avatar_helper.rb @@ -42,7 +42,7 @@ module AvatarHelper end def get_avatar?(source) - if File.exist?(disk_filename(source.class,source.id)) + if source && File.exist?(disk_filename(source.class,source.id)) return true else return false diff --git a/app/helpers/bids_helper.rb b/app/helpers/bids_helper.rb index 8b03d74cd..a5c25ecb5 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 84b979c44..341de8932 100644 --- a/app/helpers/boards_helper.rb +++ b/app/helpers/boards_helper.rb @@ -29,6 +29,19 @@ module BoardsHelper breadcrumb links end + # add by nwb + def course_board_breadcrumb(item) + board = item.is_a?(Message) ? item.board : item + links = [link_to(l(:label_board_plural), course_boards_path(item.course))] + boards = board.ancestors.reverse + if item.is_a?(Message) + boards << board + end + links += boards.map {|ancestor| link_to(h(ancestor.name), course_board_path(ancestor.course, ancestor))} + breadcrumb links + end + + def boards_options_for_select(boards) options = [] Board.board_tree(boards) do |board, level| diff --git a/app/helpers/contestnotifications_helper.rb b/app/helpers/contestnotifications_helper.rb new file mode 100644 index 000000000..ab17149d7 --- /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 8206a8ff0..184fc7c40 100644 --- a/app/helpers/contests_helper.rb +++ b/app/helpers/contests_helper.rb @@ -55,8 +55,9 @@ module ContestsHelper content_tag('div', content, :class => "tabs_enterprise") end #end - - + + + #huang def sort_contest(state) content = ''.html_safe diff --git a/app/helpers/courses_helper.rb b/app/helpers/courses_helper.rb index 959d36cb0..80beea16c 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 000000000..3510dc783 --- /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 480524457..cfebb4d30 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 91e05d6a8..134b7c007 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 000000000..2d90bfe32 --- /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 a42a626dc..c859fec23 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 f2cbc6ab9..9e0828133 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 201a582f2..8e9e6bbb9 100644 --- a/app/helpers/tags_helper.rb +++ b/app/helpers/tags_helper.rb @@ -16,6 +16,8 @@ module TagsHelper @obj = Attachment.find_by_id(obj_id) when '7' @obj= Contest.find_by_id(obj_id) + when '9' + @obj= Course.find_by_id(obj_id) else raise Exception, '[TagsHelper] ===> tag type unknow.' end @@ -46,6 +48,8 @@ module TagsHelper if user.id == obj_id @result = true end + when '9' + @result = is_course_manager?(user.id,obj_id) end return @result end diff --git a/app/helpers/user_score_helper.rb b/app/helpers/user_score_helper.rb index d9ab8730a..3101b823c 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 87b495f00..e65fe174e 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 50170ee9e..ea72e8184 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 330010212..4ff5a48e4 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 aff63439e..116e2de9a 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 e58e640a0..f65d71fa8 100644 --- a/app/models/bid.rb +++ b/app/models/bid.rb @@ -22,11 +22,11 @@ class Bid < ActiveRecord::Base belongs_to :course has_many :biding_projects, :dependent => :destroy has_many :projects, :through => :biding_projects - has_many :projects_member, :class_name => 'User', :through => :projects + has_many :courses_member, :class_name => 'User', :through => :courses has_many :journals_for_messages, :as => :jour, :dependent => :destroy has_many :acts, :class_name => 'Activity', :as => :act, :dependent => :destroy has_many :homework_for_courses, :dependent => :destroy - has_many :courses, :through => :homework_for_courses, :source => :project + has_many :courses, :through => :homework_for_courses, :source => :course has_many :homeworks, :class_name => 'HomeworkAttach', :dependent => :destroy has_many :join_in_contests, :dependent => :destroy has_many :praise_tread, as: :praise_tread_object, dependent: :destroy diff --git a/app/models/board.rb b/app/models/board.rb index cb81e0a5a..b51790e19 100644 --- a/app/models/board.rb +++ b/app/models/board.rb @@ -18,6 +18,7 @@ class Board < ActiveRecord::Base include Redmine::SafeAttributes belongs_to :project + belongs_to :course has_many :topics, :class_name => 'Message', :conditions => "#{Message.table_name}.parent_id IS NULL", :order => "#{Message.table_name}.created_on DESC" has_many :messages, :dependent => :destroy, :order => "#{Message.table_name}.created_on DESC" belongs_to :last_message, :class_name => 'Message', :foreign_key => :last_message_id diff --git a/app/models/changeset.rb b/app/models/changeset.rb index e3e7ac705..a56dee691 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 9a3268654..e1706b166 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 000000000..0bda49548 --- /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 de383a1f5..5034ab0d8 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 000000000..6478b383a --- /dev/null +++ b/app/models/course_infos.rb @@ -0,0 +1,5 @@ +class CourseInfos < ActiveRecord::Base + attr_accessible :user_id, :course_id + belongs_to :user + belongs_to :course +end diff --git a/app/models/course_status.rb b/app/models/course_status.rb new file mode 100644 index 000000000..b36661ebe --- /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 0c2ce1736..7c2730682 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 e6b16df39..cd9c210dd 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 ad59d107d..99d540bd1 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 7a440449a..59fd7ba1e 100644 --- a/app/models/homework_for_course.rb +++ b/app/models/homework_for_course.rb @@ -1,8 +1,8 @@ class HomeworkForCourse < ActiveRecord::Base - attr_accessible :bid_id, :project_id + attr_accessible :bid_id, :course_id belongs_to :bid - belongs_to :project + belongs_to :course end diff --git a/app/models/homework_user.rb b/app/models/homework_user.rb index 0adef62c4..df75ef821 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 7e899eafc..550e0dc5d 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 0997640d8..2e9363dd7 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 7356b7373..9551ff28b 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 e0ad54296..ef4996eac 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 de4d67687..46aefbd09 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -22,9 +22,10 @@ class Member < ActiveRecord::Base has_many :roles, :through => :member_roles belongs_to :project + belongs_to :course - validates_presence_of :principal, :project - validates_uniqueness_of :user_id, :scope => :project_id + validates_presence_of :principal + validates_uniqueness_of :user_id, :scope => [:project_id,:course_id] validate :validate_role before_destroy :set_issue_category_nil @@ -85,7 +86,13 @@ class Member < ActiveRecord::Base def set_issue_category_nil if user # remove category based auto assignments for this member - IssueCategory.update_all "assigned_to_id = NULL", ["project_id = ? AND assigned_to_id = ?", project.id, user.id] + #modify by nwb + if project + IssueCategory.update_all "assigned_to_id = NULL", ["project_id = ? AND assigned_to_id = ?", project.id, user.id] + elsif course + #IssueCategory.update_all "assigned_to_id = NULL", ["course_id = ? AND assigned_to_id = ?", course.id, user.id] + end + end end diff --git a/app/models/member_role.rb b/app/models/member_role.rb index 29ad6563d..67122a636 100644 --- a/app/models/member_role.rb +++ b/app/models/member_role.rb @@ -54,14 +54,16 @@ class MemberRole < ActiveRecord::Base end def add_role_to_subprojects - member.project.children.each do |subproject| - if subproject.inherit_members? - child_member = Member.find_or_new(subproject.id, member.user_id) - child_member.member_roles << MemberRole.new(:role => role, :inherited_from => id) - child_member.save! + if member.project + member.project.children.each do |subproject| + if subproject.inherit_members? + child_member = Member.find_or_new(subproject.id, member.user_id) + child_member.member_roles << MemberRole.new(:role => role, :inherited_from => id) + child_member.save! + end end end - end + end def remove_inherited_roles MemberRole.where(:inherited_from => id).all.group_by(&:member).each do |member, member_roles| diff --git a/app/models/memo.rb b/app/models/memo.rb index a0581d945..feb10dec9 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 2421a7d4f..faf7e5bdf 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -31,6 +31,10 @@ class Message < ActiveRecord::Base :include => {:board => :project}, :project_key => "#{Board.table_name}.project_id", :date_column => "#{table_name}.created_on" + acts_as_searchable :columns => ['subject', 'content'], + :include => {:board => :course}, + :course_key => "#{Board.table_name}.course_id", + :date_column => "#{table_name}.created_at" acts_as_event :title => Proc.new {|o| "#{o.board.name}: #{o.subject}"}, :description => :content, :datetime => :updated_on, @@ -42,6 +46,9 @@ class Message < ActiveRecord::Base acts_as_activity_provider :find_options => {:include => [{:board => :project}, :author]}, :author_key => :author_id + acts_as_activity_provider :find_options => {:include => [{:board => :course}, :author]}, + :type => 'course_messages', + :author_key => :author_id acts_as_watchable validates_presence_of :board, :subject, :content @@ -53,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 f2dba2f8e..9a0f8b75c 100644 --- a/app/models/news.rb +++ b/app/models/news.rb @@ -18,6 +18,8 @@ class News < ActiveRecord::Base include Redmine::SafeAttributes belongs_to :project + #added by nwb + belongs_to :course belongs_to :author, :class_name => 'User', :foreign_key => 'author_id' has_many :comments, :as => :commented, :dependent => :delete_all, :order => "created_on" # fq @@ -33,6 +35,11 @@ class News < ActiveRecord::Base acts_as_event :url => Proc.new {|o| {:controller => 'news', :action => 'show', :id => o.id}} acts_as_activity_provider :find_options => {:include => [:project, :author]}, :author_key => :author_id + #added by nwb + #课程新闻独立于项目 + acts_as_activity_provider :type => 'course_news', + :find_options => {:include => [:course, :author]}, + :author_key => :author_id acts_as_watchable after_create :add_author_as_watcher @@ -44,6 +51,9 @@ class News < ActiveRecord::Base includes(:project).where(Project.allowed_to_condition(args.shift || User.current, :view_news, *args)) } + scope :course_visible, lambda {|*args| + includes(:course).where(Course.allowed_to_condition(args.shift || User.current, :view_course_news, *args)) + } safe_attributes 'title', 'summary', 'description' def visible?(user=User.current) diff --git a/app/models/notificationcomment.rb b/app/models/notificationcomment.rb new file mode 100644 index 000000000..9cc658f22 --- /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 c27e1fc9f..98253d837 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 15cebdf53..024480635 100644 --- a/app/models/principal.rb +++ b/app/models/principal.rb @@ -26,7 +26,10 @@ class Principal < ActiveRecord::Base has_many :members, :foreign_key => 'user_id', :dependent => :destroy has_many :memberships, :class_name => 'Member', :foreign_key => 'user_id', :include => [ :project, :roles ], :conditions => "#{Project.table_name}.status<>#{Project::STATUS_ARCHIVED}", :order => "#{Project.table_name}.name" + has_many :coursememberships, :class_name => 'Member', :foreign_key => 'user_id', :include => [ :course, :roles ], :conditions => "#{Course.table_name}.status<>#{Course::STATUS_ARCHIVED}", :order => "#{Course.table_name}.name" has_many :projects, :through => :memberships + #add by nwb + has_many :courses, :through => :coursememberships has_many :issue_categories, :foreign_key => 'assigned_to_id', :dependent => :nullify # Groups and active users @@ -70,6 +73,17 @@ class Principal < ActiveRecord::Base where("#{Principal.table_name}.id NOT IN (SELECT DISTINCT user_id FROM #{Member.table_name} WHERE project_id IN (?))", ids) end } + + scope :not_member_of_course, lambda {|courses| + courses = [courses] unless courses.is_a?(Array) + if courses.empty? + where("1=0") + else + ids = courses.map(&:id) + where("#{Principal.table_name}.id NOT IN (SELECT DISTINCT user_id FROM #{Member.table_name} WHERE course_id IN (?))", ids) + end + } + scope :sorted, lambda { order(*Principal.fields_for_order_statement)} scope :applied_members, lambda {|project| diff --git a/app/models/project.rb b/app/models/project.rb index b8e11d99e..5efaf10ab 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 c6edab81c..d22bf7cfd 100644 --- a/app/models/project_info.rb +++ b/app/models/project_info.rb @@ -5,7 +5,7 @@ class ProjectInfo < ActiveRecord::Base belongs_to :user validates_presence_of :project_id, :user_id validates_uniqueness_of :project_id, :scope => :user_id - + after_save :update_user_level def self.manager? (user_id, project) for project_info in project.project_infos if project_info.user_id == user_id @@ -14,4 +14,9 @@ class ProjectInfo < ActiveRecord::Base end return false end + + #更新用户等级 + def update_user_level + UserLevels.update_user_level(self.user) + end end diff --git a/app/models/repository.rb b/app/models/repository.rb index bcd3366cb..57a818270 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 2902325d3..cba219d0d 100644 --- a/app/models/role.rb +++ b/app/models/role.rb @@ -151,7 +151,7 @@ class Role < ActiveRecord::Base if action.is_a? Hash allowed_actions.include? "#{action[:controller]}/#{action[:action]}" else - allowed_permissions.include? action + allowed_permissions.include? action end end diff --git a/app/models/students_for_course.rb b/app/models/students_for_course.rb index 597d74da6..6958cfe73 100644 --- a/app/models/students_for_course.rb +++ b/app/models/students_for_course.rb @@ -1,7 +1,8 @@ class StudentsForCourse < ActiveRecord::Base attr_accessible :course_id, :student_id - belongs_to :course, :class_name => 'Project', :foreign_key => :course_id + belongs_to :course, :class_name => 'Course', :foreign_key => :course_id + belongs_to :student, :class_name => 'User', :foreign_key => :student_id validates_presence_of :course_id, :student_id diff --git a/app/models/user.rb b/app/models/user.rb index edf703873..257681cb5 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 ea951eadd..074aa516a 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 000000000..a24738a2f --- /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 5b95386be..e0a541804 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 000000000..6371fc12d --- /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 000000000..61d5d098e --- /dev/null +++ b/app/models/user_score_details.rb @@ -0,0 +1,4 @@ +class UserScoreDetails < ActiveRecord::Base + attr_accessible :current_user_id, :current_user_level, :new_score, :old_score, :score_action, :score_changeable_obj_id, :score_changeable_obj_type, :score_type, :target_user_id, :target_user_level, :user_id + belongs_to :score_changeable_obj,:polymorphic => true +end diff --git a/app/models/watcher.rb b/app/models/watcher.rb index f700e62ac..e2e255a1e 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 cc7a26ad8..fac05e6de 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 000000000..f0bebaf89 --- /dev/null +++ b/app/views/attachments/_course_type_edit.html.erb @@ -0,0 +1,14 @@ +<% edit_allowed = User.current.allowed_to?(:manage_files, @course) %> +<% if attachmenttypes.any? %> + + <%= link_to(image_tag('edit/edit.png'), 'javascript:void(0);',:style=>"white-space:nowrap;", :id=>"edit_box"+attachment.id.to_s , + :onclick =>"$('#put-tag-form-" +attachment.id.to_s+ "').show(); + $('#attach_type_id_label" +attachment.id.to_s+ "').hide(); + $('#edit_box" +attachment.id.to_s+ "').hide();") if edit_allowed %> + +<% end %> + diff --git a/app/views/attachments/_links.html.erb b/app/views/attachments/_links.html.erb index f73df8fb4..52b090bd8 100644 --- a/app/views/attachments/_links.html.erb +++ b/app/views/attachments/_links.html.erb @@ -24,7 +24,8 @@ <% end %> <% end %> <% if options[:author] %> - <%= h(attachment.author) %>, <%= format_time(attachment.created_on) %> + + <%= link_to h(attachment.author),user_path(attachment.author) %>, <%= format_time(attachment.created_on) %> <% end %>

    <% end %> @@ -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 000000000..c5a3661da --- /dev/null +++ b/app/views/attachments/_temp.html.erb @@ -0,0 +1,3 @@ +
    + <%= render :partial => 'tags/tagEx', :locals => {:obj => file, :object_flag => "6"} %> +
    \ No newline at end of file diff --git a/app/views/attachments/add_exist_file_to_course.js.erb b/app/views/attachments/add_exist_file_to_course.js.erb new file mode 100644 index 000000000..58e5690ef --- /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 784128ea1..404ad9a61 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 63600619b..24256ccab 100644 --- a/app/views/attachments/upload.js.erb +++ b/app/views/attachments/upload.js.erb @@ -11,6 +11,6 @@ fileSpan.find('a.remove-upload') "href": '<%= j attachment_path(@attachment, :attachment_id => params[:attachment_id], :format => 'js') %>' }) .off('click'); -var divattach = fileSpan.find('div.div_attachments'); -divattach.html('<%= j(render :partial => 'tags/tagEx', :locals => {:obj => @attachment, :object_flag => "6"})%>'); +//var divattach = fileSpan.find('div.div_attachments'); +//divattach.html('<%= j(render :partial => 'tags/tagEx', :locals => {:obj => @attachment, :object_flag => "6"})%>'); <% end %> diff --git a/app/views/avatar/_avatar_form.html.erb b/app/views/avatar/_avatar_form.html.erb index fc55bd2ef..272397c62 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 000000000..d61f4ef87 --- /dev/null +++ b/app/views/bids/_app_link.html.erb @@ -0,0 +1,24 @@ + + + <% count = 0 %> + <% for attachment in attachments %> + <% if attachments.count == 1 %> + + <% elsif attachments.count == 2 %> + + <% else %> + + <% end %> + <% end %> + +
    + <%= render :partial => 'attachment', :locals => {:attachment => attachment} %> + + <%= render :partial => 'attachment', :locals => {:attachment => attachment} %> + + <% if count == 3 %> + <% break %> + <% end %> + <%= render :partial => 'attachment', :locals => {:attachment => attachment} %> + <% count = count +1 %> +
    \ No newline at end of file diff --git a/app/views/bids/_attachment.html.erb b/app/views/bids/_attachment.html.erb new file mode 100644 index 000000000..6bccc08f5 --- /dev/null +++ b/app/views/bids/_attachment.html.erb @@ -0,0 +1,6 @@ +<%= link_to_attachment attachment, :class => 'icon icon-attachment', :download => true -%> +<% if attachment.is_text? %> + <%= link_to image_tag('magnifier.png'), + :controller => 'attachments', :action => 'show', + :id => attachment, :filename => attachment.filename,:style => "width:50px"%> +<% end %> \ No newline at end of file diff --git a/app/views/bids/_bid_homework_show.html.erb b/app/views/bids/_bid_homework_show.html.erb index 3ef55c567..d452b6d53 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 8d3ffec18..47f1560dd 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 ea110473c..3fcf0f02e 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 eb6b9bbf5..f3578e713 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 5aa3462fa..92b162035 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 aa4140f95..9f6b45dbd 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 000000000..039de6b7a --- /dev/null +++ b/app/views/bids/show_courseEx.html.erb @@ -0,0 +1,72 @@ +<% if @bid.homework_type == Bid::HomeworkFile %> + + <%= render :partial => 'homework' %> + +<% else %> + + + <% if User.current.logged? %> + + +
    <%= 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 dd10f7b1b..bd069c8c8 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 8b7e0d8ea..96ed4ea75 100644 --- a/app/views/bids/show.html.erb +++ b/app/views/bids/show.html.erb @@ -2,7 +2,7 @@
    <%= image_tag(url_to_avatar(@bid.author), :class => "avatar")%> -

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

    +

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

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

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

    - @@ -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 c14d2e14c..039de6b7a 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 000000000..30d5f0106 --- /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 000000000..eea4cc204 --- /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 48a5ed328..10086e5a3 100644 --- a/app/views/contests/_list_projects.html.erb +++ b/app/views/contests/_list_projects.html.erb @@ -76,7 +76,8 @@ <%= l(:label_contest_user) %> <% unless c_project.user.nil? %> - <%= c_project.user.lastname %><%= c_project.user.firstname %> + + <%= link_to c_project.user.lastname + c_project.user.firstname,user_path(c_project.user) %> <% end %> diff --git a/app/views/contests/index.html.erb b/app/views/contests/index.html.erb index 670ba27cf..8c999f941 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 8a567bd53..ecdfd5ac5 100644 --- a/app/views/contests/show_attendingcontest.html.erb +++ b/app/views/contests/show_attendingcontest.html.erb @@ -259,7 +259,10 @@ <%= l(:label_attendingcontest_time) %> :<%= format_time c_project.created_at %> <%= l(:label_attendingcontest_spoksman) %> - :<%= c_project.user.name %> + + <% unless c_project.nil? || c_project.user.nil? %> + :<%= link_to c_project.user.name,user_path(c_project.user) %>
    + <% end %>
    @@ -293,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 67414b0c8..c379bc668 100644 --- a/app/views/contests/show_contest.html.erb +++ b/app/views/contests/show_contest.html.erb @@ -15,7 +15,7 @@
    <%= render :partial => "/praise_tread/praise_tread", - :locals => {:obj => @contest,:show_flag => true,:user_id =>User.current.id}%> + :locals => {:obj => @contest,:show_flag => true,:user_id =>User.current.id,:horizontal => false}%>
    diff --git a/app/views/courses/_course.html.erb b/app/views/courses/_course.html.erb new file mode 100644 index 000000000..ef8f37566 --- /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 017c4e6ee..2e7607bbf 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 000000000..92f59f85e --- /dev/null +++ b/app/views/courses/_edit.html.erb @@ -0,0 +1,6 @@ +
    +<%= labelled_form_for @course do |f| %> + <%= render :partial => 'course_form', :locals => { :f => f } %> + <%= submit_tag l(:button_save) %> +<% end %> +
    diff --git a/app/views/projects/_homework_form.html.erb b/app/views/courses/_homework_form.html.erb similarity index 63% rename from app/views/projects/_homework_form.html.erb rename to app/views/courses/_homework_form.html.erb index e4a471367..41c059603 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 000000000..a8a9e8085 --- /dev/null +++ b/app/views/courses/_member_list.html.erb @@ -0,0 +1,35 @@ +<% if members.any? %> + <% members.each do |member| %> +
    + <% next if member.new_record? %> + <% unless member.created_on.nil? %> + <%= content_tag "p", "#{format_date(member.created_on)}#{l(:label_member_since)}", :class => "float_right member_since" %> + <% end %> + <%= member.user.nil? ? '' : (image_tag(url_to_avatar(member.user), :class => 'avatar')) %> + <% if @canShowCode %> + <%= content_tag "div", link_to(member.user.show_name, user_path(member.user)), :class => "nomargin avatar_name" %> + <% else %> + <%= content_tag "div", link_to(member.user.name, user_path(member.user)), :class => "nomargin avatar_name" %> + <% end %> + + + <% unless member.user.user_extensions.identity ==0 %> + + <%if @canShowCode%> + <%= content_tag "p", "#{l(:label_bidding_user_studentcode)}#{' : '}#{member.user.user_extensions.student_id}", :class => "nomargin avatar_name" %> + <% end %> + <% end %> +
      +

    +

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

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

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

    <%= l(:label_user_response) %>

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

    文件列表

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

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

    +

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

    上传作业

    diff --git a/app/views/courses/index.html.erb b/app/views/courses/index.html.erb new file mode 100644 index 000000000..db94cf6c5 --- /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 000000000..3d3076bcc --- /dev/null +++ b/app/views/courses/member.html.erb @@ -0,0 +1,10 @@ +
    +

    + <%= @subPage_title %> +

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

    <%=l(:label_course_new)%>

    +
    + <%= render :partial => 'course_form', :locals => { :f => f } %> + <%= submit_tag l(:button_create), :class => "enterprise"%> + + <%= javascript_tag "$('#course_name').focus();" %> +
    +<% end %> diff --git a/app/views/projects/new_homework.html.erb b/app/views/courses/new_homework.html.erb similarity index 76% rename from app/views/projects/new_homework.html.erb rename to app/views/courses/new_homework.html.erb index e1fd553b0..b3fff9e5f 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 000000000..c0a6f4a50 --- /dev/null +++ b/app/views/courses/new_join.js.erb @@ -0,0 +1,3 @@ +$('#ajax-modal').html('<%= escape_javascript(render :partial => 'projects/new_join', :locals => {:course => @course}) %>'); +showModal('ajax-modal', '400px'); +$('#ajax-modal').addClass('new-watcher'); diff --git a/app/views/courses/search.html.erb b/app/views/courses/search.html.erb new file mode 100644 index 000000000..25b45e0db --- /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 000000000..c2030ffec --- /dev/null +++ b/app/views/courses/settings.html.erb @@ -0,0 +1,3 @@ +

    <%=l(:label_settings)%>

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

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

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

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

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

    <%= l(:label_no_data) %>

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

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

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

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

    + +

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

    +
    + <% end %> + <% end %> +
    diff --git a/app/views/courses/show.html.erb b/app/views/courses/show.html.erb new file mode 100644 index 000000000..f0cc62140 --- /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 38ed88192..d626fe30c 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 000000000..d9913539f --- /dev/null +++ b/app/views/files/_course_file.html.erb @@ -0,0 +1,71 @@ + +<% attachmenttypes = @course.attachmenttypes %> +<% sufixtypes = @course.contenttypes %> + +<%= t(:label_user_course) %>资源共享区 + +
    + + <%#= link_to(l(:label_attachment_new), 'javascript:void(0);', :onclick=>"$('#file_buttons').slideToggle();", :class => 'icon icon-add') if User.current.allowed_to?(:manage_files, @course) %> +
    +
    + <%= link_to(l(:label_upload_files), 'javascript:void(0);', :class => 'icon m5p5 button_submit', :onclick => "$('#relation_file_div').slideUp();$('#upload_file_div').slideToggle('slow');") if User.current.allowed_to?(:manage_files, @course) %> + <%= link_to(l(:label_relation_files), 'javascript:void(0);', :onclick => "$('#upload_file_div').slideUp();$('#relation_file_div').slideToggle();", :class => 'icon m5p5 button_submit') if User.current.allowed_to?(:manage_files, @course) %> + + <% if attachmenttypes.any? %> +       + + <%= select_tag "attachment_browse", content_tag(:option, l(:attachment_all), :value => '0') +options_from_collection_for_select(attachmenttypes, "id", "typeName"), + :onchange => "course_attachmenttypes_searchex(this.value)" %> + <% end %> + <% if sufixtypes.any? %> +   + + <%= select_tag "attach_sufix_browse", content_tag(:option, l(:attachment_all), :value => '0') +options_for_select(sufixtypes), + :onchange => "course_attachment_contenttypes_searchex(this.value)" %> + <% end %> + + + + +
    + +
    +<%= javascript_tag "observeSearchfield('attach_search', null, '#{ escape_javascript attachments_autocomplete_path(:course_id => @course.id, :format => 'js') }')" %> + + +<% delete_allowed = User.current.allowed_to?(:manage_files, @course) %> + +
    + <%= render :partial => 'course_show_all_attachment' %> +
    + +<% html_title(l(:label_attachment_plural)) -%> \ No newline at end of file diff --git a/app/views/files/_course_new.html.erb b/app/views/files/_course_new.html.erb new file mode 100644 index 000000000..960b2d399 --- /dev/null +++ b/app/views/files/_course_new.html.erb @@ -0,0 +1,41 @@ +

    <%=l(:label_attachment_new)%>

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

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

    + +

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

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

    + + <%#= link_to(l(:label_attachment_new), 'javascript:void(0);', :onclick=>"$('#file_buttons').slideToggle();", :class => 'icon icon-add') if User.current.allowed_to?(:manage_files, @project) %> +
    +
    + <%= link_to(l(:label_upload_files), 'javascript:void(0);', :class => 'icon m5p5 button_submit', :onclick => "$('#relation_file_div').slideUp();$('#upload_file_div').slideToggle('slow');") if User.current.allowed_to?(:manage_files, @project) %> + <%= link_to(l(:label_relation_files), 'javascript:void(0);', :onclick => "$('#upload_file_div').slideUp();$('#relation_file_div').slideToggle();", :class => 'icon m5p5 button_submit') if User.current.allowed_to?(:manage_files, @project) %> + + <% if attachmenttypes.any? %> +       + + <%= select_tag "attachment_browse", content_tag(:option, l(:attachment_all), :value => '0') +options_from_collection_for_select(attachmenttypes, "id", "typeName"), + :onchange => "attachmenttypes_searchex(this.value)" %> + <% end %> + <% if sufixtypes.any? %> +   + + <%= select_tag "attach_sufix_browse", content_tag(:option, l(:attachment_all), :value => '0') +options_for_select(sufixtypes), + :onchange => "attachment_contenttypes_searchex(this.value)" %> + <% end %> + + + + +
    + +
    +<%= javascript_tag "observeSearchfield('attach_search', null, '#{ escape_javascript attachments_autocomplete_path(:project_id => @project.id, :format => 'js') }')" %> + + +<% delete_allowed = User.current.allowed_to?(:manage_files, @project) %> + +
    + <%= render :partial => 'show_all_attachment' %> +
    + +<% html_title(l(:label_attachment_plural)) -%> \ No newline at end of file diff --git a/app/views/files/create.js.erb b/app/views/files/create.js.erb new file mode 100644 index 000000000..0eca9c1ed --- /dev/null +++ b/app/views/files/create.js.erb @@ -0,0 +1,32 @@ +<%if @addTag%> +<% if @obj_flag == '3'%> + +$('#tags_show_issue').html('<%= escape_javascript(render :partial => 'tags/tag_name', + :locals => {:obj => @obj,:non_list_all => false,:object_flag => @obj_flag}) %>'); +//$('#put-tag-form-issue').hide(); +$('#name-issue').val(""); +<% elsif @obj_flag == '6'%> +$("#tags_show-<%=@obj.class%>-<%=@obj.id%>").empty(); +$("#tags_show-<%=@obj.class%>-<%=@obj.id%>").html('<%= escape_javascript(render :partial => 'tags/tag_name', + :locals => {:obj => @obj,:non_list_all => false,:object_flag => @obj_flag}) %>'); +$("#put-tag-form- <%=@obj.class%>- <%=@obj.id%>").hide(); +$("#put-tag-form-<%=@obj.class%>-<%=@obj.id%> #name").val(""); +<% else %> + +$('#tags_show').html('<%= escape_javascript(render :partial => 'tags/tag_name', + :locals => {:obj => @obj,:non_list_all => false,:object_flag => @obj_flag}) %>'); +$('#tags_show').html('<%=render_attachments_tag_save(@project, nil)%>'); +$('#put-tag-form #name').val(""); +//$('#put-tag-form').hide(); +<% end %> +<%else%> +$("#attachments_fields").children().remove(); +$("#upload_file_count").text("未上传文件"); +$('#upload_file_div').slideToggle('slow'); +<%if @project%> +$("#all_browse_div").html('<%= j(render partial: "show_all_attachment")%>'); +<%elsif @course%> +$("#all_browse_div").html('<%= j(render partial: "course_show_all_attachment")%>'); +<%end%> +<% end %> + diff --git a/app/views/files/getattachtype.js.erb b/app/views/files/getattachtype.js.erb index 3bc9863b2..88722073f 100644 --- a/app/views/files/getattachtype.js.erb +++ b/app/views/files/getattachtype.js.erb @@ -1,5 +1,13 @@ <% if @attachtype==0 && @contenttype=='0' %> +<% if @project%> $("#all_browse_div").html('<%= j(render partial: "show_all_attachment")%>'); -<%else%> -$("#all_browse_div").html('<%= j(render partial: "sort_by_attachtypel")%>'); +<% elsif @course%> +$("#all_browse_div").html('<%= j(render partial: "course_show_all_attachment")%>'); +<%end%> +<%else%> +<% if @project%> +$("#all_browse_div").html('<%= j(render partial: "sort_by_attachtypel")%>') +<% elsif @course%> +$("#all_browse_div").html('<%= j(render partial: "course_sort_by_attachtypel")%>') +<%end%>; <%end%> diff --git a/app/views/files/index.html.erb b/app/views/files/index.html.erb index 9fc430e3f..b086b90db 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 b14df7b11..f67aa1181 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 72e7ce221..34fc953da 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 5fca6b156..330ab9b5e 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 ce202c792..237895d23 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 1e202e6a4..7a51b0ed6 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 6cb35bccc..fb64a0995 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 000000000..9dfe170bd --- /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 000000000..ca422f0df --- /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 000000000..de749d182 --- /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 1fb643183..5f8f39fa0 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 000000000..7c2403e10 --- /dev/null +++ b/app/views/homework_attach/_show_score.html.erb @@ -0,0 +1,14 @@ + +
    + <% if stars != nil %> +
    + <% else %> +
    + <% end %> +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/app/views/homework_attach/add_homework_users.js.erb b/app/views/homework_attach/add_homework_users.js.erb new file mode 100644 index 000000000..dc4b0cc56 --- /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 ed5887a7f..e16609b68 100644 --- a/app/views/homework_attach/addjours.js.erb +++ b/app/views/homework_attach/addjours.js.erb @@ -1,6 +1,6 @@ <% if @add_jour.is_comprehensive_evaluation == 1 %> $('#comprehensive_evaluation').html('<%= escape_javascript(render(:partial => 'comprehensive_evaluation', - :locals => {:comprehensive_evaluation => @comprehensive_evaluation,:homework => @homework} )) %>'); + :locals => {:comprehensive_evaluation => @comprehensive_evaluation,:homework => @homework,:teaher_score => @teaher_score} )) %>'); <% else %> $('#message').html('<%= escape_javascript(render(:partial => 'showjour', :locals => {:jour =>@jour, :state => false,:homework => @homework} )) %>'); $('#pre_show').html('<%= escape_javascript(render(:partial => 'pre_show', :locals => {:content => nil})) %>'); diff --git a/app/views/homework_attach/destory_homework_users.js.erb b/app/views/homework_attach/destory_homework_users.js.erb new file mode 100644 index 000000000..dc4b0cc56 --- /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 e69de29bb..9a33ea992 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 000000000..64fa22cbb --- /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 073ab21b2..9f0b69f58 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 9c39e84f1..87dcf60cb 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 3f87eaabd..61cea920c 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 fdc35f496..9823e30b7 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 2b17b4fb1..b36c4b57d 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 0e4aa0731..3a33e6f5f 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 d261957c6..89fc862d0 100644 --- a/app/views/issues/show.html.erb +++ b/app/views/issues/show.html.erb @@ -33,7 +33,7 @@ - <%= render :partial => "/praise_tread/praise_tread",:locals => {:obj => @issue,:show_flag => true,:user_id =>User.current.id}%> + <%= render :partial => "/praise_tread/praise_tread",:locals => {:obj => @issue,:show_flag => true,:user_id =>User.current.id,:horizontal => false}%>

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

    <% if @issue.editable? %> - -
    + + + +<% end %> diff --git a/app/views/layouts/_base_header.html.erb b/app/views/layouts/_base_header.html.erb index d340ea9e9..983c83d2d 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 000000000..ad90e904a --- /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 d029d27e4..7fa65bec4 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 74f7d6bfe..ab298ba2e 100644 --- a/app/views/praise_tread/praise_minus.js.erb +++ b/app/views/praise_tread/praise_minus.js.erb @@ -1,3 +1,3 @@ $('#praise_tread').html('<%= j( -render :partial => "/praise_tread/praise_tread",:locals => {:obj => @obj,:show_flag => false,:user_id => User.current.id} +render :partial => "/praise_tread/praise_tread",:locals => {:obj => @obj,:show_flag => false,:user_id => User.current.id,:horizontal=>@horizontal} )%>'); diff --git a/app/views/praise_tread/praise_plus.js.erb b/app/views/praise_tread/praise_plus.js.erb index c2584dcd2..d56ff0e68 100644 --- a/app/views/praise_tread/praise_plus.js.erb +++ b/app/views/praise_tread/praise_plus.js.erb @@ -1,4 +1,4 @@ $('#praise_tread_<%= @obj.id %>').html('<%= j( -render :partial => "/praise_tread/praise_tread",:locals => {:obj => @obj,:user_id => User.current.id} +render :partial => "/praise_tread/praise_tread",:locals => {:obj => @obj,:user_id => User.current.id,:horizontal => @horizontal} )%>'); diff --git a/app/views/praise_tread/tread_plus.js.erb b/app/views/praise_tread/tread_plus.js.erb index 89efec2dc..1104440ec 100644 --- a/app/views/praise_tread/tread_plus.js.erb +++ b/app/views/praise_tread/tread_plus.js.erb @@ -1,5 +1,5 @@ $('#praise_tread_<%= @obj.id %>').html('<%= j( -render :partial => "/praise_tread/praise_tread",:locals => {:obj => @obj,:user_id => User.current.id} +render :partial => "/praise_tread/praise_tread",:locals => {:obj => @obj,:user_id => User.current.id,:horizontal => @horizontal} )%>'); diff --git a/app/views/projects/_course.html.erb b/app/views/projects/_course.html.erb index 6ea802037..6c4bfe9a6 100644 --- a/app/views/projects/_course.html.erb +++ b/app/views/projects/_course.html.erb @@ -18,7 +18,11 @@ <%if @admin&&@admin.first&&@admin.first.user&&@admin.first.user.user_extensions%> <%# unless @project.course_extra.school.nil? %> - <%= @project.course_extra.teacher.user_extensions.school.try(:name) %> + + <% unless @project.course_extra.teacher.user_extensions.school.nil? %> + <%= link_to @project.course_extra.teacher.user_extensions.school.try(:name),options={:controller => 'welcome',:action => 'course',:school_id => @project.course_extra.teacher.user_extensions.school.id}, html_options={:method => 'get'}%> + <% end %> + <%# end %> <% end %>

    diff --git a/app/views/projects/_form.html.erb b/app/views/projects/_form.html.erb index fa2e8da11..ec0bf7fbf 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 e9b21e571..d135cfbdb 100644 --- a/app/views/projects/_show_projects_score.html.erb +++ b/app/views/projects/_show_projects_score.html.erb @@ -28,7 +28,7 @@

    <%= l(:label_projects_score) %>

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

    <%= l(:label_projects_score) %>

    +
    + + + + + + +
    <%= image_tag(url_to_avatar(@project), :class => 'avatar2') %> + + + +
    <%= @project.name %>
    +
    + + + +
    <%= l(:label_projects_score) %>
    <%= format("%.2f" , finall_project_score ).to_f %>
    +
    +
    + +
    +
      +
    • + <%= link_to l(:label_projects_score), {:controller => 'projects', :action => 'show_projects_score', :remote => true}%> : + <%= format("%.2f" , finall_project_score ).to_f %> +
    • +
    • + <%= link_to l(:label_issue_score), {:controller => 'projects', :action => 'issue_score_index', :remote => true}%> : + <%= format("%.2f" , finall_issue_score).to_f %> +
    • +
    • + <%= link_to l(:label_news_score), {:controller => 'projects', :action => 'news_score_index', :remote => true}%> : + <%= format("%.2f" , finall_new_score).to_f %> +
    • +
    • + <%= link_to l(:label_file_score), {:controller => 'projects', :action => 'file_score_index', :remote => true}%> : + <%= format("%.2f" , finall_file_score).to_f %> +
    • +
    • + <%= link_to l(:label_code_submit_score), {:controller => 'projects', :action => 'code_submit_score_index', :remote => true}%> : + <%= format("%.2f" , finall_code_submit_score).to_f %> +
    • +
    • + <%= link_to l(:label_topic_score), {:controller => 'projects', :action => 'projects_topic_score_index', :remote => true}%> : + <%= format("%.2f" , finall_topic_score).to_f %> +
    • +
    +
    +
    + <%= render :partial => 'projects/project_score_index', :locals => {:index => 0 } %> +
    + \ No newline at end of file diff --git a/app/views/school/index.html.erb b/app/views/school/index.html.erb index 755bd3151..a42844ffb 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 1ea452dec..43048be58 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 c74721c3e..a5cda9944 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 000000000..0ceb8f157 --- /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 13ab819dc..f5cada9a8 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 000000000..ec06aa1fc --- /dev/null +++ b/plugins/redmine_code_review/app/views/code_review_settings/_filters.html.erb @@ -0,0 +1,117 @@ +<% +# Code Review plugin for Redmine +# Copyright (C) 2009-2012 Haruyuki Iida +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +-%> + +

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

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

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

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

    <%= f.check_box :tracker_in_review_dialog %>

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

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

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

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

    + +

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

    + +

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

    +
    + +

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

    +
    +

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

    +

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

    +

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

    +

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

    +

    +

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

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

      <script>some script;</script>

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

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

      ", + "