diff --git a/app/assets/javascripts/groups.js.coffee b/app/assets/javascripts/groups.js.coffee new file mode 100644 diff --git a/app/assets/javascripts/testcases.js.coffee b/app/assets/javascripts/testcases.js.coffee new file mode 100644 diff --git a/app/assets/stylesheets/groups.css.scss b/app/assets/stylesheets/groups.css.scss new file mode 100644 diff --git a/app/assets/stylesheets/testcases.css.scss b/app/assets/stylesheets/testcases.css.scss new file mode 100644 diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -52,25 +52,33 @@ def remove_user user = User.find(params[:user_id]) @group.users.delete(user) - redirect_to group_path(@group), notice: "User #{user.login} was removed from the group #{@group.name}" + redirect_to group_path(@group), flash: {success: "User #{user.login} was removed from the group #{@group.name}"} end def add_user user = User.find(params[:user_id]) - @group.users << user - redirect_to group_path(@group), notice: "User #{user.login} was add to the group #{@group.name}" + begin + @group.users << user + redirect_to group_path(@group), flash: { success: "User #{user.login} was add to the group #{@group.name}"} + rescue => e + redirect_to group_path(@group), alert: e.message + end end def remove_problem problem = Problem.find(params[:problem_id]) @group.problems.delete(problem) - redirect_to group_path(@group), notice: "Problem #{problem.name} was removed from the group #{@group.name}" + redirect_to group_path(@group), flash: {success: "Problem #{problem.name} was removed from the group #{@group.name}" } end def add_problem problem = Problem.find(params[:problem_id]) - @group.problems << problem - redirect_to group_path(@group), notice: "Problem #{problem.name} was add to the group #{@group.name}" + begin + @group.problems << problem + redirect_to group_path(@group), flash: {success: "Problem #{problem.name} was add to the group #{@group.name}" } + rescue => e + redirect_to group_path(@group), alert: e.message + end end private diff --git a/app/controllers/problems_controller.rb b/app/controllers/problems_controller.rb --- a/app/controllers/problems_controller.rb +++ b/app/controllers/problems_controller.rb @@ -197,10 +197,20 @@ set_available(false) elsif params.has_key? 'add_group' group = Group.find(params[:group_id]) + ok = [] + failed = [] get_problems_from_params.each do |p| - group.problems << p + begin + group.problems << p + ok << p.full_name + rescue => e + failed << p.full_name + end end + flash[:success] = "The following problems are added to the group #{group.name}: " + ok.join(', ') if ok.count > 0 + flash[:alert] = "The following problems are already in the group #{group.name}: " + failed.join(', ') if failed.count > 0 end + redirect_to :action => 'manage' end diff --git a/app/controllers/user_admin_controller.rb b/app/controllers/user_admin_controller.rb --- a/app/controllers/user_admin_controller.rb +++ b/app/controllers/user_admin_controller.rb @@ -442,7 +442,18 @@ end if @action[:add_group] and @action[:group_name] @group = Group.find(@action[:group_name]) - @users.each { |user| @group.users << user } + ok = [] + failed = [] + @users.each do |user| + begin + @group.users << user + ok << user.login + rescue => e + failed << user.login + end + end + flash[:success] = "The following users are added to the 'group #{@group.name}': " + ok.join(', ') if ok.count > 0 + flash[:alert] = "The following users are already in the 'group #{@group.name}': " + failed.join(', ') if failed.count > 0 end end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -200,7 +200,7 @@ BOOTSTRAP_FLASH_MSG = { success: 'alert-success', error: 'alert-danger', - alert: 'alert-block', + alert: 'alert-danger', notice: 'alert-info' } diff --git a/app/models/group.rb b/app/models/group.rb --- a/app/models/group.rb +++ b/app/models/group.rb @@ -1,5 +1,13 @@ class Group < ActiveRecord::Base - has_and_belongs_to_many :problems - has_and_belongs_to_many :users + has_many :groups_problems, class_name: GroupProblem + has_many :problems, :through => :groups_problems + + has_many :groups_users, class_name: GroupUser + has_many :users, :through => :groups_users + + #has_and_belongs_to_many :problems + #has_and_belongs_to_many :users + + end diff --git a/app/models/group_problem.rb b/app/models/group_problem.rb new file mode 100644 --- /dev/null +++ b/app/models/group_problem.rb @@ -0,0 +1,7 @@ +class GroupProblem < ActiveRecord::Base + self.table_name = 'groups_problems' + + belongs_to :problem + belongs_to :group + validates_uniqueness_of :problem_id, scope: :group_id, message: ->(object, data) { "'#{Problem.find(data[:value]).full_name}' is already in the group" } +end diff --git a/app/models/group_user.rb b/app/models/group_user.rb new file mode 100644 --- /dev/null +++ b/app/models/group_user.rb @@ -0,0 +1,7 @@ +class GroupUser < ActiveRecord::Base + self.table_name = 'groups_users' + + belongs_to :user + belongs_to :group + validates_uniqueness_of :user_id, scope: :group_id, message: ->(object, data) { "'#{User.find(data[:value]).full_name}' is already in the group" } +end diff --git a/app/models/problem.rb b/app/models/problem.rb --- a/app/models/problem.rb +++ b/app/models/problem.rb @@ -2,7 +2,11 @@ belongs_to :description has_and_belongs_to_many :contests, :uniq => true - has_and_belongs_to_many :groups + + #has_and_belongs_to_many :groups + has_many :groups_problems, class_name: GroupProblem + has_many :groups, :through => :groups_problems + has_many :test_pairs, :dependent => :delete_all has_many :testcases, :dependent => :destroy diff --git a/app/models/user.rb b/app/models/user.rb --- a/app/models/user.rb +++ b/app/models/user.rb @@ -7,7 +7,10 @@ class User < ActiveRecord::Base has_and_belongs_to_many :roles - has_and_belongs_to_many :groups + + #has_and_belongs_to_many :groups + has_many :groups_users, class_name: GroupUser + has_many :groups, :through => :groups_users has_many :test_requests, -> {order(submitted_at: DESC)} diff --git a/app/views/problems/index.html.haml b/app/views/problems/index.html.haml --- a/app/views/problems/index.html.haml +++ b/app/views/problems/index.html.haml @@ -1,10 +1,10 @@ - content_for :head do = stylesheet_link_tag 'problems' -%h1 Listing problems +%h1 Problems %p - = link_to 'New problem', new_problem_path, class: 'btn btn-default btn-sm' - = link_to 'Manage problems', { action: 'manage'}, class: 'btn btn-default btn-sm' - = link_to 'Import problems', {:action => 'import'}, class: 'btn btn-default btn-sm' + = link_to 'Import problems', {:action => 'import'}, class: 'btn btn-success btn-sm' + = link_to 'New problem', new_problem_path, class: 'btn btn-success btn-sm' + = link_to 'Bulk Manage', { action: 'manage'}, class: 'btn btn-info btn-sm' = link_to 'Turn off all problems', {:action => 'turn_all_off'}, class: 'btn btn-default btn-sm' = link_to 'Turn on all problems', {:action => 'turn_all_on'}, class: 'btn btn-default btn-sm' .submitbox diff --git a/app/views/problems/manage.html.haml b/app/views/problems/manage.html.haml --- a/app/views/problems/manage.html.haml +++ b/app/views/problems/manage.html.haml @@ -36,33 +36,37 @@ %h1 Manage problems -%p= link_to '[Back to problem list]', :action => 'list' +%p= link_to '[Back to problem list]', problems_path = form_tag :action=>'do_manage' do - .submitbox.panel - What do you want to do to the selected problem? - %br/ - (You can shift-click to select a range of problems) - %ul - %li - Change date added to - = select_date Date.current, :prefix => 'date_added' -     - = submit_tag 'Change', :name => 'change_date_added' - %li - Set available to - = submit_tag 'True', :name => 'enable_problem' - = submit_tag 'False', :name => 'disable_problem' + .panel.panel-primary + .panel-heading + Action + .panel-body + .submit-box + What do you want to do to the selected problem? + %br/ + (You can shift-click to select a range of problems) + %ul + %li + Change date added to + = select_date Date.current, :prefix => 'date_added' +     + = submit_tag 'Change', :name => 'change_date_added', class: 'btn btn-default' + %li + Set available to + = submit_tag 'True', :name => 'enable_problem', class: 'btn btn-default' + = submit_tag 'False', :name => 'disable_problem', class: 'btn btn-default' - - if GraderConfiguration.multicontests? - %li - Add to - = select("contest","id",Contest.all.collect {|c| [c.title, c.id]}) - = submit_tag 'Add', :name => 'add_to_contest' - %li - Add problems to group - = select_tag "group_id", options_from_collection_for_select( Group.all, 'id','name',params[:group_name]), id: 'group_name',class: 'select2' - = submit_tag 'Add', name: 'add_group' + - if GraderConfiguration.multicontests? + %li + Add to + = select("contest","id",Contest.all.collect {|c| [c.title, c.id]}) + = submit_tag 'Add', :name => 'add_to_contest', class: 'btn btn-default' + %li + Add problems to group + = select_tag "group_id", options_from_collection_for_select( Group.all, 'id','name',params[:group_name]), id: 'group_name',class: 'select2' + = submit_tag 'Add', name: 'add_group', class: 'btn btn-default' %table.table.table-hover diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb new file mode 100644 --- /dev/null +++ b/config/initializers/assets.rb @@ -0,0 +1,23 @@ +# Be sure to restart your server when you modify this file. + +# Version of your assets, change this if you want to expire all your assets. +Rails.application.config.assets.version = '1.0' + +# Add additional assets to the asset load path. +# Rails.application.config.assets.paths << Emoji.images_path +# Add Yarn node_modules folder to the asset load path. +Rails.application.config.assets.paths << Rails.root.join('node_modules') +Rails.application.config.assets.paths << Rails.root.join('vendor/assets/fonts') + +# Precompile additional assets. +# application.js, application.css, and all non-JS/CSS in the app/assets +# folder are already added. +# Rails.application.config.assets.precompile += %w( admin.js admin.css ) + +Rails.application.config.assets.precompile += ['announcement_refresh.js','effects.js','site_update.js'] +Rails.application.config.assets.precompile += ['local_jquery.js','tablesorter-theme.cafe.css'] +%w( announcements submissions configurations contests contest_management graders heartbeat + login main messages problems report site sites sources tasks groups + test user_admin users ).each do |controller| + Rails.application.config.assets.precompile += ["#{controller}.js", "#{controller}.css"] +end