Skip to content

Commit

Permalink
Add site alerts.
Browse files Browse the repository at this point in the history
  • Loading branch information
Syfaro committed Sep 5, 2024
1 parent 5e935e2 commit 45b9136
Show file tree
Hide file tree
Showing 16 changed files with 423 additions and 4 deletions.
26 changes: 26 additions & 0 deletions frontend/src/ts/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,3 +232,29 @@ document.querySelectorAll(".human-number").forEach((elem) => {
const value = parseInt(elem.textContent?.trim() || "0", 10);
elem.textContent = numberFormatter.format(value);
});

document.querySelectorAll(".site-alert-delete").forEach((elem) => {
const alertId = (elem as HTMLElement).dataset.alertId;
if (!alertId) return;

elem.addEventListener("click", async () => {
const formData = new URLSearchParams();
formData.set("alert_id", alertId);

const resp = await fetch("/api/alert/dismiss", {
method: "POST",
body: formData,
credentials: "same-origin",
});

if (resp.status !== 204) {
alert("Error dismissing alert, try again later.");
return;
}

const notification = elem.closest(".notification");
if (notification) {
notification.parentNode?.removeChild(notification);
}
});
});
1 change: 1 addition & 0 deletions migrations/20240905145854_site_alerts.down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DROP TABLE site_alert_dismiss, site_alert;
15 changes: 15 additions & 0 deletions migrations/20240905145854_site_alerts.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
CREATE TABLE site_alert (
id uuid PRIMARY KEY NOT NULL DEFAULT gen_random_uuid(),
created_at timestamp with time zone NOT NULL DEFAULT current_timestamp,
active boolean NOT NULL DEFAULT true,
content text NOT NULL
);

CREATE INDEX site_alert_lookup_idx ON site_alert (created_at DESC);

CREATE TABLE site_alert_dismiss (
site_alert_id uuid NOT NULL REFERENCES site_alert (id) ON DELETE CASCADE,
user_account_id uuid NOT NULL REFERENCES user_account (id) ON DELETE CASCADE,
dismissed_at timestamp with time zone NOT NULL DEFAULT current_timestamp,
PRIMARY KEY (site_alert_id, user_account_id)
);
13 changes: 13 additions & 0 deletions queries/site_alerts/active_for_user.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
SELECT
id,
created_at,
active,
content
FROM
site_alert
LEFT JOIN site_alert_dismiss ON site_alert_dismiss.site_alert_id = site_alert.id AND site_alert_dismiss.user_account_id = $1
WHERE
site_alert_dismiss.site_alert_id IS NULL
AND active = true
ORDER BY
created_at DESC;
4 changes: 4 additions & 0 deletions queries/site_alerts/create.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
INSERT INTO
site_alert (content)
VALUES
($1) RETURNING id;
6 changes: 6 additions & 0 deletions queries/site_alerts/deactivate.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
UPDATE
site_alert
SET
active = false
WHERE
id = $1;
4 changes: 4 additions & 0 deletions queries/site_alerts/dismiss.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
INSERT INTO
site_alert_dismiss (site_alert_id, user_account_id)
VALUES
($1, $2) ON CONFLICT DO NOTHING;
11 changes: 11 additions & 0 deletions queries/site_alerts/list.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
SELECT
id,
created_at,
active,
content
FROM
site_alert
ORDER BY
created_at DESC
LIMIT
50;
119 changes: 119 additions & 0 deletions sqlx-data.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

77 changes: 76 additions & 1 deletion src/admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use futures::TryFutureExt;
use rand::Rng;
use serde::Deserialize;
use sha2::{Digest, Sha256};
use uuid::Uuid;

use crate::{
jobs::{JobInitiator, JobInitiatorExt, NewSubmissionJob},
Expand All @@ -21,11 +22,13 @@ pub fn service() -> Scope {
admin_imports,
admin_sites_reddit,
admin_sites_flist,
admin_alerts,
inject_post,
job_manual,
subreddit_add,
subreddit_state,
flist_abort
flist_abort,
services![alert_create, alert_deactivate]
])
}

Expand Down Expand Up @@ -460,3 +463,75 @@ async fn job_manual(
.insert_header(("Location", request.url_for_static("admin_inject")?.as_str()))
.finish())
}

#[derive(Template)]
#[template(path = "admin/alerts.html")]
struct AdminAlerts {
alerts: Vec<models::SiteAlert>,
}

#[get("/alerts", name = "admin_alerts")]
async fn admin_alerts(
conn: web::Data<sqlx::PgPool>,
request: actix_web::HttpRequest,
user: models::User,
) -> Result<HttpResponse, Error> {
if !user.is_admin {
return Err(actix_web::error::ErrorUnauthorized("Unauthorized").into());
}

let alerts = models::SiteAlert::list(&conn).await?;

let body = AdminAlerts { alerts }
.wrap_admin(&request, &user)
.await
.render()?;

Ok(HttpResponse::Ok().content_type("text/html").body(body))
}

#[derive(Deserialize)]
struct AlertCreateForm {
content: String,
}

#[post("/alerts/create")]
async fn alert_create(
conn: web::Data<sqlx::PgPool>,
request: actix_web::HttpRequest,
user: models::User,
web::Form(form): web::Form<AlertCreateForm>,
) -> Result<HttpResponse, Error> {
if !user.is_admin {
return Err(actix_web::error::ErrorUnauthorized("Unauthorized").into());
}

models::SiteAlert::create(&conn, form.content).await?;

Ok(HttpResponse::Found()
.insert_header(("Location", request.url_for_static("admin_alerts")?.as_str()))
.finish())
}

#[derive(Deserialize)]
struct AlertActionForm {
alert_id: Uuid,
}

#[post("/alerts/deactivate")]
async fn alert_deactivate(
conn: web::Data<sqlx::PgPool>,
request: actix_web::HttpRequest,
user: models::User,
web::Form(form): web::Form<AlertActionForm>,
) -> Result<HttpResponse, Error> {
if !user.is_admin {
return Err(actix_web::error::ErrorUnauthorized("Unauthorized").into());
}

models::SiteAlert::deactivate(&conn, form.alert_id).await?;

Ok(HttpResponse::Found()
.insert_header(("Location", request.url_for_static("admin_alerts")?.as_str()))
.finish())
}
18 changes: 17 additions & 1 deletion src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,22 @@ async fn events(
}
}

#[derive(Deserialize)]
struct AlertDismissForm {
alert_id: Uuid,
}

#[post("/alert/dismiss")]
async fn alert_dismiss(
user: models::User,
conn: web::Data<sqlx::PgPool>,
web::Form(form): web::Form<AlertDismissForm>,
) -> Result<HttpResponse, Error> {
models::SiteAlert::dismiss(&conn, form.alert_id, user.id).await?;

Ok(HttpResponse::new(actix_http::StatusCode::NO_CONTENT))
}

#[get("/ingest/stats")]
async fn ingest_stats(
user: models::User,
Expand Down Expand Up @@ -483,7 +499,7 @@ async fn flist_lookup(

pub fn service() -> Scope {
web::scope("/api")
.service(services![events, ingest_stats, upload, flist_lookup])
.service(services![events, alert_dismiss, ingest_stats, upload, flist_lookup])
.service(web::scope("/service").service(services![fuzzysearch]))
.service(web::scope("/chunk").service(services![chunk_add]))
}
Loading

0 comments on commit 45b9136

Please sign in to comment.