tag: Introduce tag system

Create a new table representing tags, composed of a name and color.
They can be used to tag truths and filter them later.
Tags display under the truths they correspond to and can be clicked
to access all truths matching this tag.

Introduce a new element in the top bar to allow navigating to the
tag list, which can be used to create and edit tags for the admin
and used to select a list of tags to filter against for everyone.

Update the database records of the truths to include the tag vector.
As the database query result is a multi-row result, it cannot be
parsed automatically so it needs to be skipped and retrieved
manually.
This commit is contained in:
trotFunky 2024-08-01 21:18:30 +01:00
parent d79375365d
commit 19898e1b09
13 changed files with 551 additions and 25 deletions

View file

@ -10,7 +10,8 @@ use sqlx::{Acquire, Executor};
use crate::{auth, vote};
use crate::auth::User;
use crate::database::Db;
use crate::database_records::{DisplayTruth, Player, Truth, Week};
use crate::database_records::{DisplayTruth, Player, Tag, Truth, Week};
use crate::tag;
use crate::vote::WeeklyUserVotes;
pub async fn get_last_week(db: &mut Connection<Db>) -> u8 {
@ -57,7 +58,7 @@ pub async fn week(week_number: u8, mut db: Connection<Db>, cookies: &CookieJar<'
// FIXME : This is fucking *trash* but fucking hell mate
if user.is_admin {
let truths: Vec<Truth> = match sqlx::query_as("SELECT * FROM Truths WHERE week == $1 ORDER BY number")
let mut truths: Vec<Truth> = match sqlx::query_as("SELECT * FROM Truths WHERE week == $1 ORDER BY number")
.bind(week_number)
.fetch_all(&mut **db).await {
Ok(v) => v,
@ -67,15 +68,22 @@ pub async fn week(week_number: u8, mut db: Connection<Db>, cookies: &CookieJar<'
}
};
for truth in &mut truths {
truth.tags = tag::get_truth_tags(truth.id, &mut db).await;
}
let tags: Vec<Tag> = tag::get_all_tags(&mut db, cookies).await;
Template::render("weeks/index", context! {
week_data: week_data,
truths: truths,
user: user,
other_players: other_players,
vote_data: vote_data
vote_data: vote_data,
tags: tags
})
} else {
let truths: Vec<DisplayTruth> = match sqlx::query_as("SELECT id, week, number, author_id, rendered_text FROM Truths WHERE week == $1 ORDER BY number")
let mut truths: Vec<DisplayTruth> = match sqlx::query_as("SELECT id, week, number, author_id, rendered_text FROM Truths WHERE week == $1 ORDER BY number")
.bind(week_number)
.fetch_all(&mut **db).await {
Ok(v) => v,
@ -85,6 +93,10 @@ pub async fn week(week_number: u8, mut db: Connection<Db>, cookies: &CookieJar<'
}
};
for truth in &mut truths {
truth.tags = tag::get_truth_tags(truth.id, &mut db).await;
}
Template::render("weeks/index", context! {
week_data: week_data,
truths: truths,