mirror of
https://github.com/philomena-dev/philomena.git
synced 2024-11-23 20:18:00 +01:00
admin mod notes
This commit is contained in:
parent
e37ab2849e
commit
299e0cf923
12 changed files with 197 additions and 8 deletions
|
@ -49,8 +49,8 @@ defmodule Philomena.ModNotes do
|
|||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def create_mod_note(attrs \\ %{}) do
|
||||
%ModNote{}
|
||||
def create_mod_note(creator, attrs \\ %{}) do
|
||||
%ModNote{moderator_id: creator.id}
|
||||
|> ModNote.changeset(attrs)
|
||||
|> Repo.insert()
|
||||
end
|
||||
|
|
|
@ -12,7 +12,8 @@ defmodule Philomena.ModNotes.ModNote do
|
|||
field :notable_type, :string
|
||||
|
||||
field :body, :string
|
||||
field :deleted, :boolean, default: false
|
||||
|
||||
field :notable, :any, virtual: true
|
||||
|
||||
timestamps(inserted_at: :created_at)
|
||||
end
|
||||
|
@ -20,7 +21,8 @@ defmodule Philomena.ModNotes.ModNote do
|
|||
@doc false
|
||||
def changeset(mod_note, attrs) do
|
||||
mod_note
|
||||
|> cast(attrs, [])
|
||||
|> validate_required([])
|
||||
|> cast(attrs, [:notable_id, :notable_type, :body])
|
||||
|> validate_required([:notable_id, :notable_type, :body])
|
||||
|> validate_inclusion(:notable_type, ["User", "Report", "DnpEntry"])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,12 +7,14 @@ defmodule Philomena.Polymorphic do
|
|||
"Comment" => Philomena.Comments.Comment,
|
||||
"Commission" => Philomena.Commissions.Commission,
|
||||
"Conversation" => Philomena.Conversations.Conversation,
|
||||
"DnpEntry" => Philomena.DnpEntries.DnpEntry,
|
||||
"Filter" => Philomena.Filters.Filter,
|
||||
"Forum" => Philomena.Forums.Forum,
|
||||
"Gallery" => Philomena.Galleries.Gallery,
|
||||
"Image" => Philomena.Images.Image,
|
||||
"LivestreamChannel" => Philomena.Channels.Channel,
|
||||
"Post" => Philomena.Posts.Post,
|
||||
"Report" => Philomena.Reports.Report,
|
||||
"Topic" => Philomena.Topics.Topic,
|
||||
"User" => Philomena.Users.User
|
||||
}
|
||||
|
@ -21,10 +23,12 @@ defmodule Philomena.Polymorphic do
|
|||
"Comment" => [:user, image: :tags],
|
||||
"Commission" => [:user],
|
||||
"Conversation" => [:from, :to],
|
||||
"DnpEntry" => [:requesting_user],
|
||||
"Gallery" => [:creator],
|
||||
"Image" => [:user, :tags],
|
||||
"Post" => [:user, topic: :forum],
|
||||
"Topic" => [:forum, :user]
|
||||
"Topic" => [:forum, :user],
|
||||
"Report" => [:user]
|
||||
}
|
||||
|
||||
# Deal with Rails polymorphism BS
|
||||
|
@ -64,4 +68,4 @@ defmodule Philomena.Polymorphic do
|
|||
%{struct | name => row}
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,6 +9,7 @@ defimpl Canada.Can, for: [Atom, Philomena.Users.User] do
|
|||
alias Philomena.Images.Image
|
||||
alias Philomena.Forums.Forum
|
||||
alias Philomena.Topics.Topic
|
||||
alias Philomena.ModNotes.ModNote
|
||||
alias Philomena.Posts.Post
|
||||
alias Philomena.Filters.Filter
|
||||
alias Philomena.Galleries.Gallery
|
||||
|
@ -97,6 +98,9 @@ defimpl Canada.Can, for: [Atom, Philomena.Users.User] do
|
|||
# Award badges
|
||||
def can?(%User{role: "moderator"}, :create, %Award{}), do: true
|
||||
|
||||
# Create mod notes
|
||||
def can?(%User{role: "moderator"}, :index, ModNote), do: true
|
||||
|
||||
#
|
||||
# Assistants can...
|
||||
#
|
||||
|
|
92
lib/philomena_web/controllers/admin/mod_note_controller.ex
Normal file
92
lib/philomena_web/controllers/admin/mod_note_controller.ex
Normal file
|
@ -0,0 +1,92 @@
|
|||
defmodule PhilomenaWeb.Admin.ModNoteController do
|
||||
use PhilomenaWeb, :controller
|
||||
|
||||
alias Philomena.Textile.Renderer
|
||||
alias Philomena.ModNotes.ModNote
|
||||
alias Philomena.Polymorphic
|
||||
alias Philomena.ModNotes
|
||||
alias Philomena.Repo
|
||||
import Ecto.Query
|
||||
|
||||
plug :verify_authorized
|
||||
plug :load_resource, model: ModNote, only: [:edit, :update, :delete]
|
||||
plug :preload_association when action in [:edit, :update, :delete]
|
||||
|
||||
def index(conn, %{"q" => q}) do
|
||||
ModNote
|
||||
|> where([m], ilike(m.body, ^"%#{q}%"))
|
||||
|> load_mod_notes(conn)
|
||||
end
|
||||
|
||||
def index(conn, _params) do
|
||||
load_mod_notes(ModNote, conn)
|
||||
end
|
||||
|
||||
defp load_mod_notes(queryable, conn) do
|
||||
mod_notes =
|
||||
queryable
|
||||
|> preload(:moderator)
|
||||
|> Repo.paginate(conn.assigns.scrivener)
|
||||
|
||||
bodies = Renderer.render_collection(mod_notes, conn)
|
||||
preloaded = Polymorphic.load_polymorphic(mod_notes, notable: [notable_id: :notable_type])
|
||||
mod_notes = %{mod_notes | entries: Enum.zip(bodies, preloaded)}
|
||||
|
||||
render(conn, "index.html", mod_notes: mod_notes)
|
||||
end
|
||||
|
||||
def new(conn, %{"notable_type" => type, "notable_id" => id}) do
|
||||
changeset = ModNotes.change_mod_note(%ModNote{notable_type: type, notable_id: id})
|
||||
render(conn, "new.html", changeset: changeset)
|
||||
end
|
||||
|
||||
def create(conn, %{"mod_note" => mod_note_params}) do
|
||||
case ModNotes.create_mod_note(conn.assigns.current_user, mod_note_params) do
|
||||
{:ok, _mod_note} ->
|
||||
conn
|
||||
|> put_flash(:info, "Successfully created mod note.")
|
||||
|> redirect(to: Routes.admin_mod_note_path(conn, :index))
|
||||
|
||||
{:error, changeset} ->
|
||||
render(conn, "new.html", changeset: changeset)
|
||||
end
|
||||
end
|
||||
|
||||
def edit(conn, _params) do
|
||||
changeset = ModNotes.change_mod_note(conn.assigns.mod_note)
|
||||
render(conn, "edit.html", changeset: changeset)
|
||||
end
|
||||
|
||||
def update(conn, %{"mod_note" => mod_note_params}) do
|
||||
case ModNotes.update_mod_note(conn.assigns.mod_note, mod_note_params) do
|
||||
{:ok, _mod_note} ->
|
||||
conn
|
||||
|> put_flash(:info, "Successfully updated mod note.")
|
||||
|> redirect(to: Routes.admin_mod_note_path(conn, :index))
|
||||
|
||||
{:error, changeset} ->
|
||||
render(conn, "edit.html", changeset: changeset)
|
||||
end
|
||||
end
|
||||
|
||||
def delete(conn, _params) do
|
||||
{:ok, _mod_note} = ModNotes.delete_mod_note(conn.assigns.mod_note)
|
||||
|
||||
conn
|
||||
|> put_flash(:info, "Successfully deleted mod note.")
|
||||
|> redirect(to: Routes.admin_mod_note_path(conn, :index))
|
||||
end
|
||||
|
||||
defp verify_authorized(conn, _opts) do
|
||||
case Canada.Can.can?(conn.assigns.current_user, :index, ModNote) do
|
||||
true -> conn
|
||||
_false -> PhilomenaWeb.NotAuthorizedPlug.call(conn)
|
||||
end
|
||||
end
|
||||
|
||||
def preload_association(%{assigns: %{mod_note: mod_note}} = conn, _opts) do
|
||||
[mod_note] = Polymorphic.load_polymorphic([mod_note], notable: [notable_id: :notable_type])
|
||||
|
||||
assign(conn, :mod_note, mod_note)
|
||||
end
|
||||
end
|
|
@ -205,6 +205,7 @@ defmodule PhilomenaWeb.Router do
|
|||
|
||||
resources "/forums", ForumController, except: [:show, :delete]
|
||||
resources "/badges", BadgeController, except: [:show, :delete]
|
||||
resources "/mod_notes", ModNoteController, except: [:show]
|
||||
end
|
||||
|
||||
resources "/duplicate_reports", DuplicateReportController, only: [] do
|
||||
|
|
15
lib/philomena_web/templates/admin/mod_note/_form.html.slime
Normal file
15
lib/philomena_web/templates/admin/mod_note/_form.html.slime
Normal file
|
@ -0,0 +1,15 @@
|
|||
= form_for @changeset, @action, fn f ->
|
||||
= if @changeset.action do
|
||||
.alert.alert-danger
|
||||
p Oops, something went wrong! Please check the errors below.
|
||||
|
||||
.field
|
||||
=> label f, :body, "Note"
|
||||
= text_input f, :body, class: "input input--wide", required: true
|
||||
= error_tag f, :body
|
||||
|
||||
= hidden_input f, :notable_id
|
||||
= hidden_input f, :notable_type
|
||||
|
||||
.field
|
||||
= submit "Save", class: "button"
|
|
@ -0,0 +1,6 @@
|
|||
h2
|
||||
' Editing mod note for
|
||||
=> @mod_note.notable_type
|
||||
=> @mod_note.notable_id
|
||||
|
||||
= render PhilomenaWeb.Admin.ModNoteView, "_form.html", changeset: @changeset, action: Routes.admin_mod_note_path(@conn, :update, @mod_note), conn: @conn
|
38
lib/philomena_web/templates/admin/mod_note/index.html.slime
Normal file
38
lib/philomena_web/templates/admin/mod_note/index.html.slime
Normal file
|
@ -0,0 +1,38 @@
|
|||
- route = fn p -> Routes.admin_mod_note_path(@conn, :index, p) end
|
||||
- pagination = render PhilomenaWeb.PaginationView, "_pagination.html", page: @mod_notes, route: route, conn: @conn
|
||||
|
||||
h2 Mod Notes
|
||||
|
||||
.block
|
||||
.block__header
|
||||
span.block__header__title Mod Notes
|
||||
= pagination
|
||||
|
||||
.block__content
|
||||
table.table
|
||||
thead
|
||||
tr
|
||||
td Object
|
||||
td Note
|
||||
td Time
|
||||
td Moderator
|
||||
td Actions
|
||||
tbody
|
||||
= for {body, note} <- @mod_notes do
|
||||
tr
|
||||
td
|
||||
= link_to_noted_thing(@conn, note.notable)
|
||||
|
||||
td
|
||||
== body
|
||||
|
||||
td
|
||||
= pretty_time note.created_at
|
||||
|
||||
td
|
||||
= link note.moderator.name, to: Routes.profile_path(@conn, :show, note.moderator)
|
||||
|
||||
td
|
||||
=> link "Edit", to: Routes.admin_mod_note_path(@conn, :edit, note)
|
||||
' •
|
||||
=> link "Delete", to: Routes.admin_mod_note_path(@conn, :delete, note), data: [confirm: "Are you really, really sure?", method: "delete"]
|
|
@ -0,0 +1,6 @@
|
|||
h2
|
||||
' New mod note for
|
||||
=> @conn.params["notable_type"]
|
||||
=> @conn.params["notable_id"]
|
||||
|
||||
= render PhilomenaWeb.Admin.ModNoteView, "_form.html", changeset: @changeset, action: Routes.admin_mod_note_path(@conn, :create), conn: @conn
|
|
@ -37,7 +37,7 @@
|
|||
' Pages
|
||||
|
||||
= if manages_mod_notes?(@conn) do
|
||||
= link to: "#", class: "header__link" do
|
||||
= link to: Routes.admin_mod_note_path(@conn, :index), class: "header__link" do
|
||||
i.fa.fa-fw.fa-sticky-note>
|
||||
' Mod Notes
|
||||
|
||||
|
|
21
lib/philomena_web/views/admin/mod_note_view.ex
Normal file
21
lib/philomena_web/views/admin/mod_note_view.ex
Normal file
|
@ -0,0 +1,21 @@
|
|||
defmodule PhilomenaWeb.Admin.ModNoteView do
|
||||
use PhilomenaWeb, :view
|
||||
|
||||
alias Philomena.Users.User
|
||||
alias Philomena.Reports.Report
|
||||
alias Philomena.DnpEntries.DnpEntry
|
||||
|
||||
def link_to_noted_thing(conn, %DnpEntry{requesting_user: user} = dnp_entry),
|
||||
do: link("#{user.name}'s DNP entry", to: Routes.dnp_entry_path(conn, :show, dnp_entry))
|
||||
|
||||
def link_to_noted_thing(conn, %Report{user: nil} = report),
|
||||
do: link("Report #{report.id}", to: Routes.admin_report_path(conn, :show, report))
|
||||
|
||||
def link_to_noted_thing(conn, %Report{user: user} = report),
|
||||
do: link("Report #{report.id} by #{user.name}", to: Routes.admin_report_path(conn, :show, report))
|
||||
|
||||
def link_to_noted_thing(conn, %User{} = user),
|
||||
do: link("User #{user.name}", to: Routes.profile_path(conn, :show, user))
|
||||
|
||||
def link_to_noted_thing(_conn, notable), do: "Item permanently deleted"
|
||||
end
|
Loading…
Reference in a new issue