diff --git a/libs/workspace-template/src/document/get_started.rs b/libs/workspace-template/src/document/get_started.rs new file mode 100644 index 00000000..72bd9ad1 --- /dev/null +++ b/libs/workspace-template/src/document/get_started.rs @@ -0,0 +1,55 @@ +use crate::document::parser::JsonToDocumentParser; +use crate::hierarchy_builder::WorkspaceViewBuilder; +use crate::{TemplateData, WorkspaceTemplate}; +use async_trait::async_trait; +use collab::core::collab::MutexCollab; +use collab::core::origin::CollabOrigin; +use collab_document::document::Document; +use collab_entity::CollabType; +use collab_folder::ViewLayout; +use std::sync::Arc; +use tokio::sync::RwLock; + +/// This template generates a document containing a 'read me' guide. +/// It ensures that at least one view is created for the document. +pub struct GetStartedDocumentTemplate; + +#[async_trait] +impl WorkspaceTemplate for GetStartedDocumentTemplate { + fn layout(&self) -> ViewLayout { + ViewLayout::Document + } + + async fn create_workspace_view( + &self, + _uid: i64, + workspace_view_builder: Arc>, + ) -> anyhow::Result { + let view_id = workspace_view_builder + .write() + .await + .with_view_builder(|view_builder| async { + view_builder + .with_name("Getting started") + .with_icon("⭐️") + .build() + }) + .await; + + // create a empty document + let data = tokio::task::spawn_blocking(|| { + let json_str = include_str!("../../assets/read_me.json"); + let document_data = JsonToDocumentParser::json_str_to_document(json_str).unwrap(); + let collab = Arc::new(MutexCollab::new(CollabOrigin::Empty, &view_id, vec![])); + let document = Document::create_with_data(collab, document_data)?; + let data = document.get_collab().encode_collab_v1(); + Ok::<_, anyhow::Error>(TemplateData { + object_id: view_id, + object_type: CollabType::Document, + object_data: data, + }) + }) + .await??; + Ok(data) + } +} diff --git a/libs/workspace-template/src/document/mod.rs b/libs/workspace-template/src/document/mod.rs index d04f2203..effd01a9 100644 --- a/libs/workspace-template/src/document/mod.rs +++ b/libs/workspace-template/src/document/mod.rs @@ -1,54 +1,2 @@ +pub mod get_started; mod parser; - -use crate::document::parser::JsonToDocumentParser; -use crate::hierarchy_builder::WorkspaceViewBuilder; -use crate::{TemplateData, WorkspaceTemplate}; -use async_trait::async_trait; -use collab::core::collab::MutexCollab; -use collab::core::origin::CollabOrigin; -use collab_document::document::Document; -use collab_entity::CollabType; -use std::sync::Arc; -use tokio::sync::RwLock; - -/// A default template for creating documents. -/// -/// This template generates a document containing a 'read me' guide. -/// It ensures that at least one view is created for the document. -pub struct DocumentTemplate; - -#[async_trait] -impl WorkspaceTemplate for DocumentTemplate { - async fn create_workspace_view( - &self, - _uid: i64, - workspace_view_builder: Arc>, - ) -> anyhow::Result { - let view_id = workspace_view_builder - .write() - .await - .with_view_builder(|view_builder| async { - view_builder - .with_name("Getting started") - .with_icon("⭐️") - .build() - }) - .await; - - // create a empty document - let data = tokio::task::spawn_blocking(|| { - let json_str = include_str!("../../assets/read_me.json"); - let document_data = JsonToDocumentParser::json_str_to_document(json_str).unwrap(); - let collab = Arc::new(MutexCollab::new(CollabOrigin::Empty, &view_id, vec![])); - let document = Document::create_with_data(collab, document_data)?; - let data = document.get_collab().encode_collab_v1(); - Ok::<_, anyhow::Error>(TemplateData { - object_id: view_id, - object_type: CollabType::Document, - object_data: data, - }) - }) - .await??; - Ok(data) - } -} diff --git a/libs/workspace-template/src/lib.rs b/libs/workspace-template/src/lib.rs index a8cedc78..616d68f8 100644 --- a/libs/workspace-template/src/lib.rs +++ b/libs/workspace-template/src/lib.rs @@ -1,4 +1,4 @@ -mod document; +pub mod document; mod hierarchy_builder; use crate::hierarchy_builder::{FlattedViews, WorkspaceViewBuilder}; @@ -17,6 +17,8 @@ use tokio::sync::RwLock; #[async_trait] pub trait WorkspaceTemplate { + fn layout(&self) -> ViewLayout; + async fn create_workspace_view( &self, uid: i64, @@ -40,9 +42,7 @@ pub struct WorkspaceTemplateBuilder { 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)); + let handlers = WorkspaceTemplateHandlers::default(); Self { uid, workspace_id: workspace_id.to_string(), @@ -50,6 +50,11 @@ impl WorkspaceTemplateBuilder { } } + pub fn with_template(mut self, template: T) -> Self { + self.handlers.insert(template.layout(), Arc::new(template)); + self + } + pub async fn default_workspace(&self) -> Result> { let workspace_view_builder = Arc::new(RwLock::new(WorkspaceViewBuilder::new( self.workspace_id.clone(), diff --git a/src/biz/user.rs b/src/biz/user.rs index 1a4b0078..2e89a187 100644 --- a/src/biz/user.rs +++ b/src/biz/user.rs @@ -25,6 +25,7 @@ use snowflake::Snowflake; use sqlx::{types::uuid, PgPool}; use tokio::sync::RwLock; use tracing::{debug, event, instrument}; +use workspace_template::document::get_started::GetStartedDocumentTemplate; use workspace_template::WorkspaceTemplateBuilder; /// Verify the token from the gotrue server and create the user if it is a new user @@ -89,6 +90,7 @@ where // Create the default workspace for the user. A default workspace might contain multiple // templates, e.g. a document template, a database template, etc. let templates = WorkspaceTemplateBuilder::new(new_uid, &workspace_id) + .with_template(GetStartedDocumentTemplate) .default_workspace() .await?;