diff --git a/app/controllers/concerns/point_visualisation.rb b/app/controllers/concerns/point_visualisation.rb new file mode 100644 index 000000000..cf3bdcd8a --- /dev/null +++ b/app/controllers/concerns/point_visualisation.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true. +module PointVisualisation + extend ActiveSupport::Concern + + def define_point_stats(user) + # TODO: bit ugly + @awarded_points = Hash[AwardedPoint.where(id: AwardedPoint.all_awarded(user)).to_a.sort!.group_by(&:course_id).map { |k, v| [k, v.map(&:name)] }] + @courses = [] + @missing_points = {} + @percent_completed = {} + @group_completion_ratios = {} + @awarded_points.keys.each do |course_id| + course = Course.find(course_id) + next if course.hide_submissions? + @courses << course + + awarded = @awarded_points[course.id] + missing = AvailablePoint.course_points(course).order!.map(&:name) - awarded + @missing_points[course_id] = missing + + @percent_completed[course_id] = + if (awarded.size + missing.size).positive? + 100 * (awarded.size.to_f / (awarded.size + missing.size)) + else + 0 + end + @group_completion_ratios[course_id] = course.exercise_group_completion_ratio_for_user(user) + end + end +end diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb index 4c3b86257..ec3342dbe 100644 --- a/app/controllers/courses_controller.rb +++ b/app/controllers/courses_controller.rb @@ -4,6 +4,7 @@ require 'exercise_completion_status_generator' class CoursesController < ApplicationController + include PointVisualisation before_action :set_organization before_action :set_course, except: [:help, :index, :show_json] @@ -41,6 +42,8 @@ def show authorize! :read, @course UncomputedUnlock.resolve(@course, current_user) + define_point_stats(current_user) + respond_to do |format| format.html do assign_show_view_vars diff --git a/app/controllers/participants_controller.rb b/app/controllers/participants_controller.rb index 1167e9bea..41e73b7df 100644 --- a/app/controllers/participants_controller.rb +++ b/app/controllers/participants_controller.rb @@ -1,6 +1,7 @@ require 'portable_csv' class ParticipantsController < ApplicationController + include PointVisualisation before_action :set_organization, only: [:index] def index @@ -61,8 +62,6 @@ def index def show @user = User.find(params[:id]) authorize! :view_participant_information, @user - # TODO: bit ugly - @awarded_points = Hash[AwardedPoint.where(id: AwardedPoint.all_awarded(@user)).to_a.sort!.group_by(&:course_id).map { |k, v| [k, v.map(&:name)] }] if current_user.administrator? add_breadcrumb 'Participants', :participants_path @@ -71,27 +70,7 @@ def show add_breadcrumb 'My stats', participant_path(@user) end - @courses = [] - @missing_points = {} - @percent_completed = {} - @group_completion_ratios = {} - for course_id in @awarded_points.keys - course = Course.find(course_id) - if !course.hide_submissions? - @courses << course - - awarded = @awarded_points[course.id] - missing = AvailablePoint.course_points(course).order!.map(&:name) - awarded - @missing_points[course_id] = missing - - if awarded.size + missing.size > 0 - @percent_completed[course_id] = 100 * (awarded.size.to_f / (awarded.size + missing.size)) - else - @percent_completed[course_id] = 0 - end - @group_completion_ratios[course_id] = course.exercise_group_completion_ratio_for_user(@user) - end - end + define_point_stats(@user) if current_user.administrator? || current_user.id == @user.id @submissions = @user.submissions.order('created_at DESC').includes(:user).includes(:course) @@ -102,7 +81,6 @@ def show @submissions = @submissions.limit(100) unless !!params[:view_all] Submission.eager_load_exercises(@submissions) - end def me diff --git a/app/controllers/points_controller.rb b/app/controllers/points_controller.rb index 577cfc16f..a6c491071 100644 --- a/app/controllers/points_controller.rb +++ b/app/controllers/points_controller.rb @@ -81,6 +81,9 @@ def show end respond_to do |format| format.html + format.csv do + render_csv(filename: "#{@course.name}_#{@sheetname}_points.csv") + end format.json do output = { api_version: ApiVersion::API_VERSION, diff --git a/app/views/courses/show.html.erb b/app/views/courses/show.html.erb index 19c5083c8..dfd39cd3a 100644 --- a/app/views/courses/show.html.erb +++ b/app/views/courses/show.html.erb @@ -246,6 +246,10 @@ %> + <% if signed_in? %> + <%= render 'layouts/points', courses: [@course], title: 'My points', show_course_name: false %> + <% end %> + <% if @submissions %>

Latest submissions

diff --git a/app/views/layouts/_points.html.erb b/app/views/layouts/_points.html.erb new file mode 100644 index 000000000..61e17ff2e --- /dev/null +++ b/app/views/layouts/_points.html.erb @@ -0,0 +1,70 @@ +
+
+

<%= title %>

+
+ <% for course in courses %> + <% if course && @percent_completed[course.id] %> +
+
+ <% if show_course_name %> +

