119 lines
3.4 KiB
Rust
119 lines
3.4 KiB
Rust
mod document;
|
|
mod hierarchy_builder;
|
|
|
|
use crate::hierarchy_builder::{FlattedViews, WorkspaceViewBuilder};
|
|
pub use anyhow::Result;
|
|
use async_trait::async_trait;
|
|
use collab::core::collab::MutexCollab;
|
|
use collab::core::collab_plugin::EncodedCollab;
|
|
use collab::core::origin::CollabOrigin;
|
|
use collab_entity::CollabType;
|
|
use collab_folder::{
|
|
timestamp, Folder, FolderData, RepeatedViewIdentifier, ViewIdentifier, ViewLayout, Workspace,
|
|
};
|
|
use std::collections::HashMap;
|
|
use std::sync::Arc;
|
|
use tokio::sync::RwLock;
|
|
|
|
#[async_trait]
|
|
pub trait WorkspaceTemplate {
|
|
async fn create_workspace_view(
|
|
&self,
|
|
uid: i64,
|
|
workspace_view_builder: Arc<RwLock<WorkspaceViewBuilder>>,
|
|
) -> Result<TemplateData>;
|
|
}
|
|
|
|
pub struct TemplateData {
|
|
pub object_id: String,
|
|
pub object_type: CollabType,
|
|
pub object_data: EncodedCollab,
|
|
}
|
|
|
|
pub type WorkspaceTemplateHandlers = HashMap<ViewLayout, Arc<dyn WorkspaceTemplate + Send + Sync>>;
|
|
|
|
pub struct WorkspaceTemplateBuilder {
|
|
pub uid: i64,
|
|
pub workspace_id: String,
|
|
pub handlers: WorkspaceTemplateHandlers,
|
|
}
|
|
|
|
impl WorkspaceTemplateBuilder {
|
|
pub fn new(uid: i64, workspace_id: &str) -> Self {
|
|
let mut handlers = WorkspaceTemplateHandlers::default();
|
|
// register the document template handler
|
|
handlers.insert(ViewLayout::Document, Arc::new(document::DocumentTemplate));
|
|
Self {
|
|
uid,
|
|
workspace_id: workspace_id.to_string(),
|
|
handlers,
|
|
}
|
|
}
|
|
|
|
pub async fn default_workspace(&self) -> Result<Vec<TemplateData>> {
|
|
let workspace_view_builder = Arc::new(RwLock::new(WorkspaceViewBuilder::new(
|
|
self.workspace_id.clone(),
|
|
self.uid,
|
|
)));
|
|
let mut templates = vec![];
|
|
for handler in self.handlers.values() {
|
|
if let Ok(template) = handler
|
|
.create_workspace_view(self.uid, workspace_view_builder.clone())
|
|
.await
|
|
{
|
|
templates.push(template);
|
|
}
|
|
}
|
|
|
|
let views = workspace_view_builder.write().await.build();
|
|
// Safe to unwrap because we have at least one view.
|
|
let first_view = views.first().unwrap().parent_view.clone();
|
|
let first_level_views = views
|
|
.iter()
|
|
.map(|value| ViewIdentifier {
|
|
id: value.parent_view.id.clone(),
|
|
})
|
|
.collect::<Vec<_>>();
|
|
|
|
let workspace = Workspace {
|
|
id: self.workspace_id.clone(),
|
|
name: "Workspace".to_string(),
|
|
child_views: RepeatedViewIdentifier::new(first_level_views),
|
|
created_at: timestamp(),
|
|
created_by: Some(self.uid),
|
|
last_edited_time: timestamp(),
|
|
last_edited_by: Some(self.uid),
|
|
};
|
|
|
|
let uid = self.uid;
|
|
let workspace_id = self.workspace_id.clone();
|
|
let folder_template = tokio::task::spawn_blocking(move || {
|
|
let folder_data = FolderData {
|
|
workspace,
|
|
current_view: first_view.id,
|
|
views: FlattedViews::flatten_views(views),
|
|
favorites: Default::default(),
|
|
recent: Default::default(),
|
|
trash: Default::default(),
|
|
};
|
|
|
|
let collab = Arc::new(MutexCollab::new(CollabOrigin::Empty, &workspace_id, vec![]));
|
|
let folder = Folder::create(uid, collab, None, folder_data);
|
|
let data = folder.encode_collab_v1();
|
|
Ok::<_, anyhow::Error>(TemplateData {
|
|
object_id: workspace_id,
|
|
object_type: CollabType::Folder,
|
|
object_data: data,
|
|
})
|
|
})
|
|
.await??;
|
|
|
|
templates.push(folder_template);
|
|
Ok(templates)
|
|
}
|
|
}
|
|
|
|
pub fn gen_view_id() -> String {
|
|
uuid::Uuid::new_v4().to_string()
|
|
}
|