diff --git a/lib/philomena/dnp_entries.ex b/lib/philomena/dnp_entries.ex index f934b254..7146da31 100644 --- a/lib/philomena/dnp_entries.ex +++ b/lib/philomena/dnp_entries.ex @@ -49,9 +49,11 @@ defmodule Philomena.DnpEntries do {:error, %Ecto.Changeset{}} """ - def create_dnp_entry(attrs \\ %{}) do + def create_dnp_entry(user, tags, attrs \\ %{}) do + tag = Enum.find(tags, &to_string(&1.id) == attrs["tag_id"]) + %DnpEntry{} - |> DnpEntry.changeset(attrs) + |> DnpEntry.creation_changeset(attrs, tag, user) |> Repo.insert() end @@ -67,9 +69,17 @@ defmodule Philomena.DnpEntries do {:error, %Ecto.Changeset{}} """ - def update_dnp_entry(%DnpEntry{} = dnp_entry, attrs) do + def update_dnp_entry(%DnpEntry{} = dnp_entry, tags, attrs) do + tag = Enum.find(tags, &to_string(&1.id) == attrs["tag_id"]) + dnp_entry - |> DnpEntry.changeset(attrs) + |> DnpEntry.update_changeset(attrs, tag) + |> Repo.update() + end + + def transition_dnp_entry(%DnpEntry{} = dnp_entry, user, new_state) do + dnp_entry + |> DnpEntry.transition_changeset(user, new_state) |> Repo.update() end diff --git a/lib/philomena/dnp_entries/dnp_entry.ex b/lib/philomena/dnp_entries/dnp_entry.ex index bac17756..6f8c9d1a 100644 --- a/lib/philomena/dnp_entries/dnp_entry.ex +++ b/lib/philomena/dnp_entries/dnp_entry.ex @@ -11,12 +11,12 @@ defmodule Philomena.DnpEntries.DnpEntry do belongs_to :tag, Tag field :aasm_state, :string, default: "requested" - field :dnp_type, :string - field :conditions, :string - field :reason, :string + field :dnp_type, :string, default: "" + field :conditions, :string, default: "" + field :reason, :string, default: "" field :hide_reason, :boolean, default: false - field :instructions, :string - field :feedback, :string + field :instructions, :string, default: "" + field :feedback, :string, default: "" timestamps(inserted_at: :created_at) end @@ -27,4 +27,67 @@ defmodule Philomena.DnpEntries.DnpEntry do |> cast(attrs, []) |> validate_required([]) end + + def update_changeset(dnp_entry, attrs, tag) do + dnp_entry + |> cast(attrs, [:conditions, :reason, :hide_reason, :instructions, :feedback, :dnp_type]) + |> put_change(:tag_id, tag.id) + |> validate_required([:reason, :dnp_type]) + |> validate_inclusion(:dnp_type, types()) + |> validate_conditions() + |> foreign_key_constraint(:tag_id, name: "fk_rails_473a736b4a") + end + + def creation_changeset(dnp_entry, attrs, tag, user) do + dnp_entry + |> change(requesting_user_id: user.id) + |> update_changeset(attrs, tag) + end + + def transition_changeset(dnp_entry, user, new_state) do + dnp_entry + |> change(modifying_user_id: user.id) + |> change(aasm_state: new_state) + |> validate_inclusion(:aasm_state, states()) + end + + defp validate_conditions(%Ecto.Changeset{changes: %{dnp_type: "Other"}} = changeset), + do: validate_required(changeset, [:conditions]) + defp validate_conditions(changeset), + do: changeset + + def types do + [ + "No Edits", + "Artist Tag Change", + "Uploader Credit Change", + "Certain Type/Location Only", + "With Permission Only", + "Artist Upload Only", + "Other" + ] + end + + def reasons do + [ + {"No Edits", "I would like to prevent edited versions of my artwork from being uploaded in the future"}, + {"Artist Tag Change", "I would like my artist tag to be changed to something that can not be connected to my current name"}, + {"Uploader Credit Change", "I would like the uploader credit for already existing uploads of my art to be assigned to me"}, + {"Certain Type/Location Only", "I only want to allow art of a certain type or from a certain location to be uploaded to Derpibooru"}, + {"With Permission Only", "I only want people with my permission to be allowed to upload my art to Derpibooru"}, + {"Artist Upload Only", "I want to be the only person allowed to upload my art to Derpibooru"}, + {"Other", "I would like a DNP entry under other conditions"} + ] + end + + def states do + [ + "requested", + "claimed", + "listed", + "rescinded", + "acknowledged", + "closed" + ] + end end diff --git a/lib/philomena/users/ability.ex b/lib/philomena/users/ability.ex index d2264259..7a658c94 100644 --- a/lib/philomena/users/ability.ex +++ b/lib/philomena/users/ability.ex @@ -4,6 +4,7 @@ defimpl Canada.Can, for: [Atom, Philomena.Users.User] do alias Philomena.Commissions.Commission alias Philomena.Conversations.Conversation alias Philomena.DuplicateReports.DuplicateReport + alias Philomena.DnpEntries.DnpEntry alias Philomena.Images.Image alias Philomena.Forums.Forum alias Philomena.Topics.Topic @@ -60,6 +61,11 @@ defimpl Canada.Can, for: [Atom, Philomena.Users.User] do # Reveal anon users def can?(%User{role: "moderator"}, :reveal_anon, _object), do: true + # Show the DNP list + def can?(%User{role: "moderator"}, :index, DnpEntry), do: true + def can?(%User{role: "moderator"}, :edit, %DnpEntry{}), do: true + def can?(%User{role: "moderator"}, :update, %DnpEntry{}), do: true + # # Assistants can... # @@ -172,7 +178,7 @@ defimpl Canada.Can, for: [Atom, Philomena.Users.User] do def can?(_user, :show, %User{}), do: true # View and create DNP entries - def can?(%User{}, action, DnpEntry) when action in [:new, :create, :index], do: true + def can?(%User{}, action, DnpEntry) when action in [:new, :create], do: true def can?(%User{id: id}, :show, %DnpEntry{requesting_user_id: id}), do: true def can?(%User{id: id}, :show_reason, %DnpEntry{requesting_user_id: id}), do: true def can?(%User{id: id}, :show_feedback, %DnpEntry{requesting_user_id: id}), do: true diff --git a/lib/philomena_web/controllers/admin/dnp_entry/transition_controller.ex b/lib/philomena_web/controllers/admin/dnp_entry/transition_controller.ex new file mode 100644 index 00000000..16e65621 --- /dev/null +++ b/lib/philomena_web/controllers/admin/dnp_entry/transition_controller.ex @@ -0,0 +1,30 @@ +defmodule PhilomenaWeb.Admin.DnpEntry.TransitionController do + use PhilomenaWeb, :controller + + alias Philomena.DnpEntries.DnpEntry + alias Philomena.DnpEntries + + plug :verify_authorized + plug :load_resource, model: DnpEntry, only: [:create], id_name: "dnp_entry_id", persisted: true + + def create(conn, %{"state" => new_state}) do + case DnpEntries.transition_dnp_entry(conn.assigns.dnp_entry, conn.assigns.current_user, new_state) do + {:ok, dnp_entry} -> + conn + |> put_flash(:info, "Successfully updated DNP entry.") + |> redirect(to: Routes.dnp_entry_path(conn, :show, dnp_entry)) + + {:error, _changeset} -> + conn + |> put_flash(:error, "Failed to update DNP entry!") + |> redirect(external: conn.assigns.referrer) + end + end + + defp verify_authorized(conn, _opts) do + case Canada.Can.can?(conn.assigns.current_user, :index, DnpEntry) do + true -> conn + _false -> PhilomenaWeb.NotAuthorizedPlug.call(conn) + end + end +end diff --git a/lib/philomena_web/controllers/admin/dnp_entry_controller.ex b/lib/philomena_web/controllers/admin/dnp_entry_controller.ex new file mode 100644 index 00000000..23448d44 --- /dev/null +++ b/lib/philomena_web/controllers/admin/dnp_entry_controller.ex @@ -0,0 +1,60 @@ +defmodule PhilomenaWeb.Admin.DnpEntryController do + use PhilomenaWeb, :controller + + alias Philomena.Textile.Renderer + alias Philomena.DnpEntries.DnpEntry + alias Philomena.Repo + import Ecto.Query + + plug :verify_authorized + plug :load_resource, model: DnpEntry, only: [:show, :edit, :update] + + def index(conn, %{"states" => states}) when is_list(states) do + DnpEntry + |> where([d], d.aasm_state in ^states) + |> load_entries(conn) + end + + def index(conn, %{"q" => q}) when is_binary(q) do + q = to_ilike(q) + + DnpEntry + |> join(:inner, [d], _ in assoc(d, :tag)) + |> join(:inner, [d, _t], _ in assoc(d, :requesting_user)) + |> where([d, t, u], ilike(u.name, ^q) or ilike(t.name, ^q) or ilike(d.reason, ^q) or ilike(d.conditions, ^q) or ilike(d.instructions, ^q)) + |> load_entries(conn) + end + + def index(conn, _params) do + DnpEntry + |> where([d], d.aasm_state in ["requested", "claimed", "rescinded", "acknowledged"]) + |> load_entries(conn) + end + + defp load_entries(dnp_entries, conn) do + dnp_entries = + dnp_entries + |> preload([:tag, :requesting_user, :modifying_user]) + |> order_by(desc: :updated_at) + |> Repo.paginate(conn.assigns.scrivener) + + bodies = + dnp_entries + |> Enum.map(&%{body: &1.conditions}) + |> Renderer.render_collection(conn) + + dnp_entries = + %{dnp_entries | entries: Enum.zip(bodies, dnp_entries.entries)} + + render(conn, "index.html", layout_class: "layout--wide", dnp_entries: dnp_entries) + end + + defp verify_authorized(conn, _opts) do + case Canada.Can.can?(conn.assigns.current_user, :index, DnpEntry) do + true -> conn + _false -> PhilomenaWeb.NotAuthorizedPlug.call(conn) + end + end + + defp to_ilike(query), do: "%" <> query <> "%" +end diff --git a/lib/philomena_web/controllers/dnp_entry_controller.ex b/lib/philomena_web/controllers/dnp_entry_controller.ex index 064f766b..be2de467 100644 --- a/lib/philomena_web/controllers/dnp_entry_controller.ex +++ b/lib/philomena_web/controllers/dnp_entry_controller.ex @@ -1,23 +1,35 @@ defmodule PhilomenaWeb.DnpEntryController do use PhilomenaWeb, :controller - # alias Philomena.DnpEntries alias Philomena.DnpEntries.DnpEntry alias Philomena.Textile.Renderer + alias Philomena.DnpEntries alias Philomena.Tags.Tag alias Philomena.Repo import Ecto.Query - plug :load_and_authorize_resource, model: DnpEntry, only: [:show], preload: [:tag] + plug PhilomenaWeb.FilterBannedUsersPlug when action in [:new, :create] + plug :load_and_authorize_resource, model: DnpEntry, only: [:show, :edit, :update], preload: [:tag] + + def index(%{assigns: %{current_user: user}} = conn, %{"mine" => _mine}) when not is_nil(user) do + DnpEntry + |> where(requesting_user_id: ^user.id) + |> preload(:tag) + |> order_by(asc: :created_at) + |> load_entries(conn, true) + end def index(conn, _params) do - dnp_entries = - DnpEntry - |> where(aasm_state: "listed") - |> join(:inner, [d], t in Tag, on: d.tag_id == t.id) - |> preload([:tag]) - |> order_by([d, t], asc: t.name_in_namespace) - |> Repo.paginate(conn.assigns.scrivener) + DnpEntry + |> where(aasm_state: "listed") + |> join(:inner, [d], t in Tag, on: d.tag_id == t.id) + |> preload(:tag) + |> order_by([_d, t], asc: t.name_in_namespace) + |> load_entries(conn, false) + end + + defp load_entries(dnp_entries, conn, status) do + dnp_entries = Repo.paginate(dnp_entries, conn.assigns.scrivener) bodies = dnp_entries @@ -27,7 +39,7 @@ defmodule PhilomenaWeb.DnpEntryController do dnp_entries = %{dnp_entries | entries: Enum.zip(bodies, dnp_entries.entries)} - render(conn, "index.html", layout_class: "layout--medium", dnp_entries: dnp_entries) + render(conn, "index.html", layout_class: "layout--medium", dnp_entries: dnp_entries, status_column: status) end def show(conn, _params) do @@ -45,4 +57,51 @@ defmodule PhilomenaWeb.DnpEntryController do render(conn, "show.html", dnp_entry: dnp_entry, conditions: conditions, reason: reason, instructions: instructions) end + + def new(conn, _params) do + changeset = DnpEntries.change_dnp_entry(%DnpEntry{}) + render(conn, "new.html", changeset: changeset, selectable_tags: selectable_tags(conn)) + end + + def create(conn, %{"dnp_entry" => dnp_entry_params}) do + case DnpEntries.create_dnp_entry(conn.assigns.current_user, selectable_tags(conn), dnp_entry_params) do + {:ok, dnp_entry} -> + conn + |> put_flash(:info, "Successfully submitted DNP request.") + |> redirect(to: Routes.dnp_entry_path(conn, :show, dnp_entry)) + + {:error, changeset} -> + render(conn, "new.html", changeset: changeset, selectable_tags: selectable_tags(conn)) + end + end + + def edit(conn, _params) do + changeset = DnpEntries.change_dnp_entry(conn.assigns.dnp_entry) + render(conn, "edit.html", changeset: changeset, selectable_tags: selectable_tags(conn)) + end + + def update(conn, %{"dnp_entry" => dnp_entry_params}) do + case DnpEntries.update_dnp_entry(conn.assigns.dnp_entry, selectable_tags(conn), dnp_entry_params) do + {:ok, dnp_entry} -> + conn + |> put_flash(:info, "Successfully submupdateditted DNP request.") + |> redirect(to: Routes.dnp_entry_path(conn, :show, dnp_entry)) + + {:error, changeset} -> + render(conn, "edit.html", changeset: changeset, selectable_tags: selectable_tags(conn)) + end + end + + defp selectable_tags(conn) do + case not is_nil(conn.params["tag_id"]) and Canada.Can.can?(conn.assigns.current_user, :index, DnpEntry) do + true -> [Repo.get!(Tag, conn.params["tag_id"])] + false -> linked_tags(conn) + end + end + + defp linked_tags(conn) do + conn.assigns.current_user + |> Repo.preload(:linked_tags) + |> Map.get(:linked_tags) + end end diff --git a/lib/philomena_web/router.ex b/lib/philomena_web/router.ex index cfe42c31..6aaca70b 100644 --- a/lib/philomena_web/router.ex +++ b/lib/philomena_web/router.ex @@ -170,6 +170,8 @@ defmodule PhilomenaWeb.Router do resources "/subscription", Channel.SubscriptionController, only: [:create, :delete], singleton: true end + resources "/dnp", DnpEntryController, only: [:new, :create, :edit, :update] + resources "/ip_profiles", IpProfileController, only: [:show] resources "/fingerprint_profiles", FingerprintProfileController, only: [:show] @@ -184,6 +186,10 @@ defmodule PhilomenaWeb.Router do resources "/contact", UserLink.ContactController, only: [:create], singleton: true resources "/reject", UserLink.RejectController, only: [:create], singleton: true end + + resources "/dnp_entries", DnpEntryController, only: [:index] do + resources "/transition", DnpEntry.TransitionController, only: [:create], singleton: true + end end resources "/duplicate_reports", DuplicateReportController, only: [] do diff --git a/lib/philomena_web/templates/admin/dnp_entry/index.html.slime b/lib/philomena_web/templates/admin/dnp_entry/index.html.slime new file mode 100644 index 00000000..50f351dd --- /dev/null +++ b/lib/philomena_web/templates/admin/dnp_entry/index.html.slime @@ -0,0 +1,90 @@ +h2 Do-Not-Post Requests + += form_for :dnp_entry, Routes.admin_dnp_entry_path(@conn, :index), [method: "get", class: "hform"], fn f -> + .field + = text_input f, :q, name: :q, value: @conn.params["q"], class: "input hform__text", placeholder: "Search query", autocapitalize: "none" + = submit "Search", class: "hform__button button" + +- route = fn p -> Routes.admin_dnp_entry_path(@conn, :index, p) end +- pagination = render PhilomenaWeb.PaginationView, "_pagination.html", page: @dnp_entries, route: route, params: [states: state_param(@conn.params["states"])] + +.block + .block__header + = pagination + + span.block__header__title Display Only: + => link "All Open", to: Routes.admin_dnp_entry_path(@conn, :index, states: ~W(requested claimed rescinded acknowledged)) + => link "Listed", to: Routes.admin_dnp_entry_path(@conn, :index, states: ~W(listed)) + => link "Rescinded", to: Routes.admin_dnp_entry_path(@conn, :index, states: ~W(rescinded acknowledged)) + => link "Closed", to: Routes.admin_dnp_entry_path(@conn, :index, states: ~W(closed)) + + .block__content + table.table + thead + tr + td Tag + td Requesting User + td Type + td Conditions + td Status + td Created + td Modified + td Options + + tbody + = for {body, request} <- @dnp_entries do + tr + td + = render PhilomenaWeb.TagView, "_tag.html", tag: request.tag, conn: @conn + + td + = link request.requesting_user.name, to: Routes.profile_path(@conn, :show, request.requesting_user) + + td + = request.dnp_type + + td + == body + + td class=dnp_entry_row_class(request) + => pretty_state(request) + + = if request.modifying_user do + ' by + = link request.modifying_user.name, to: Routes.profile_path(@conn, :show, request.modifying_user) + + td + = pretty_time(request.created_at) + + td + = pretty_time(request.updated_at) + + td + => link "Show", to: Routes.dnp_entry_path(@conn, :show, request) + ' • + => link "Send PM", to: Routes.conversation_path(@conn, :new, recipient: request.requesting_user.name) + + = case request.aasm_state do + - s when s in ["requested", "claimed"] -> + ' • + => link "Claim", to: Routes.admin_dnp_entry_transition_path(@conn, :create, request, state: "claimed"), data: [method: "post", confirm: "Are you really, really sure?"] + ' • + => link "Approve", to: Routes.admin_dnp_entry_transition_path(@conn, :create, request, state: "listed"), data: [method: "post", confirm: "Are you really, really sure?"] + ' • + => link "Close", to: Routes.admin_dnp_entry_transition_path(@conn, :create, request, state: "closed"), data: [method: "post", confirm: "Are you really, really sure?"] + + - "listed" -> + ' • + => link "Rescind", to: Routes.admin_dnp_entry_transition_path(@conn, :create, request, state: "rescinded"), data: [method: "post", confirm: "Are you really, really sure?"] + ' • + = link "Close", to: Routes.admin_dnp_entry_transition_path(@conn, :create, request, state: "closed"), data: [method: "post", confirm: "Are you really, really sure?"] + + - s when s in ["rescinded", "acknowledged"] -> + ' • + => link "Claim", to: Routes.admin_dnp_entry_transition_path(@conn, :create, request, state: "acknowledged"), data: [method: "post", confirm: "Are you really, really sure?"] + ' • + = link "Close", to: Routes.admin_dnp_entry_transition_path(@conn, :create, request, state: "closed"), data: [method: "post", confirm: "Are you really, really sure?"] + + - _state -> + ' • + => link "Claim", to: Routes.admin_dnp_entry_transition_path(@conn, :create, request, state: "claimed"), data: [method: "post", confirm: "Are you really, really sure?"] diff --git a/lib/philomena_web/templates/dnp_entry/_form.html.slime b/lib/philomena_web/templates/dnp_entry/_form.html.slime new file mode 100644 index 00000000..e8164b7f --- /dev/null +++ b/lib/philomena_web/templates/dnp_entry/_form.html.slime @@ -0,0 +1,85 @@ += if show_steps?(@changeset) do + .block.block--fixed.block--success.walloftext + h3 Getting on the DNP list? + + p + ' We offer the DNP list in order to give artists the last say on their art, but we + ' won't deny that we are sad whenever we see good art and artists disappear. + ' Because we know that many who seek a DNP do so on their first contact with the site, + ' we'd be very grateful if you as the artist would like to give the site a shot first. + ' Why not upload some of your own art? The community might appreciate it more than you think. + + p + ' Do you wish to submit a DNP Request? + button.button.button--separate-left.js-dnp-yes data-click-show=".js-dnp-common-options" data-click-disable=".js-dnp-yes" + ' Yes + + .block.block--fixed.walloftext.js-dnp-common-options.hidden + h3 Options + + p + ' We are aware of several common reasons for why artists seek a DNP. + ' They include things such as unwanted edits or a wish to disassociate + ' their name from their artwork. Many of these concerns can be addressed + ' without removing art. + + p We have created several options for you below: + + ul.line-spacing + = for {type, description} <- reasons() do + li + = link description, to: "#", data: [click_show: ".js-dnp-form", click_hide: ".js-dnp-common-options", click_inputvalue: ".js-dnp-type", set_value: type] + += form_for @changeset, @action, fn f -> + = if @changeset.action do + .alert.alert-danger + p Oops, something went wrong! Please check the errors below. + + .block.js-dnp-form class=form_class(@changeset) + .block__header + span.block__header__title DNP Request Form + + .block__content + / Artist Tag + strong Artist Tag + p Select the artist tag you would like to request a DNP entry for + .field + = select f, :tag_id, selectable_options(@selectable_tags), class: "input" + = error_tag f, :tag_id + hr + / Conditions + strong Conditions + p If you selected "Other", or have other conditions applicable to your request, please enter them here. If someone always has permission to upload your artwork, enter their name here. (Optional) + .field + = textarea f, :conditions, class: "input input--wide", placeholder: "Conditions" + = error_tag f, :conditions + hr + / Reason + strong Reason For Request + p Please indicate the reason why you would like your artwork to be removed. (Required) + .field + = textarea f, :reason, class: "input input--wide", placeholder: "Reason", required: true + = error_tag f, :reason + .field + => checkbox f, :hide_reason, class: "checkbox" + = label f, :hide_reason, "Hide request reason" + p Only select this box if your request contains sensitive or private information that you do not wish to be publicly available. Reasons that do not contain such information will not be hidden. + hr + / Instructions + strong Instructions + p If you would like existing artwork to be removed under this request, please provide instructions, such as "Remove all art with my artist tag that contain the "edit" tag." (Optional) + .field + = textarea f, :instructions, class: "input input--wide", placeholder: "Instructions" + = error_tag f, :instructions + hr + / Feedback + strong Feedback + p If you have any additional feedback for the site staff, you may enter it here. (Optional) + .field + = textarea f, :feedback, class: "input input--wide", placeholder: "Feedback" + = error_tag f, :feedback + + / Option (hidden, set by script depending on the option chosen above) + = hidden_input f, :dnp_type, class: "js-dnp-type" + hr + = submit "Submit Request", class: "button" diff --git a/lib/philomena_web/templates/dnp_entry/edit.html.slime b/lib/philomena_web/templates/dnp_entry/edit.html.slime new file mode 100644 index 00000000..1201dfa1 --- /dev/null +++ b/lib/philomena_web/templates/dnp_entry/edit.html.slime @@ -0,0 +1,2 @@ +h2 Edit DNP Request += render PhilomenaWeb.DnpEntryView, "_form.html", changeset: @changeset, action: Routes.dnp_entry_path(@conn, :update, @dnp_entry), conn: @conn, selectable_tags: @selectable_tags diff --git a/lib/philomena_web/templates/dnp_entry/index.html.slime b/lib/philomena_web/templates/dnp_entry/index.html.slime index ef83c603..115ed2cf 100644 --- a/lib/philomena_web/templates/dnp_entry/index.html.slime +++ b/lib/philomena_web/templates/dnp_entry/index.html.slime @@ -26,16 +26,29 @@ h3 The List th Tag th Restriction th Conditions + = if @status_column do + th Status + th Created th Options tbody = for {body, entry} <- @dnp_entries do tr td = render PhilomenaWeb.TagView, "_tag.html", tag: entry.tag, conn: @conn + td = entry.dnp_type + td == body + + = if @status_column do + td + = pretty_state(entry) + + td + = pretty_time(entry.created_at) + td = link "More Info", to: Routes.dnp_entry_path(@conn, :show, entry) diff --git a/lib/philomena_web/templates/dnp_entry/new.html.slime b/lib/philomena_web/templates/dnp_entry/new.html.slime new file mode 100644 index 00000000..e6cbb325 --- /dev/null +++ b/lib/philomena_web/templates/dnp_entry/new.html.slime @@ -0,0 +1,2 @@ +h2 New DNP Request += render PhilomenaWeb.DnpEntryView, "_form.html", changeset: @changeset, action: Routes.dnp_entry_path(@conn, :create), conn: @conn, selectable_tags: @selectable_tags diff --git a/lib/philomena_web/templates/dnp_entry/show.html.slime b/lib/philomena_web/templates/dnp_entry/show.html.slime index b57a1b58..58257293 100644 --- a/lib/philomena_web/templates/dnp_entry/show.html.slime +++ b/lib/philomena_web/templates/dnp_entry/show.html.slime @@ -5,6 +5,9 @@ h2 .block .block__header span.block__header__title DNP Information + = if can?(@conn, :edit, @dnp_entry) do + = link "Edit listing", to: Routes.dnp_entry_path(@conn, :edit, @dnp_entry, tag_id: @dnp_entry.tag_id) + = link "Back to DNP List", to: Routes.dnp_entry_path(@conn, :index) .block__content @@ -45,4 +48,4 @@ h2 tr td Status: td - = String.capitalize(@dnp_entry.aasm_state) \ No newline at end of file + = String.capitalize(@dnp_entry.aasm_state) diff --git a/lib/philomena_web/templates/layout/_header_staff_links.html.slime b/lib/philomena_web/templates/layout/_header_staff_links.html.slime index 34126757..3bef6273 100644 --- a/lib/philomena_web/templates/layout/_header_staff_links.html.slime +++ b/lib/philomena_web/templates/layout/_header_staff_links.html.slime @@ -62,7 +62,7 @@ span.header__counter__admin = @user_link_count = if @dnp_entry_count do - = link to: "#", class: "header__link", title: "DNP Requests" do + = link to: Routes.admin_dnp_entry_path(@conn, :index), class: "header__link", title: "DNP Requests" do ' S span.header__counter__admin = @dnp_entry_count diff --git a/lib/philomena_web/views/admin/dnp_entry_view.ex b/lib/philomena_web/views/admin/dnp_entry_view.ex new file mode 100644 index 00000000..9cc552ff --- /dev/null +++ b/lib/philomena_web/views/admin/dnp_entry_view.ex @@ -0,0 +1,12 @@ +defmodule PhilomenaWeb.Admin.DnpEntryView do + use PhilomenaWeb, :view + + import PhilomenaWeb.DnpEntryView, only: [pretty_state: 1] + + def dnp_entry_row_class(%{aasm_state: state}) when state in ["closed", "listed"], do: "success" + def dnp_entry_row_class(%{aasm_state: state}) when state in ["claimed", "acknowledged"], do: "warning" + def dnp_entry_row_class(_dnp_entry), do: "danger" + + def state_param(states) when is_list(states), do: states + def state_param(_states), do: [] +end diff --git a/lib/philomena_web/views/dnp_entry_view.ex b/lib/philomena_web/views/dnp_entry_view.ex index 24a1077d..e9f9db47 100644 --- a/lib/philomena_web/views/dnp_entry_view.ex +++ b/lib/philomena_web/views/dnp_entry_view.ex @@ -1,3 +1,28 @@ defmodule PhilomenaWeb.DnpEntryView do use PhilomenaWeb, :view + + def reasons do + Philomena.DnpEntries.DnpEntry.reasons() + end + + def form_class(changeset) do + case show_steps?(changeset) do + true -> "hidden" + false -> nil + end + end + + def selectable_options(tags) do + Enum.map(tags, &{&1.name, &1.id}) + end + + def pretty_state(%{aasm_state: "claimed"}), do: "Claimed" + def pretty_state(%{aasm_state: "listed"}), do: "Listed" + def pretty_state(%{aasm_state: "closed"}), do: "Closed" + def pretty_state(%{aasm_state: "acknowledged"}), do: "Claimed (Rescinded)" + def pretty_state(_dnp_entry), do: "Requested" + + def show_steps?(changeset) do + not is_nil(changeset.action) and not changeset.data.state == :loaded + end end