+ <% if can? :read, course %> + <%= link_to course.title, organization_course_path(course.organization, course) %> + <% else %> + <%= course.title %> + <% end %> +

+
+ <% end %> + <% if can? :see_points, course%> + Awarded points +
+
+ <%= sprintf("%.0f", @percent_completed[course.id]) %>% +
+
+ <% if @group_completion_ratios[course.id] %> + <% @group_completion_ratios[course.id].each do |group, ratio| %> +
+ Awarded points for <%= group %> +
+ <% unless ratio.zero? %> +
+ <%= sprintf("%.0f", ratio * 100) %>% +
+ <% end %> +
+ <% end %> +
+ <% end %> +
+ + + + + + + + + + + + + + + +
Point names
Awarded points + <%= points_list(@awarded_points[course.id]) %>
Missing points + <%= points_list(@missing_points[course.id]) %>
+ <% else %> + For this course points are not visible. + <% end %> +
+
+ <%else%> + You don't have any points for this course +
+ <% end %> +
+ <% end %> +
diff --git a/app/views/participants/show.html.erb b/app/views/participants/show.html.erb index fe8e2363c..e32ddc625 100644 --- a/app/views/participants/show.html.erb +++ b/app/views/participants/show.html.erb @@ -18,75 +18,7 @@
-<% unless @user.email_verified? %> - -<% end %> - -
-
-

Points

-
- <% for course in @courses %> -
-
-

- <% if can? :read, course %> - <%= link_to course.title, organization_course_path(course.organization, course) %> - <% else %> - <%= course.title %> - <% end %> -

-
- <% if can? :see_points, course %> - Awarded points -
-
- <%= sprintf("%.0f", @percent_completed[course.id]) %>% -
-
- <% if @group_completion_ratios[course.id] %> - <% @group_completion_ratios[course.id].each do |group, ratio| %> -
- Awarded points for <%= group %> -
- <% unless ratio.zero? %> -
- <%= sprintf("%.0f", ratio * 100) %>% -
- <% end %> -
- <% end %> -
- <% end %> -
- - - - - - - - - - - - - - - -
Point names
Awarded points - <%= points_list(@awarded_points[course.id]) %>
Missing points - <%= points_list(@missing_points[course.id]) %>
- <% else %> - For this course points are not visible. - <% end %> -
-
-
- <% end %> -
+<%= render 'layouts/points', courses: @courses, title: 'Points', show_course_name: true %>

Submissions

diff --git a/app/views/points/show.csv.erb b/app/views/points/show.csv.erb new file mode 100644 index 000000000..c450c42e5 --- /dev/null +++ b/app/views/points/show.csv.erb @@ -0,0 +1,29 @@ +<% require 'portable_csv' %> +<%= PortableCSV.generate(:force_quotes => true) do |csv| + arr = ["Username"] + arr += @user_fields.map(&:label) if @user_fields + arr += @exercises.map{ |exercise| [exercise[:name]] + (exercise.available_points.length > 1 ? [nil] * (exercise.available_points.length-1) : []) }.flatten + csv << arr + + arr = [nil] + arr += [nil] * @user_fields.length if @user_fields + arr += @exercises.map{|exercise| exercise.available_points.sort.map{|point| point.name }}.flatten + csv << arr + + @users.each do |user, index| + user_points = @users_to_points[user.login] + arr = [user.login] + if @user_fields + @user_fields.each do |field| + value = user.user_field_values.find { |o| o.field_name == field.name } + arr += [value.value] if value + end + end + @exercises.each do |exercise| + exercise.available_points.sort.each do |p| + arr += user_points.include?(p.name) ? [1] : [0] + end + end + csv << arr + end +end.html_safe %> diff --git a/app/views/points/show.html.erb b/app/views/points/show.html.erb index b2d552195..9b1df2075 100644 --- a/app/views/points/show.html.erb +++ b/app/views/points/show.html.erb @@ -6,11 +6,14 @@ <% if can? :refresh_gdocs_spreadsheet, @course %> <% link_to 'Refresh Google Docs worksheet', refresh_gdocs_organization_course_point_path(@organization, @course, @sheetname), class: "btn btn-primary" %> <% end %> diff --git a/ext/tmc-langs b/ext/tmc-langs index 01c61d96e..6693f225f 160000 --- a/ext/tmc-langs +++ b/ext/tmc-langs @@ -1 +1 @@ -Subproject commit 01c61d96e3832fb39e03504ecd331a9e9527e2dd +Subproject commit 6693f225f79d4a39311280c5328a863544e342f3 diff --git a/ext/tmc-sandbox b/ext/tmc-sandbox index da1da949a..40fc24b64 160000 --- a/ext/tmc-sandbox +++ b/ext/tmc-sandbox @@ -1 +1 @@ -Subproject commit da1da949a64df5803544798314fad4693b692288 +Subproject commit 40fc24b64a59070f12c59effc4d6aac7a301fa11