From be8ba63b95f70f5cf529da4b6737ad0be796cb87 Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Mon, 20 Jun 2022 00:59:47 +0200 Subject: [PATCH] Add a way for moderators to view user inboxes --- .../moderation/inbox_controller.rb | 18 ++++++++ app/views/inbox/_entry.haml | 44 +++++++++---------- app/views/inbox/show.haml | 2 +- app/views/moderation/inbox/index.haml | 25 +++++++++++ app/views/moderation/inbox/index.js.erb | 8 ++++ app/views/user/_actions.haml | 4 ++ config/locales/views.en.yml | 4 ++ config/routes.rb | 1 + .../moderation/inbox_controller_spec.rb | 29 ++++++++++++ 9 files changed, 112 insertions(+), 23 deletions(-) create mode 100644 app/controllers/moderation/inbox_controller.rb create mode 100644 app/views/moderation/inbox/index.haml create mode 100644 app/views/moderation/inbox/index.js.erb create mode 100644 spec/controllers/moderation/inbox_controller_spec.rb diff --git a/app/controllers/moderation/inbox_controller.rb b/app/controllers/moderation/inbox_controller.rb new file mode 100644 index 00000000..a71ee529 --- /dev/null +++ b/app/controllers/moderation/inbox_controller.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +class Moderation::InboxController < ApplicationController + before_action :authenticate_user! + + def index + @user = User.find_by(screen_name: params[:user]) + @inboxes = @user.cursored_inbox(last_id: params[:last_id]) + @inbox_last_id = @inboxes.map(&:id).min + @more_data_available = !@user.cursored_inbox(last_id: @inbox_last_id, size: 1).count.zero? + @inbox_count = @user.inboxes.count + + respond_to do |format| + format.html + format.js { render layout: false } + end + end +end diff --git a/app/views/inbox/_entry.haml b/app/views/inbox/_entry.haml index 3ae427b1..819b9bda 100644 --- a/app/views/inbox/_entry.haml +++ b/app/views/inbox/_entry.haml @@ -32,25 +32,25 @@ %a.dropdown-item{ href: rails_admin_path_for_resource(i) } %i.fa.fa-gears = t("voc.view_in_rails_admin") - - .card-body - %textarea.form-control{ name: "ib-answer", placeholder: t(".placeholder"), data: { id: i.id } } - %br/ - %button.btn.btn-success{ name: "ib-answer", data: { ib_id: i.id } } - = t("voc.answer") - %button.btn.btn-danger{ name: "ib-destroy", data: { ib_id: i.id } } - = t("voc.delete") - %button.btn.btn-default{ name: "ib-options", data: { ib_id: i.id, state: :hidden } } - %i.fa.fa-cog - %span.sr-only= t(".options") - .card-footer.d-none{ id: "ib-options-#{i.id}" } - %h4= t(".sharing.heading") - - if current_user.services.count.positive? - .row - - current_user.services.each do |service| - .col-md-3.col-sm-4.col-xs-6 - %label - %input{ type: "checkbox", name: "ib-share", checked: :checked, data: { ib_id: i.id, service: service.provider } } - = raw t(".sharing.post_to", service: service.provider.capitalize) - - else - %p= t(".sharing.none_html", settings: link_to(t(".sharing.settings"), services_path)) + - if current_user == i.user + .card-body + %textarea.form-control{ name: "ib-answer", placeholder: t(".placeholder"), data: { id: i.id } } + %br/ + %button.btn.btn-success{ name: "ib-answer", data: { ib_id: i.id } } + = t("voc.answer") + %button.btn.btn-danger{ name: "ib-destroy", data: { ib_id: i.id } } + = t("voc.delete") + %button.btn.btn-default{ name: "ib-options", data: { ib_id: i.id, state: :hidden } } + %i.fa.fa-cog + %span.sr-only= t(".options") + .card-footer.d-none{ id: "ib-options-#{i.id}" } + %h4= t(".sharing.heading") + - if current_user.services.count.positive? + .row + - current_user.services.each do |service| + .col-md-3.col-sm-4.col-xs-6 + %label + %input{ type: "checkbox", name: "ib-share", checked: :checked, data: { ib_id: i.id, service: service.provider } } + = raw t(".sharing.post_to", service: service.provider.capitalize) + - else + %p= t(".sharing.none_html", settings: link_to(t(".sharing.settings"), services_path)) diff --git a/app/views/inbox/show.haml b/app/views/inbox/show.haml index c60a429c..7a817ad2 100644 --- a/app/views/inbox/show.haml +++ b/app/views/inbox/show.haml @@ -11,4 +11,4 @@ .d-flex.justify-content-center.justify-content-sm-start %button.btn.btn-light#load-more-btn{ type: :button, data: { last_id: @inbox_last_id } } - = t("vpc.load") + = t("voc.load") diff --git a/app/views/moderation/inbox/index.haml b/app/views/moderation/inbox/index.haml new file mode 100644 index 00000000..36b2ddc7 --- /dev/null +++ b/app/views/moderation/inbox/index.haml @@ -0,0 +1,25 @@ +- provide(:title, generate_title(t(".title", user: @user.screen_name))) + +.card.question--fixed + .container + .card-body + .media + %a.pull-left{ href: show_user_profile_path(@user.screen_name) } + %img.answerbox__question-user-avatar.avatar-md{ src: @user.profile_picture.url(:medium) } + .media-body + Viewing inbox for + %br + %strong= @user.screen_name + = " (##{@user.id})" +.container-lg.container--main + #entries + - @inboxes.each do |i| + = render "inbox/entry", i: i + + = render "shared/cursored_pagination_dummy", more_data_available: @more_data_available, last_id: @inbox_last_id + + - if @more_data_available + + .d-flex.justify-content-center.justify-content-sm-start + %button.btn.btn-light#load-more-btn{ type: :button, data: { last_id: @inbox_last_id } } + = t("voc.load") diff --git a/app/views/moderation/inbox/index.js.erb b/app/views/moderation/inbox/index.js.erb new file mode 100644 index 00000000..7bab73b8 --- /dev/null +++ b/app/views/moderation/inbox/index.js.erb @@ -0,0 +1,8 @@ +$('#entries').append('<% @inboxes.each do |i| + %><%= j render 'inbox/entry', i: i +%><% end %>'); +<% if @more_data_available %> +$('#pagination').html('<%= j render 'shared/cursored_pagination_dummy', more_data_available: @more_data_available, last_id: @inbox_last_id %>'); +<% else %> +$('#pagination, #load-more-btn').remove(); +<% end %> diff --git a/app/views/user/_actions.haml b/app/views/user/_actions.haml index 1dd4cc45..ead0c139 100644 --- a/app/views/user/_actions.haml +++ b/app/views/user/_actions.haml @@ -36,6 +36,10 @@ %a.dropdown-item{ href: '#', data: { target: '#modal-ban', toggle: :modal } } %i.fa.fa-ban = t 'views.actions.ban' + - if current_user.mod? && user != current_user + %a.dropdown-item{ href: mod_inbox_index_path(user: user.screen_name) } + %i.fa.fa-inbox + View inbox - if current_user.has_role? :administrator %a.dropdown-item{ href: rails_admin_path_for_resource(user), target: '_blank' } %i.fa.fa-cogs diff --git a/config/locales/views.en.yml b/config/locales/views.en.yml index c70f0f97..5d16a7d3 100644 --- a/config/locales/views.en.yml +++ b/config/locales/views.en.yml @@ -326,3 +326,7 @@ en: title: "Theme Settings" export: title: "Export" + moderation: + inbox: + index: + title: "Inbox for %{user}" diff --git a/config/routes.rb b/config/routes.rb index 83edd94d..b9deab5a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -25,6 +25,7 @@ Rails.application.routes.draw do match '/moderation/priority(/:user_id)', to: 'moderation#priority', via: :get, as: :moderation_priority match '/moderation/ip/:user_id', to: 'moderation#ip', via: :get, as: :moderation_ip match '/moderation(/:type)', to: 'moderation#index', via: :get, as: :moderation, defaults: {type: 'all'} + match '/moderation/inbox/:user', to: 'moderation/inbox#index', via: :get, as: :mod_inbox_index namespace :ajax do match '/mod/destroy_report', to: 'moderation#destroy_report', via: :post, as: :mod_destroy_report match '/mod/create_comment', to: 'moderation#create_comment', via: :post, as: :mod_create_comment diff --git a/spec/controllers/moderation/inbox_controller_spec.rb b/spec/controllers/moderation/inbox_controller_spec.rb new file mode 100644 index 00000000..0cf89d2d --- /dev/null +++ b/spec/controllers/moderation/inbox_controller_spec.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +require "rails_helper" + +describe Moderation::InboxController do + context "#index" do + subject { get :index, params: params } + + let(:target_user) { FactoryBot.create(:user) } + let!(:inboxes) { FactoryBot.create_list(:inbox, 60, user: target_user) } + let(:params) { { user: target_user.screen_name } } + + context "moderator signed in" do + before do + sign_in(FactoryBot.create(:user, roles: [:moderator])) + end + + it "renders the index template" do + subject + expect(response).to render_template(:index) + end + + it "assigns inbox entries" do + subject + expect(assigns(:inboxes).count).to eq(APP_CONFIG[:items_per_page]) + end + end + end +end