89 lines
2.4 KiB
Rust
89 lines
2.4 KiB
Rust
use anyhow::Result;
|
|
use askama::Template;
|
|
use derive_builder::Builder;
|
|
use phono_backends::client::WorkspaceClient;
|
|
use phono_models::{client::AppDbClient, workspace::Workspace};
|
|
use sqlx::postgres::types::Oid;
|
|
use uuid::Uuid;
|
|
|
|
use crate::{
|
|
navigator::Navigator,
|
|
workspaces::{RelationPortalSet, fetch_all_accessible_portals},
|
|
};
|
|
|
|
#[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,
|
|
}
|
|
|
|
impl WorkspaceNav {
|
|
pub fn builder() -> WorkspaceNavBuilder {
|
|
WorkspaceNavBuilder::default()
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub struct RelationItem {
|
|
pub name: String,
|
|
pub oid: Oid,
|
|
pub portals: Vec<PortalItem>,
|
|
}
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub struct PortalItem {
|
|
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,
|
|
}
|
|
|
|
impl WorkspaceNavBuilder {
|
|
/// Helper function to populate relations and lenses automatically.
|
|
/// [`WorkspaceNavBuilder::workspace()`] must be called first, or else this
|
|
/// method will return an error.
|
|
///
|
|
/// WARNING: This assumes that `workspace_client` is authenticated with
|
|
/// [`RoleAssignment::User`] for the current user.
|
|
pub async fn populate_rels(
|
|
&mut self,
|
|
app_db: &mut AppDbClient,
|
|
workspace_client: &mut WorkspaceClient,
|
|
) -> Result<&mut Self> {
|
|
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 {
|
|
name: rel.relname,
|
|
oid: rel.oid,
|
|
portals: portals
|
|
.into_iter()
|
|
.map(|portal| PortalItem {
|
|
id: portal.id,
|
|
name: portal.name,
|
|
})
|
|
.collect(),
|
|
})
|
|
.collect(),
|
|
))
|
|
}
|
|
}
|