pique/src/handler/documents.rs

170 lines
4.8 KiB
Rust

use axum::{extract::Path, response::Redirect, Form};
use axum_login::AuthSession;
use crate::{handler::internal_server_error, models::{Document, ModelPermission, ModelType, Permission}, prelude::*};
pub async fn documents_page(
State(ctx): State<Context>,
auth_session: AuthSession<Context>,
) -> Response {
if let Some(user) = auth_session.user {
render_documents_page(ctx, user).await
} else {
Redirect::to("/login").into_response()
}
}
async fn render_documents_page(ctx: Context, user: crate::entity::user::Model) -> Response {
let documents = ModelPermission::user_documents(&ctx.kv_handles, user.id).unwrap_or_default();
let values = context! {
user => user,
documents => documents,
};
ctx.render_resp("documents/list_documents.html", values)
}
pub async fn create_document_page(
State(ctx): State<Context>,
auth_session: AuthSession<Context>,
) -> Response {
let user = match auth_session.user {
Some(user) => user,
None => return Redirect::to("/login").into_response(),
};
let projects = ModelPermission::user_projects(&ctx.kv_handles, user.id).unwrap_or_default();
let values = context! {
user => user,
projects => projects,
};
ctx.render_resp("documents/create_document.html", values)
}
#[derive(Debug, Deserialize)]
pub struct CreateDocumentSubmission {
pub project_id: Uuid,
pub title: String,
}
pub async fn create_document_submit(
State(ctx): State<Context>,
auth_session: AuthSession<Context>,
form: Form<CreateDocumentSubmission>,
) -> Response {
let user = match auth_session.user {
Some(user) => user,
None => return Redirect::to("/login").into_response(),
};
let project = match ModelPermission::user_project(&ctx.kv_handles, user.id, form.project_id) {
Ok(Some(project)) => project,
Ok(None) => return Redirect::to("/documents/create").into_response(),
Err(err) => {
error!(?err, "failed to access kv store");
return Redirect::to("/documents/create").into_response();
}
};
let document = Document {
id: Uuid::now_v7(),
project_id: project.id,
title: form.title.to_owned(),
content: "".to_owned(),
};
if let Err(err) = document.save(&ctx.kv_handles) {
error!(?err, "failed to save document");
return internal_server_error();
}
info!(?document, "document created");
let permission = ModelPermission {
user_id: user.id,
model_type: ModelType::Document,
role: Permission::Admin,
model_id: document.id,
};
if let Err(err) = permission.add(&ctx.kv_handles) {
error!(?err, "failed to save new project permission");
return internal_server_error();
}
Redirect::to("/documents").into_response()
}
pub async fn edit_document_page(
State(ctx): State<Context>,
auth_session: AuthSession<Context>,
Path((id,)): Path<(Uuid,)>,
) -> Response {
let user = match auth_session.user {
Some(user) => user,
None => return Redirect::to("/login").into_response(),
};
let document = match ModelPermission::user_document(&ctx.kv_handles, user.id, id) {
Ok(Some(document)) => document,
Ok(None) => return Redirect::to("/documents").into_response(),
Err(err) => {
error!(?err, "failed to load document");
return internal_server_error();
}
};
dbg!(&document);
let values = context! {
user => user,
document => document,
};
ctx.render_resp("documents/edit_document.html", values)
}
#[derive(Debug, Deserialize)]
pub struct EditDocumentSubmission {
pub title: String,
pub content: String,
}
pub async fn edit_document_submit(
State(ctx): State<Context>,
auth_session: AuthSession<Context>,
Path((document_id,)): Path<(Uuid,)>,
form: Form<EditDocumentSubmission>,
) -> Response {
let user = match auth_session.user {
Some(user) => user,
None => return Redirect::to("/login").into_response(),
};
let mut document = match ModelPermission::user_document(&ctx.kv_handles, user.id, document_id) {
Ok(Some(document)) => document,
Ok(None) => return Redirect::to("/documents").into_response(),
Err(err) => {
error!(?err, "failed to load document");
return internal_server_error();
}
};
let new_document = Document {
id: document.id,
project_id: document.id,
title: form.title.to_owned(),
content: form.content.to_owned(),
};
if let Err(err) = new_document.save(&ctx.kv_handles) {
error!(?err, "failed to save document");
return internal_server_error();
}
info!(?new_document, "document updated");
Redirect::to("/documents").into_response()
}