3.4 KiB · text History 6280797
defmodule GitGudWeb.OrgLive.Moderation do
@moduledoc """
Org admins' moderation page: reports about content in any repo the
org owns, and bans that apply across all of them.
Before this, a report could only be seen by an instance admin, so an
org had no way to learn that its own content had been reported.
"""
use GitGudWeb, :live_view
import GitGudWeb.ModerationAdminComponents
alias GitGud.Moderation
alias GitGud.Organizations
alias GitGud.Organizations.Organization
alias GitGud.Reports
alias GitGudWeb.ModerationActions
@impl true
def mount(%{"handle" => handle}, _session, socket) do
org = Organizations.get_organization_by_handle!(handle)
user = socket.assigns.current_scope.user
if Organizations.org_admin?(org, user) do
{:ok,
socket
|> assign(:org, org)
|> assign(:scope, org)
|> assign(:moderator, user)
|> assign(:page_title, "Moderation — @#{org.handle}")
|> reload()}
else
{:ok,
socket
|> put_flash(:error, "Admins only.")
|> push_navigate(to: ~p"/orgs/#{org.handle}")}
end
end
defp reload(socket) do
org = socket.assigns.org
reports = Reports.list_open_for_org(org)
socket
|> assign(:reports, reports)
|> assign(:previews, Map.new(reports, &{&1.id, Reports.preview(&1)}))
|> assign(:bans, Moderation.list_bans(org))
end
@impl true
def handle_event("dismiss_report", %{"id" => id}, socket),
do: {:noreply, ModerationActions.dismiss_report(socket, id, &reload/1)}
def handle_event("action_report", %{"id" => id}, socket),
do: {:noreply, ModerationActions.action_report(socket, id, &reload/1)}
def handle_event("moderate_report", %{"id" => id}, socket),
do: {:noreply, ModerationActions.moderate_report(socket, id, &reload/1)}
def handle_event("ban_reported_author", %{"id" => id}, socket),
do: {:noreply, ModerationActions.ban_reported_author(socket, id, &reload/1)}
def handle_event("ban_user", params, socket),
do: {:noreply, ModerationActions.ban_user(socket, params, &reload/1)}
def handle_event("lift_ban", %{"id" => id}, socket),
do: {:noreply, ModerationActions.lift_ban(socket, id, &reload/1)}
@impl true
def render(assigns) do
~H"""
<Layouts.app flash={@flash} current_scope={@current_scope}>
<div class="space-y-6 max-w-3xl">
<header>
<p class="text-xs opacity-60">
<.link navigate={~p"/orgs/#{@org.handle}"} class="link link-hover">
{Organization.display(@org)}
</.link>
</p>
<h1 class="text-xl font-semibold">Moderation</h1>
<p class="text-sm opacity-70 mt-1">
Covers every repository {Organization.display(@org)} owns.
</p>
</header>
<section>
<h2 class="font-semibold text-sm mb-2">
Open reports
<span :if={@reports != []} class="badge badge-sm badge-warning ml-1">
{length(@reports)}
</span>
</h2>
<.report_queue reports={@reports} previews={@previews} />
</section>
<section>
<h2 class="font-semibold text-sm mb-2">Ban someone</h2>
<.ban_form scope_label="organization" />
</section>
<section>
<h2 class="font-semibold text-sm mb-2">Bans</h2>
<.ban_list bans={@bans} scope_label="organization" />
</section>
</div>
</Layouts.app>
"""
end
end