site notices

This commit is contained in:
byte[] 2019-12-14 13:28:04 -05:00
parent 5871920c14
commit 56ce4c74bc
10 changed files with 215 additions and 10 deletions

View file

@ -54,9 +54,9 @@ defmodule Philomena.SiteNotices do
{:error, %Ecto.Changeset{}} {:error, %Ecto.Changeset{}}
""" """
def create_site_notice(attrs \\ %{}) do def create_site_notice(creator, attrs \\ %{}) do
%SiteNotice{} %SiteNotice{user_id: creator.id}
|> SiteNotice.changeset(attrs) |> SiteNotice.save_changeset(attrs)
|> Repo.insert() |> Repo.insert()
end end
@ -74,7 +74,7 @@ defmodule Philomena.SiteNotices do
""" """
def update_site_notice(%SiteNotice{} = site_notice, attrs) do def update_site_notice(%SiteNotice{} = site_notice, attrs) do
site_notice site_notice
|> SiteNotice.changeset(attrs) |> SiteNotice.save_changeset(attrs)
|> Repo.update() |> Repo.update()
end end

View file

@ -3,17 +3,21 @@ defmodule Philomena.SiteNotices.SiteNotice do
import Ecto.Changeset import Ecto.Changeset
alias Philomena.Users.User alias Philomena.Users.User
import Philomena.Schema.Time
schema "site_notices" do schema "site_notices" do
belongs_to :user, User belongs_to :user, User
field :title, :string field :title, :string
field :text, :string field :text, :string, default: ""
field :link, :string field :link, :string, default: ""
field :link_text, :string field :link_text, :string, default: ""
field :live, :boolean, default: false field :live, :boolean, default: true
field :start_date, :naive_datetime field :start_date, :utc_datetime
field :finish_date, :naive_datetime field :finish_date, :utc_datetime
field :start_time, :string, virtual: true
field :finish_time, :string, virtual: true
timestamps(inserted_at: :created_at) timestamps(inserted_at: :created_at)
end end
@ -22,6 +26,15 @@ defmodule Philomena.SiteNotices.SiteNotice do
def changeset(site_notice, attrs) do def changeset(site_notice, attrs) do
site_notice site_notice
|> cast(attrs, []) |> cast(attrs, [])
|> propagate_time(:start_date, :start_time)
|> propagate_time(:finish_date, :finish_time)
|> validate_required([]) |> validate_required([])
end end
def save_changeset(site_notice, attrs) do
site_notice
|> cast(attrs, [:title, :text, :link, :link_text, :live, :start_time, :finish_time])
|> assign_time(:start_time, :start_date)
|> assign_time(:finish_time, :finish_date)
end
end end

View file

@ -0,0 +1,69 @@
defmodule PhilomenaWeb.Admin.SiteNoticeController do
use PhilomenaWeb, :controller
alias Philomena.SiteNotices.SiteNotice
alias Philomena.SiteNotices
alias Philomena.Repo
import Ecto.Query
plug :verify_authorized
plug :load_and_authorize_resource, model: SiteNotice, except: [:index]
def index(conn, _params) do
site_notices =
SiteNotice
|> order_by(desc: :start_date)
|> Repo.paginate(conn.assigns.scrivener)
render(conn, "index.html", site_notices: site_notices)
end
def new(conn, _params) do
changeset = SiteNotices.change_site_notice(%SiteNotice{})
render(conn, "new.html", changeset: changeset)
end
def create(conn, %{"site_notice" => site_notice_params}) do
case SiteNotices.create_site_notice(conn.assigns.current_user, site_notice_params) do
{:ok, _site_notice} ->
conn
|> put_flash(:info, "Successfully created site notice.")
|> redirect(to: Routes.admin_site_notice_path(conn, :index))
{:error, changeset} ->
render(conn, "new.html", changeset: changeset)
end
end
def edit(conn, _params) do
changeset = SiteNotices.change_site_notice(conn.assigns.site_notice)
render(conn, "edit.html", changeset: changeset)
end
def update(conn, %{"site_notice" => site_notice_params}) do
case SiteNotices.update_site_notice(conn.assigns.site_notice, site_notice_params) do
{:ok, _site_notice} ->
conn
|> put_flash(:info, "Succesfully updated site notice.")
|> redirect(to: Routes.admin_site_notice_path(conn, :index))
{:error, changeset} ->
render(conn, "edit.html", changeset: changeset)
end
end
def delete(conn, _params) do
{:ok, _site_notice} = SiteNotices.delete_site_notice(conn.assigns.site_notice)
conn
|> put_flash(:info, "Sucessfully deleted site notice.")
|> redirect(to: Routes.admin_site_notice_path(conn, :index))
end
defp verify_authorized(conn, _opts) do
case Canada.Can.can?(conn.assigns.current_user, :index, SiteNotice) do
true -> conn
false -> PhilomenaWeb.NotAuthorizedPlug.call(conn)
end
end
end

View file

@ -194,6 +194,8 @@ defmodule PhilomenaWeb.Router do
resources "/user_bans", UserBanController, only: [:index, :new, :create, :edit, :update, :delete] resources "/user_bans", UserBanController, only: [:index, :new, :create, :edit, :update, :delete]
resources "/subnet_bans", SubnetBanController, only: [:index, :new, :create, :edit, :update, :delete] resources "/subnet_bans", SubnetBanController, only: [:index, :new, :create, :edit, :update, :delete]
resources "/fingerprint_bans", FingerprintBanController, only: [:index, :new, :create, :edit, :update, :delete] resources "/fingerprint_bans", FingerprintBanController, only: [:index, :new, :create, :edit, :update, :delete]
resources "/site_notices", SiteNoticeController, except: [:show]
end end
resources "/duplicate_reports", DuplicateReportController, only: [] do resources "/duplicate_reports", DuplicateReportController, only: [] do

