use askama::Template; use axum::{ debug_handler, extract::{Path, State}, response::{Html, IntoResponse}, }; use phono_models::{ accessors::{Accessor, Actor, portal::PortalAccessor}, portal::Portal, workspace::Workspace, }; use serde::Deserialize; use sqlx::postgres::types::Oid; use uuid::Uuid; use crate::{ app::{App, AppDbConn}, errors::AppError, navigator::{Navigator, NavigatorPage as _}, settings::Settings, user::CurrentUser, workspace_nav::{NavLocation, RelLocation, WorkspaceNav}, workspace_pooler::{RoleAssignment, WorkspacePooler}, }; #[derive(Debug, Deserialize)] pub(super) struct PathParams { portal_id: Uuid, rel_oid: u32, workspace_id: Uuid, } /// HTTP GET handler for portal settings, including renaming and deletion. #[debug_handler(state = App)] pub(super) async fn get( State(settings): State, CurrentUser(user): CurrentUser, AppDbConn(mut app_db): AppDbConn, Path(PathParams { portal_id, rel_oid, workspace_id, }): Path, navigator: Navigator, State(mut pooler): State, ) -> Result { let mut workspace_client = pooler .acquire_for(workspace_id, RoleAssignment::User(user.id)) .await?; let portal = PortalAccessor::new() .id(portal_id) .as_actor(Actor::User(user.id)) .verify_workspace_id(workspace_id) .verify_rel_oid(Oid(rel_oid)) .verify_rel_ownership() .using_app_db(&mut app_db) .using_workspace_client(&mut workspace_client) .fetch_one() .await?; let workspace = Workspace::with_id(workspace_id) .fetch_one(&mut app_db) .await?; #[derive(Debug, Template)] #[template(path = "relations_single/portal_settings.html")] struct ResponseTemplate { navigator: Navigator, portal: Portal, settings: Settings, workspace_nav: WorkspaceNav, } Ok(Html( ResponseTemplate { workspace_nav: WorkspaceNav::builder() .navigator(navigator.clone()) .workspace(workspace) .populate_rels(&mut app_db, &mut workspace_client) .await? .current(NavLocation::Rel(Oid(rel_oid), Some(RelLocation::Sharing))) .build()?, navigator, portal, settings, } .render()?, )) }