phonograph/phono-server/src/workspace_nav.rs

90 lines
2.4 KiB
Rust
Raw Normal View History

2025-08-04 13:59:42 -07:00
use anyhow::Result;
use askama::Template;
use derive_builder::Builder;
use phono_backends::client::WorkspaceClient;
use phono_models::{client::AppDbClient, workspace::Workspace};
2025-08-04 13:59:42 -07:00
use sqlx::postgres::types::Oid;
use uuid::Uuid;
2025-10-01 22:36:19 -07:00
use crate::{
navigator::Navigator,
2025-12-16 09:59:30 -08:00
workspaces::{RelationPortalSet, fetch_all_accessible_portals},
2025-10-01 22:36:19 -07:00
};
2025-08-04 13:59:42 -07:00
#[derive(Builder, Clone, Debug, Template)]
#[template(path = "workspace_nav.html")]
pub(crate) struct WorkspaceNav {
workspace: Workspace,
relations: Vec<RelationItem>,
#[builder(default, setter(strip_option))]
current: Option<NavLocation>,
navigator: Navigator,
2025-08-04 13:59:42 -07:00
}
impl WorkspaceNav {
pub fn builder() -> WorkspaceNavBuilder {
WorkspaceNavBuilder::default()
}
2025-08-04 13:59:42 -07:00
}
#[derive(Clone, Debug)]
pub struct RelationItem {
2025-08-04 13:59:42 -07:00
pub name: String,
pub oid: Oid,
pub portals: Vec<PortalItem>,
2025-08-04 13:59:42 -07:00
}
#[derive(Clone, Debug)]
pub struct PortalItem {
2025-08-04 13:59:42 -07:00
pub name: String,
pub id: Uuid,
}
#[derive(Clone, Debug, PartialEq)]
pub enum NavLocation {
Rel(Oid, Option<RelLocation>),
}
#[derive(Clone, Debug, PartialEq)]
pub enum RelLocation {
Portal(Uuid),
Sharing,
2025-08-04 13:59:42 -07:00
}
impl WorkspaceNavBuilder {
2025-08-04 13:59:42 -07:00
/// Helper function to populate relations and lenses automatically.
/// [`WorkspaceNavBuilder::workspace()`] must be called first, or else this
/// method will return an error.
2025-10-01 22:36:19 -07:00
///
/// WARNING: This assumes that `workspace_client` is authenticated with
/// [`RoleAssignment::User`] for the current user.
2025-08-04 13:59:42 -07:00
pub async fn populate_rels(
&mut self,
app_db: &mut AppDbClient,
workspace_client: &mut WorkspaceClient,
2025-08-04 13:59:42 -07:00
) -> Result<&mut Self> {
2025-10-01 22:36:19 -07:00
let workspace_id = self
.workspace
.clone()
.ok_or(WorkspaceNavBuilderError::UninitializedField("workspace"))?
.id;
Ok(self.relations(
fetch_all_accessible_portals(workspace_id, app_db, workspace_client)
.await?
.into_iter()
.map(|RelationPortalSet { rel, portals }| RelationItem {
2025-08-04 13:59:42 -07:00
name: rel.relname,
oid: rel.oid,
portals: portals
2025-08-04 13:59:42 -07:00
.into_iter()
.map(|portal| PortalItem {
id: portal.id,
2025-10-01 22:36:19 -07:00
name: portal.name,
2025-08-04 13:59:42 -07:00
})
.collect(),
2025-10-01 22:36:19 -07:00
})
.collect(),
))
2025-08-04 13:59:42 -07:00
}
}