View file

@ -0,0 +1,47 @@
= 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, :title, "Title (the bold bit) for the site notice; keep this short:"
= text_input f, :title, class: "input input--wide", placeholder: "Title", required: true
= error_tag f, :title
.field
=> label f, :text, "Main body of the site notice:"
= text_input f, :text, class: "input input--wide", placeholder: "Text", required: true
= error_tag f, :text
h3
' Link
small
' (optional; leave these two fields blank for no link)
.field
=> label f, :link_text, "Text which will contain the link:"
= text_input f, :link_text, class: "input input--wide", placeholder: "Link text"
= error_tag f, :link_text
.field
=> label f, :link, "Link which the site notice should take users to:"
= text_input f, :link, class: "input input--wide", placeholder: "Link"
= error_tag f, :link
h3 Run Time
.field
=> label f, :start_time, "Start time for the site notice (usually \"now\"):"
= text_input f, :start_time, class: "input input--wide", required: true
= error_tag f, :start_time
.field
=> label f, :finish_time, "Finish time for the site notice (e.g. \"2 weeks from now\"):"
= text_input f, :finish_time, class: "input input--wide", required: true
= error_tag f, :finish_time
h3 Enable
.field
=> checkbox f, :live, class: "checkbox"
= label f, :live, "Live"
= submit "Save Site Notice", class: "button"

View file

@ -0,0 +1,2 @@
h1 Editing site notice
= render PhilomenaWeb.Admin.SiteNoticeView, "_form.html", changeset: @changeset, action: Routes.admin_site_notice_path(@conn, :update, @site_notice), conn: @conn

View file

@ -0,0 +1,44 @@
h1 Site Notices
- route = fn p -> Routes.admin_site_notice_path(@conn, :index, p) end
- pagination = render PhilomenaWeb.PaginationView, "_pagination.html", page: @site_notices, route: route, conn: @conn
.block
.block__header
a href=Routes.admin_site_notice_path(@conn, :new)
i.fa.fa-plus>
' New site notice
= pagination
.block__content
table.table
thead
tr
th Title
th Start
th Finish
th Live?
th Options
tbody
= for site_notice <- @site_notices do
tr
td
em = site_notice.title
td class=time_column_class(site_notice.start_date)
= pretty_time site_notice.start_date
td class=time_column_class(site_notice.finish_date)
= pretty_time site_notice.finish_date
td
= live_text site_notice
td
=> link "Edit", to: Routes.admin_site_notice_path(@conn, :edit, site_notice)
' &bull;
=> link "Destroy", to: Routes.admin_site_notice_path(@conn, :delete, site_notice), data: [confirm: "Are you really, really sure?", method: "delete"]
.block__header.block__header--light
= pagination

View file

@ -0,0 +1,2 @@
h1 New site notice
= render PhilomenaWeb.Admin.SiteNoticeView, "_form.html", changeset: @changeset, action: Routes.admin_site_notice_path(@conn, :create), conn: @conn

View file

@ -0,0 +1,15 @@
defmodule PhilomenaWeb.Admin.SiteNoticeView do
use PhilomenaWeb, :view
def time_column_class(time) do
now = DateTime.utc_now()
case DateTime.diff(time, now) > 0 do
true -> "success"
false -> "danger"
end
end
def live_text(%{live: true}), do: "Yes"
def live_text(_site_notice), do: "No"
end

View file

@ -28,6 +28,13 @@ defmodule RelativeDate.Parser do
|> eos() |> eos()
|> unwrap_and_tag(:moon) |> unwrap_and_tag(:moon)
now =
space
|> string("now")
|> concat(space)
|> eos()
|> unwrap_and_tag(:now)
date = date =
space space
|> integer(min: 1) |> integer(min: 1)
@ -42,6 +49,7 @@ defmodule RelativeDate.Parser do
relative_date = relative_date =
choice([ choice([
moon, moon,
now,
date date
]) ])
@ -77,6 +85,9 @@ defmodule RelativeDate.Parser do
{:ok, [moon: _moon], _1, _2, _3, _4} -> {:ok, [moon: _moon], _1, _2, _3, _4} ->
{:ok, DateTime.utc_now() |> DateTime.add(31_536_000_000, :second) |> DateTime.truncate(:second)} {:ok, DateTime.utc_now() |> DateTime.add(31_536_000_000, :second) |> DateTime.truncate(:second)}
{:ok, [now: _now], _1, _2, _3, _4} ->
{:ok, DateTime.utc_now() |> DateTime.truncate(:second)}
{:ok, [relative_date: [amount, scale, direction]], _1, _2, _3, _4} -> {:ok, [relative_date: [amount, scale, direction]], _1, _2, _3, _4} ->
{:ok, DateTime.utc_now() |> DateTime.add(amount * scale * direction, :second) |> DateTime.truncate(:second)} {:ok, DateTime.utc_now() |> DateTime.add(amount * scale * direction, :second) |> DateTime.truncate(:second)}