Skip to content

Commit

Permalink
Merge pull request #15044 from hellcp-work/paper_trail
Browse files Browse the repository at this point in the history
Comment history dropdown
  • Loading branch information
hellcp-work committed Oct 16, 2023
2 parents bad27ce + 2def8aa commit 954c433
Show file tree
Hide file tree
Showing 14 changed files with 139 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
.d-inline-flex
%i.fas.fa-lg.fa-comment.text-dark{ title: 'Comment' }
= render(AvatarComponent.new(name: comment.user.name, email: comment.user.email, size: 35, shape: :circle, custom_css: 'avatars-counter'))
%p
.mb-3
= link_to(helpers.realname_with_login(comment.user), user_path(comment.user))
wrote
= link_to("#comment-#{comment.id}", title: l(comment.created_at.utc), name: "comment-#{comment.id}") do
= render TimeComponent.new(time: comment.created_at)
= render CommentHistoryComponent.new(comment)
.timeline-item-comment.mb-4
.comment-bubble
- if policy(comment).update? || policy(comment).destroy?
Expand Down
14 changes: 14 additions & 0 deletions src/api/app/components/comment_history_component.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
%span.dropdown
(edited
= link_to('#', role: 'button', data: { 'bs-toggle': 'dropdown' }, 'aria-expanded': false, class: 'dropdown-toggle') do
= render TimeComponent.new(time: @comment.versions.last.created_at)
)
.d-block
%ul.dropdown-menu
- @comment.versions.each do |version|
%li.dropdown-item
= link_to(comment_history_path(@comment, version_id: version.id, format: 'js'), data: { remote: true }) do
- if version.whodunnit
= User.find(version.whodunnit).login
= paper_trail_event(version.event)
= render TimeComponent.new(time: version.created_at)
13 changes: 13 additions & 0 deletions src/api/app/components/comment_history_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
class CommentHistoryComponent < ApplicationComponent
include Webui::PaperTrailHelper

def initialize(comment)
super

@comment = comment
end

def render?
policy(@comment).history? && @comment.versions.where(event: 'update').present?
end
end
13 changes: 11 additions & 2 deletions src/api/app/controllers/webui/comments_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
class Webui::CommentsController < Webui::WebuiController
before_action :require_login
before_action :set_commented, only: :create
before_action :set_comment, only: :moderate
before_action :set_comment, only: [:moderate, :history]

def create
if @commented.nil?
Expand Down Expand Up @@ -132,6 +132,15 @@ def moderate
end
end

def history
authorize @comment, :history?

@version = @comment.versions.find(params[:version_id])
respond_to do |format|
format.js { render 'webui/comment/history' }
end
end

private

def permitted_params
Expand All @@ -140,7 +149,7 @@ def permitted_params

# FIXME: Use this function for the rest of the actions
def set_comment
@comment = Comment.find(params[:id] || params[:comment_id])
@comment = Comment.find(params[:comment_id] || params[:id])
rescue ActiveRecord::RecordNotFound => e
flash[:error] = e.message
render partial: 'layouts/webui/flash'
Expand Down
6 changes: 6 additions & 0 deletions src/api/app/controllers/webui/webui_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class Webui::WebuiController < ActionController::Base
before_action :current_announcement
before_action :fetch_watchlist_items
after_action :clean_cache
before_action :set_paper_trail_whodunnit

# :notice and :alert are default, we add :success and :error
add_flash_types :success, :error
Expand Down Expand Up @@ -199,6 +200,11 @@ def pundit_user
User.possibly_nobody
end

# TODO: This wouldn't be required if we used fairly common standard current_user function
def user_for_paper_trail
User.session&.id
end

def current_announcement
@current_announcement = StatusMessage.latest_for_current_user
end
Expand Down
16 changes: 16 additions & 0 deletions src/api/app/helpers/webui/paper_trail_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module Webui::PaperTrailHelper
include Webui::WebuiHelper

PAPER_TRAIL_EVENTS = {
'create' => 'created',
'update' => 'updated',
'destroy' => 'destroyed',
'delete' => 'deleted',
'moderate' => 'moderated',
'release' => 'released'
}.freeze

def paper_trail_event(event)
PAPER_TRAIL_EVENTS[event] || 'edited'
end
end
4 changes: 4 additions & 0 deletions src/api/app/models/comment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ class Comment < ApplicationRecord
extend ActsAsTree::TreeWalker
acts_as_tree order: 'created_at'

has_paper_trail

scope :on_actions_for_request, ->(bs_request) { where(commentable: BsRequestAction.where(bs_request: bs_request)) }
scope :without_parent, -> { where(parent_id: nil) }

