diff --git a/app/assets/javascripts/editor/editor.js.erb b/app/assets/javascripts/editor/editor.js.erb index e3e34462..2d145e34 100644 --- a/app/assets/javascripts/editor/editor.js.erb +++ b/app/assets/javascripts/editor/editor.js.erb @@ -155,9 +155,9 @@ configureEditors: function () { if (!same) { this.publishCodeOceanEvent("codeocean_editor_paste", { text: pasteObject.text, + codeocean_user_id: $('#editor').data('user-id'), exercise: $('#editor').data('exercise-id'), file_id: "1" - }); } }, @@ -390,9 +390,7 @@ configureEditors: function () { var payload = { user: { - type: 'User', - uuid: $('#editor').data('user-id'), - external_id: $('#editor').data('user-external-id') + uuid: $('#editor').data('user-external-id') }, verb: { type: eventName diff --git a/app/assets/javascripts/editor/submissions.js.erb b/app/assets/javascripts/editor/submissions.js.erb index 467c2cd7..20d8cd10 100644 --- a/app/assets/javascripts/editor/submissions.js.erb +++ b/app/assets/javascripts/editor/submissions.js.erb @@ -75,6 +75,8 @@ CodeOceanEditorSubmissions = { } // toggle button states (it might be the case that the request for comments button has to be enabled this.toggleButtonStates(); + + this.updateSaveStateLabel(); }, /** @@ -200,12 +202,15 @@ CodeOceanEditorSubmissions = { } }, - autosave: function () { + updateSaveStateLabel: function() { var date = new Date(); var autosaveLabel = $(this.autosaveLabel); autosaveLabel.parent().css("visibility", "visible"); autosaveLabel.text(date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds()); autosaveLabel.text(date.toLocaleTimeString()); + }, + + autosave: function () { this.autosaveTimer = null; this.createSubmission($('#autosave'), null); } diff --git a/app/assets/stylesheets/request-for-comments.css.scss b/app/assets/stylesheets/request-for-comments.css.scss index cbaf9d36..6448e6e7 100644 --- a/app/assets/stylesheets/request-for-comments.css.scss +++ b/app/assets/stylesheets/request-for-comments.css.scss @@ -17,3 +17,50 @@ width: 100%; height: 200px; } + +.ace_tooltip { + display: none !important; +} + +p.comment { + width: 400px; +} + +.popover-header { + width: 100%; + overflow: hidden; + padding-bottom: 10px; + margin: auto; +} + +.popover-username { + font-weight: bold; + width: 60%; + float: left; +} + +.popover-date { + text-align: right; + color: #008cba; + margin-left: 60%; + font-size: x-small; +} + +.popover-updated { + text-align: right; + margin-left: 60%; + font-size: x-small; +} + +.popover-comment { + word-wrap: break-word; + margin-bottom: 10px; +} + +.popover-divider { + width: 100%; + height: 1px; + background-color: #008cba; + overflow: hidden; + margin-bottom: 10px; +} diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index f6e4f7fb..01dcd9d5 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -19,6 +19,8 @@ class CommentsController < ApplicationController @comments = Comment.where(file_id: params[:file_id]) @comments.map{|comment| comment.username = comment.user.displayname + comment.date = comment.created_at.strftime('%d.%m.%Y %k:%M') + comment.updated = (comment.created_at != comment.updated_at) } else @comments = [] diff --git a/app/controllers/request_for_comments_controller.rb b/app/controllers/request_for_comments_controller.rb index eb2305cc..fca5c99b 100644 --- a/app/controllers/request_for_comments_controller.rb +++ b/app/controllers/request_for_comments_controller.rb @@ -11,14 +11,45 @@ class RequestForCommentsController < ApplicationController # GET /request_for_comments # GET /request_for_comments.json def index - @search = RequestForComment.last_per_user(2).search(params[:q]) + @search = RequestForComment + .last_per_user(2) + .joins('join "submissions" s on s.id = request_for_comments.submission_id + left outer join "files" f on f.context_id = s.id + left outer join "comments" on comments.file_id = f.id') + .group('request_for_comments.id, request_for_comments.user_id, request_for_comments.exercise_id, + request_for_comments.file_id, request_for_comments.question, request_for_comments.created_at, + request_for_comments.updated_at, request_for_comments.user_type, request_for_comments.solved, + request_for_comments.submission_id, request_for_comments.row_number') # ugly, but rails wants it this way + .select('request_for_comments.*, max(comments.updated_at) as last_comment') + .search(params[:q]) @request_for_comments = @search.result.order('created_at DESC').paginate(page: params[:page]) authorize! end def get_my_comment_requests - @search = RequestForComment.where(user_id: current_user.id).order('created_at DESC').search(params[:q]) - @request_for_comments = @search.result.paginate(page: params[:page]) + @search = RequestForComment + .where(user_id: current_user.id) + .joins('join "submissions" s on s.id = request_for_comments.submission_id + left outer join "files" f on f.context_id = s.id + left outer join "comments" on comments.file_id = f.id') + .group('request_for_comments.id') + .select('request_for_comments.*, max(comments.updated_at) as last_comment') + .search(params[:q]) + @request_for_comments = @search.result.order('created_at DESC').paginate(page: params[:page]) + render 'index' + end + + def get_rfcs_with_my_comments + @search = RequestForComment + .joins(:comments) # we don't need to outer join here, because we know the user has commented on these + .where(comments: {user_id: current_user.id}) + .joins('join "submissions" s on s.id = request_for_comments.submission_id + left outer join "files" f on f.context_id = s.id + left outer join "comments" as c on c.file_id = f.id') + .group('request_for_comments.id') + .select('request_for_comments.*, max(c.updated_at) as last_comment') + .search(params[:q]) + @request_for_comments = @search.result.order('last_comment DESC').paginate(page: params[:page]) render 'index' end diff --git a/app/models/comment.rb b/app/models/comment.rb index ceeb9c36..a5946ac9 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -1,7 +1,7 @@ class Comment < ActiveRecord::Base # inherit the creation module: encapsulates that this is a polymorphic user, offers some aliases and makes sure that all necessary attributes are set. include Creation - attr_accessor :username + attr_accessor :username, :date, :updated belongs_to :file, class_name: 'CodeOcean::File' belongs_to :user, polymorphic: true diff --git a/app/policies/comment_policy.rb b/app/policies/comment_policy.rb index ef7a0922..549c8438 100644 --- a/app/policies/comment_policy.rb +++ b/app/policies/comment_policy.rb @@ -12,7 +12,7 @@ class CommentPolicy < ApplicationPolicy everyone end - [:new?, :destroy?].each do |action| + [:new?, :destroy?, :update?].each do |action| define_method(action) { admin? || author? } end diff --git a/app/views/application/_session.html.slim b/app/views/application/_session.html.slim index cbbf3b12..eb9f4d23 100644 --- a/app/views/application/_session.html.slim +++ b/app/views/application/_session.html.slim @@ -10,6 +10,7 @@ li = link_to(t('internal_users.show.link'), current_user) li = link_to(t('request_for_comments.index.all'), request_for_comments_path) li = link_to(t('request_for_comments.index.get_my_comment_requests'), my_request_for_comments_path) + li = link_to(t('request_for_comments.index.get_my_rfc_activity'), my_rfc_activity_path) - if current_user.internal_user? li = link_to(t('sessions.destroy.link'), sign_out_path, method: :delete) - else diff --git a/app/views/comments/index.json.jbuilder b/app/views/comments/index.json.jbuilder index 85172014..55dfac49 100644 --- a/app/views/comments/index.json.jbuilder +++ b/app/views/comments/index.json.jbuilder @@ -1,4 +1,4 @@ json.array!(@comments) do |comment| - json.extract! comment, :id, :user_id, :file_id, :row, :column, :text, :username + json.extract! comment, :id, :user_id, :file_id, :row, :column, :text, :username, :date, :updated json.url comment_url(comment, format: :json) end diff --git a/app/views/request_for_comments/index.html.slim b/app/views/request_for_comments/index.html.slim index db16b562..a081dd55 100644 --- a/app/views/request_for_comments/index.html.slim +++ b/app/views/request_for_comments/index.html.slim @@ -20,6 +20,7 @@ h1 = RequestForComment.model_name.human(count: 2) i class="fa fa-comment" aria-hidden="true" title = t('request_for_comments.comments') align="center" th = t('activerecord.attributes.request_for_comments.username') th = t('activerecord.attributes.request_for_comments.requested_at') + th = t('activerecord.attributes.request_for_comments.last_update') tbody - @request_for_comments.each do |request_for_comment| tr data-id=request_for_comment.id @@ -36,5 +37,6 @@ h1 = RequestForComment.model_name.human(count: 2) td = request_for_comment.comments_count td = request_for_comment.user.displayname td = t('shared.time.before', time: distance_of_time_in_words_to_now(request_for_comment.created_at)) + td = t('shared.time.before', time: distance_of_time_in_words_to_now(request_for_comment.last_comment.nil? ? request_for_comment.updated_at : request_for_comment.last_comment)) = render('shared/pagination', collection: @request_for_comments) \ No newline at end of file diff --git a/app/views/request_for_comments/show.html.erb b/app/views/request_for_comments/show.html.erb index b28c1eb9..ab60ef91 100644 --- a/app/views/request_for_comments/show.html.erb +++ b/app/views/request_for_comments/show.html.erb @@ -64,6 +64,8 @@