Merge remote-tracking branch 'origin/staff-tools'

This commit is contained in:
byte[] 2019-12-06 17:57:26 -05:00
commit 2a9cbb0ff0
23 changed files with 1429 additions and 752 deletions

View file

@ -24,13 +24,32 @@ module.exports = {
sass: {
mode: 'native',
options: {
includePaths: ['css', 'node_modules/font-awesome/scss']
includePaths: ['css', 'node_modules/@fortawesome/fontawesome-free/scss']
}
},
copycat: {
fonts: ['node_modules/font-awesome/fonts'],
fonts: ['node_modules/@fortawesome/fontawesome-free/webfonts'],
verbose: false,
onlyChanged: true
},
postcss: {
processors: [
require('autoprefixer')({
overrideBrowserslist: [
'last 2 Android versions',
'last 2 Chrome versions',
'last 2 ChromeAndroid versions',
'last 2 Edge versions',
'last 1 Explorer version',
'last 1 ExplorerMobile versions',
'last 2 Firefox versions',
'last 2 FirefoxAndroid versions',
'last 2 iOS versions',
'last 2 Opera versions'
],
add: true
})
]
}
},
conventions: {

View file

@ -11,8 +11,14 @@
@import "global";
@import "../../node_modules/font-awesome/scss/font-awesome.scss";
@import "../../node_modules/normalize-scss/sass/_normalize.scss";
// Because FA is a SPECIAL SNOWFLAKE.
$fa-font-path: "/fonts";
@import "../../node_modules/@fortawesome/fontawesome-free/scss/fontawesome.scss";
@import "../../node_modules/@fortawesome/fontawesome-free/scss/solid.scss";
@import "../../node_modules/@fortawesome/fontawesome-free/scss/regular.scss";
@import "../../node_modules/@fortawesome/fontawesome-free/scss/brands.scss";
@import "../../node_modules/normalize-scss/sass/normalize/import-now";
body {
background-color: $background_color;

1871
assets/package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -6,14 +6,15 @@
"dependencies": {
"brunch": "^2.10.17",
"copycat-brunch": "^1.1.1",
"font-awesome": "^4.7.0"
"@fortawesome/fontawesome-free": "^5.11.2"
},
"devDependencies": {
"acorn": "^7.0.0",
"autoprefixer": "^9.5.1",
"acorn": "^7.1.0",
"autoprefixer": "^9.7.3",
"normalize-scss": "^7.0.1",
"rollup-brunch": "git+https://github.com/liamwhite/rollup-brunch#31967fc",
"sass-brunch": "git+https://github.com/brunch/sass-brunch#e9c0bfe",
"rollup-brunch": "git+https://github.com/liamwhite/rollup-brunch.git#31967fc",
"sass-brunch": "git+https://github.com/brunch/sass-brunch.git#e9c0bfe",
"spostcss-brunch": "git+https://github.com/Meow/spostcss-brunch.git#b64df45",
"uglify-js-brunch": "^2.10.0"
}
}

View file

@ -101,4 +101,14 @@ defmodule Philomena.DnpEntries do
def change_dnp_entry(%DnpEntry{} = dnp_entry) do
DnpEntry.changeset(dnp_entry, %{})
end
def count_dnp_entries(user) do
if Canada.Can.can?(user, :manage, DnpEntry) do
DnpEntry
|> where([dnp], dnp.aasm_state in ["requested", "claimed", "acknowledged"])
|> Repo.aggregate(:count, :id)
else
nil
end
end
end

View file

@ -114,4 +114,14 @@ defmodule Philomena.DuplicateReports do
def change_duplicate_report(%DuplicateReport{} = duplicate_report) do
DuplicateReport.changeset(duplicate_report, %{})
end
def count_duplicate_reports(user) do
if Canada.Can.can?(user, :manage, DuplicateReport) do
DuplicateReport
|> where(state: "open")
|> Repo.aggregate(:count, :id)
else
nil
end
end
end

View file

@ -116,4 +116,14 @@ defmodule Philomena.Reports do
report
end
def count_reports(user) do
if Canada.Can.can?(user, :manage, Report) do
Report
|> where(open: true)
|> Repo.aggregate(:count, :id)
else
nil
end
end
end

View file

@ -104,4 +104,14 @@ defmodule Philomena.UserLinks do
def change_user_link(%UserLink{} = user_link) do
UserLink.changeset(user_link, %{})
end
def count_user_links(user) do
if Canada.Can.can?(user, :edit, UserLink) do
UserLink
|> where(aasm_state: "unverified")
|> Repo.aggregate(:count, :id)
else
nil
end
end
end

View file

@ -0,0 +1,48 @@
defmodule PhilomenaWeb.AdminCountersPlug do
@moduledoc """
This plug stores the counts used by the admin bar.
## Example
plug PhilomenaWeb.AdminCountersPlug
"""
alias Plug.Conn
alias Philomena.DuplicateReports
alias Philomena.Reports
alias Philomena.UserLinks
alias Philomena.DnpEntries
import Plug.Conn, only: [assign: 3]
@doc false
@spec init(any()) :: any()
def init(opts), do: opts
@doc false
@spec call(Plug.Conn.t()) :: Plug.Conn.t()
def call(conn), do: call(conn, nil)
@doc false
@spec call(Plug.Conn.t(), any()) :: Plug.Conn.t()
def call(conn, _opts) do
user = conn.assigns.current_user
maybe_assign_admin_metrics(conn, user, staff?(user))
end
defp maybe_assign_admin_metrics(conn, _user, false), do: conn
defp maybe_assign_admin_metrics(conn, user, true) do
duplicate_reports = DuplicateReports.count_duplicate_reports(user)
reports = Reports.count_reports(user)
user_links = UserLinks.count_user_links(user)
dnps = DnpEntries.count_dnp_entries(user)
conn
|> assign(:duplicate_report_count, duplicate_reports)
|> assign(:report_count, reports)
|> assign(:user_link_count, user_links)
|> assign(:dnp_entry_count, dnps)
end
defp staff?(%{role: role}) when role in ["assistant", "moderator", "admin"], do: true
defp staff?(_user), do: false
end

View file

@ -20,6 +20,7 @@ defmodule PhilomenaWeb.Router do
plug PhilomenaWeb.ForumListPlug
plug PhilomenaWeb.FilterSelectPlug
plug PhilomenaWeb.ChannelPlug
plug PhilomenaWeb.AdminCountersPlug
end
pipeline :api do

View file

@ -2,14 +2,10 @@ article.block.communication id="comment_#{@comment.id}"
.block__content.flex.flex--no-wrap
.flex__fixed.spacing-right
= render PhilomenaWeb.UserAttributionView, "_anon_user_avatar.html", object: @comment, conn: @conn
.flex__grow.communication__body
span.communication__body__sender-name = render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: @comment, awards: true, conn: @conn
br
= render PhilomenaWeb.UserAttributionView, "_anon_user_title.html", object: @comment, conn: @conn
.communication__body__text
= if @comment.hidden_from_users do
strong.comment_deleted
@ -17,10 +13,20 @@ article.block.communication id="comment_#{@comment.id}"
=> @comment.deletion_reason
- else
==<> @body
.block__content.communication__options
.flex.flex--wrap.flex--spaced-out
= render PhilomenaWeb.CommentView, "_comment_options.html", comment: @comment, conn: @conn
= if can?(@conn, :hide, @comment) do
.js-staff-action
/ todo: make delete button work
a.communication__interaction.togglable-delete-form-link href="#"
i.fa.fa-times
=<> "Delete"
= if can?(@conn, :manage, @comment) do
.communication__info
=<> link_to_ip(@comment.ip)
.communication__info
=<> link_to_fingerprint(@comment.fingerprint)
/- if can?(:hide, Comment)
/ .js-staff-action
/ - if !comment.hidden_from_users && !comment.destroyed_content

View file

@ -2,7 +2,7 @@ div
p
= if can?(@conn, :edit_description, @image) do
a.button#edit-description href="#" data-click-focus="#description" data-click-hide=".image-description" data-click-show="#description-form" title="Edit description" accessKey="d"
i.fa.fa-pencil>
i.fas.fa-edit>
' Description:
- else

View file

@ -51,8 +51,14 @@
div
' Uploaded
=> pretty_time(@image.created_at)
span.image_uploader
' by
=> render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: @image, awards: true, conn: @conn
= if can?(@conn, :manage, @image) do
=<> link_to_ip(@image.ip)
=<> link_to_fingerprint(@image.fingerprint)
a href="#"
i.fa.fa-edit
span.image-size
| &nbsp;
= @image.image_width

View file

@ -23,7 +23,7 @@
.flex.flex--wrap#image-source
p
a.button.button--separate-right#edit-source data-click-focus="#source-field" data-click-hide="#image-source" data-click-show="#source-form" title="Edit source" accessKey="s"
i.fa.fa-pencil>
i.fas.fa-edit>
' Source:
p

View file

@ -52,7 +52,7 @@
.tagsauce
.block
a.button.js-tag-sauce-toggle#edit-tags data-click-toggle=".tagsauce, .js-imageform" data-click-focus=".js-taginput-plain:not(.hidden), .js-taginput-input" title="Edit tags" accessKey="t"
i.fa.fa-pencil>
i.fas.fa-edit>
' Tags:
a.button.button--link.button--separate-left href=Routes.image_tag_change_path(@conn, :index, @image) title="Tag history"

View file

@ -6,7 +6,7 @@
.block
.block__header.block__header--js-tabbed
a.selected href="#" data-click-tab="write"
i.fa.fa-pencil>
i.fas.fa-edit>
' Edit
a href="#" data-click-tab="preview"

View file

@ -10,6 +10,7 @@ elixir:
=> pluralize("comment", "comments", @image.comments_count)
' posted
button.button#js-refresh-comments title="Refresh" data-disable-with="..."
i.fa.fa-sync
span.hide-mobile<> Refresh
= for {comment, body} <- @comments do

View file

@ -73,7 +73,7 @@ header.header
i.fa.fa-fw.fa-comments>
| Comments
a.header__link href="/posts?pq=my:posts"
i.fa.fa-fw.fa-pencil>
i.fas.fa-fw.fa-pen-square>
| Posts
a.header__link href='/user_links'
i.fa.fa-fw.fa-link>
@ -88,7 +88,7 @@ header.header
i.fa.fa-fw.fa-user>
| Account
a.header__link href="/session" data-method='delete'
i.fa.fa-fw.fa-sign-out>
i.fa.fa-fw.fa-sign-out-alt>
| Logout
- else
a.header__link.hide-mobile href="/filters"
@ -107,5 +107,5 @@ header.header
nav.header.header--secondary
.flex.flex--centered.flex--spaced-out.flex--wrap
= render PhilomenaWeb.LayoutView, "_header_navigation.html", assigns
/- if current_user.try(:staff?)
include _header_staff_links.html
= if @current_user.role != "user" do
= render PhilomenaWeb.LayoutView, "_header_staff_links.html", assigns

View file

@ -0,0 +1,85 @@
/ Dummy view for the admin bar
.flex.flex--centered.header--secondary__admin-links.stretched-mobile-links.js-staff-action
.dropdown.hide-mobile
/a.header__link title="Admin"
' A
i.fa.fa-caret-down
.dropdown__content.js-burger-links
/ todo: make some sort of permission for this
= if @current_user.role == "admin" do
= link to: "/admin/flipper", class: "header__link" do
i.fa.fa-fw.fa-toggle-on>
' Site Settings
= if can?(@conn, :manage, SiteNotice) do
= link to: "/admin/site_notices", class: "header__link" do
i.fa.fa-fw.fa-info-circle>
' Site Notices
= if can?(@conn, :manage, Tag) do
= link to: "#", class: "header__link" do
i.fa.fa-fw.fa-tags>
' Tags
= if can?(@conn, :mod_read, User) do
= link to: "#", class: "header__link" do
i.fa.fa-fw.fa-users>
' Users
= if can?(@conn, :mod_read, Comment) do
= link to: "#", class: "header__link" do
i.fa.fa-fw.fa-comments>
' Comments
= if can?(@conn, :mod_read, Forum) do
= link to: "#", class: "header__link" do
i.fa.fa-fw.fa-paragraph>
' Forums
= if can?(@conn, :manage, Advert) do
= link to: "#", class: "header__link" do
i.fa.fa-fw.fa-shopping-bag>
' Advertisements
= if can?(@conn, :award, Badge) do
= link to: "#", class: "header__link" do
i.fa.fa-fw.fa-trophy>
' Badges
= if can?(@conn, :manage, StaticPage) do
= link to: "#", class: "header__link" do
i.fa.fa-fw.fa-sticky-note>
' Pages
= if can?(@conn, :manage, ModNote) do
= link to: "#", class: "header__link" do
i.fa.fa-fw.fa-sticky-note>
' Mod Notes
= if @duplicate_report_count do
= link to: "#", class: "header__link", title: "Duplicates" do
' D
span.header__counter__admin
= @duplicate_report_count
= if @report_count do
= link to: "#", class: "header__link", title: "Reports" do
' R
span.header__counter__admin
= @report_count
= if @user_link_count do
= link to: "#", class: "header__link", title: "User Links" do
' L
span.header__counter__admin
= @user_link_count
= if @dnp_entry_count do
= link to: "#", class: "header__link", title: "DNP Requests" do
' S
span.header__counter__admin
= @dnp_entry_count
.dropdown.hide-mobile
a.header__link title="Bans"
' B
i.fa.fa-caret-down
.dropdown__content.dropdown__content-right.js-burger-links
= if can?(@conn, :mod_read, UserBan) do
= link to: "#", class: "header__link" do
i.fa.fa-fw.fa-user>
' User Bans
= if can?(@conn, :mod_read, SubnetBan) do
= link to: "#", class: "header__link" do
i.fab.fa-fw.fa-internet-explorer>
' IP Bans
= if can?(@conn, :mod_read, FingerprintBan) do
= link to: "#", class: "header__link" do
i.fa.fa-fw.fa-desktop>
' FP Bans

View file

@ -2,13 +2,10 @@ article.block.communication id="post_#{@post.id}"
.block__content.flex.flex--no-wrap
.flex__fixed.spacing-right
= render PhilomenaWeb.UserAttributionView, "_anon_user_avatar.html", object: @post, conn: @conn
.flex__grow.communication__body
span.communication__body__sender-name = render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: @post, awards: true, conn: @conn
br
= render PhilomenaWeb.UserAttributionView, "_anon_user_title.html", object: @post, conn: @conn
.communication__body__text
= if @post.hidden_from_users do
strong.comment_deleted
@ -16,12 +13,19 @@ article.block.communication id="post_#{@post.id}"
=> @post.deletion_reason
- else
==<> @body
.block__content.communication__options
.flex.flex--wrap.flex--spaced-out
= render PhilomenaWeb.PostView, "_post_options.html", conn: @conn, post: @post
= if can?(@conn, :hide, @post) do
/ todo: make post deletion work
a.communication__interaction.togglable-delete-form-link href="#"
i.fa.fa-times
=<> "Delete"
= if can?(@conn, :manage, @post) do
.communication__info
=<> link_to_ip(@post.ip)
.communication__info
=<> link_to_fingerprint(@post.fingerprint)
/- if can?(:hide, Post)
/ .js-staff-action
/ - if !post.hidden_from_users && !post.destroyed_content

View file

@ -6,7 +6,7 @@
.block
.block__header.block__header--js-tabbed
a.selected href="#" data-click-tab="write"
i.fa.fa-pencil>
i.fas.fa-pencil-alt>
' Create a Topic
a href="#" data-click-tab="preview"

View file

@ -6,7 +6,7 @@
.block
.block__header.block__header--js-tabbed
a.selected href="#" data-click-tab="write"
i.fa.fa-pencil>
i.fas.fa-edit>
' Edit
a href="#" data-click-tab="preview"

View file

@ -113,4 +113,17 @@ defmodule PhilomenaWeb.AppView do
])
|> to_string()
end
defp text_or_na(text), do: text
defp text_or_na(nil), do: "N/A"
# todo: make ip a real link
def link_to_ip(ip) do
link(text_or_na(ip), to: "#")
end
# todo: make fp a real link
def link_to_fingerprint(fp) do
link(String.slice(text_or_na(fp), 0..6), to: "#")
end
end