Expand All @@ -35,6 +37,7 @@ def to_s

def blank_or_destroy
if children.exists?
self.paper_trail_event = 'delete'
self.body = 'This comment has been deleted'
self.user = User.find_nobody!
save!
Expand All @@ -60,6 +63,7 @@ def moderated?
end

def moderate(state)
self.paper_trail_event = state ? 'moderate' : 'release'
self.moderated_at = state ? Time.zone.now : nil
self.moderator = state ? User.session : nil
save!
Expand Down
9 changes: 9 additions & 0 deletions src/api/app/policies/comment_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,13 @@ def locked?
record.commentable.comment_lock.present?
end
end

def history?
return false unless Flipper.enabled?(:content_moderation, user)
# Always display the comment history if the user is admin or moderator
return true if user.is_admin? || user.is_staff? || user.is_moderator?

# Don't display history for moderated and soft deleted comments
!(record.moderated? || record.user.is_nobody?)
end
end
3 changes: 2 additions & 1 deletion src/api/app/views/webui/comment/_content.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
.flex-shrink-0
= image_tag_for(comment.user, size: 35, custom_class: 'me-3 d-none d-sm-block')
.comment.flex-grow-1.text-break
%p
.mb-3
= link_to(comment.user, user_path(comment.user))
wrote
= link_to("#comment-#{comment.id}", title: I18n.l(comment.created_at.utc), name: "comment-#{comment.id}") do
= render TimeComponent.new(time: comment.created_at)
= render CommentHistoryComponent.new(comment)
- if level == 1 && comment.commentable.is_a?(BsRequestAction)
- sourcediff = comment.commentable.bs_request.webui_actions(action_id: comment.commentable, diffs: true, cacheonly: 1).first[:sourcediff].first
- unless sourcediff[:error]
Expand Down
37 changes: 37 additions & 0 deletions src/api/app/views/webui/comment/_history.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
.modal.fade{ id: "comment-history-modal-#{version.id}", tabindex: -1, role: 'dialog',
aria: { hidden: true } }
.modal-dialog.modal-xl.modal-fullscreen-xl-down{ role: 'document' }
.modal-content
.modal-header
%h5.modal-title
- if version.whodunnit
= render UserAvatarComponent.new(User.find(version.whodunnit).login)
= paper_trail_event(version.event)
= render TimeComponent.new(time: version.created_at)
%button.btn-close{ type: 'button', data: { 'bs-dismiss': 'modal' }, aria: { label: 'Close' } }
.modal-body
%table.table
- version.changeset.slice('moderator_id', 'user_id').each do |type, users|
%thead
%tr
%th{ colspan: 2 }= type.delete('_id').humanize
%tr
%th Before
%th After
%tbody
%tr
- users.each do |user|
%td
- if user
= render UserAvatarComponent.new(User.find(user).login)
- if version.changeset.key?('body')
%thead
%tr
%th{ colspan: 2 } Body
%tr
%th Before
%th After
%tbody
%tr
- version.changeset[:body].each do |body|
%td= body
9 changes: 9 additions & 0 deletions src/api/app/views/webui/comment/history.js.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
$('body').append("#{escape_javascript(render(partial: 'webui/comment/history', locals: { version: @version }))}")
var historyModalElement = document.getElementById('comment-history-modal-#{ @version.id }');
var historyModal = new bootstrap.Modal(historyModalElement, {})
historyModal.show();

// Remove after use
historyModalElement.addEventListener('hidden.bs.modal', event => {
historyModalElement.remove();
});
3 changes: 3 additions & 0 deletions src/api/config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -149,5 +149,8 @@ class Application < Rails::Application
config.view_component.default_preview_layout = 'view_component_previews'
# Below the preview, display a syntax highlighted source code example of the usage of the view component
config.view_component.show_previews_source = true

# Classes required by YAML.safe_load used by paper_trail for loading date and time values
config.active_record.yaml_column_permitted_classes = [Date, Time, ActiveSupport::TimeWithZone, ActiveSupport::TimeZone]
end
end
4 changes: 4 additions & 0 deletions src/api/config/routes/webui_routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,10 @@
post 'moderate'
end

defaults format: 'js' do
get 'history/:version_id' => :history, as: :history
end

collection do
post 'preview'
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class CommentHistoryComponentPreview < ViewComponent::Preview
# Preview at http://HOST:PORT/rails/view_components/comment_history_component/preview
def preview
comment = Comment.last
comment.body += 'a'
comment.save!
render(CommentHistoryComponent.new(comment))
end
end

0 comments on commit 954c433

Please sign in to comment.