feat: cloud workspace api (#4469)

* feat: workspace api

* feat: added cloud apis for add and delete workspace

* feat: add and delete workspace event handlers

* chore: rust fmt

* chore: save user workspace

* test: add test

* test: add test

* chore: add to gitignore

* feat: update api add name to workspace

* chore: cargo clippy and rename to create

* chore: add envrc and direnv to gitignore

* chore: change name to create workspace instead of add workspace

* chore: update client api rev

* feat: add create workspace impl

* chore: restore gitignore to original

* test: fix create workspace event test

* fix: change delete workspace input

* fix: compile

* fix: create workspace test

* feat: add error code for request payload too large

* chore: remove cargo backup files

* feat: add is async option for upload file handler

* chore: update client api version

---------

Co-authored-by: nathan <nathan@appflowy.io>
This commit is contained in:
Zack
2024-02-04 05:49:45 +08:00
committed by GitHub
parent 250f29f325
commit 08938b8c70
46 changed files with 457 additions and 128 deletions

View File

@ -29,6 +29,7 @@ collab = { version = "0.1.0" }
collab-plugins = { version = "0.1.0"}
collab-document = { version = "0.1.0" }
collab-entity = { version = "0.1.0" }
collab-folder = { version = "0.1.0" }
hex = "0.4.3"
postgrest = "1.0"
lib-infra = { workspace = true }

View File

@ -18,7 +18,7 @@ impl<T> DatabaseCloudService for AFCloudDatabaseCloudServiceImpl<T>
where
T: AFServer,
{
fn get_collab_doc_state_db(
fn get_database_object_doc_state(
&self,
object_id: &str,
collab_type: CollabType,
@ -48,7 +48,7 @@ where
})
}
fn batch_get_collab_doc_state_db(
fn batch_get_database_object_doc_state(
&self,
object_ids: Vec<String>,
object_ty: CollabType,
@ -90,7 +90,7 @@ where
})
}
fn get_collab_snapshots(
fn get_database_collab_object_snapshots(
&self,
_object_id: &str,
_limit: usize,

View File

@ -1,8 +1,11 @@
use anyhow::{anyhow, Error};
use client_api::entity::{CollabParams, QueryCollab, QueryCollabParams};
use anyhow::Error;
use client_api::entity::{
workspace_dto::CreateWorkspaceParam, CollabParams, QueryCollab, QueryCollabParams,
};
use collab::core::collab::CollabDocState;
use collab::core::origin::CollabOrigin;
use collab_entity::CollabType;
use collab_folder::RepeatedViewIdentifier;
use flowy_error::FlowyError;
use flowy_folder_pub::cloud::{
@ -19,8 +22,27 @@ impl<T> FolderCloudService for AFCloudFolderCloudServiceImpl<T>
where
T: AFServer,
{
fn create_workspace(&self, _uid: i64, _name: &str) -> FutureResult<Workspace, Error> {
FutureResult::new(async move { Err(anyhow!("Not support yet")) })
fn create_workspace(&self, _uid: i64, name: &str) -> FutureResult<Workspace, Error> {
let try_get_client = self.0.try_get_client();
let cloned_name = name.to_string();
FutureResult::new(async move {
let client = try_get_client?;
let new_workspace = client
.create_workspace(CreateWorkspaceParam {
workspace_name: Some(cloned_name),
})
.await?;
Ok(Workspace {
id: new_workspace.workspace_id.to_string(),
name: new_workspace.workspace_name,
created_at: new_workspace.created_at.timestamp(),
child_views: RepeatedViewIdentifier::new(vec![]),
created_by: Some(new_workspace.owner_uid),
last_edited_time: new_workspace.created_at.timestamp(),
last_edited_by: Some(new_workspace.owner_uid),
})
})
}
fn open_workspace(&self, workspace_id: &str) -> FutureResult<(), Error> {
@ -88,7 +110,7 @@ where
FutureResult::new(async move { Ok(vec![]) })
}
fn get_collab_doc_state_f(
fn get_folder_doc_state(
&self,
workspace_id: &str,
_uid: i64,
@ -116,7 +138,7 @@ where
})
}
fn batch_create_collab_object_f(
fn batch_create_folder_collab_objects(
&self,
workspace_id: &str,
objects: Vec<FolderCollabParams>,

View File

@ -2,7 +2,9 @@ use std::collections::HashMap;
use std::sync::Arc;
use anyhow::{anyhow, Error};
use client_api::entity::workspace_dto::{CreateWorkspaceMember, WorkspaceMemberChangeset};
use client_api::entity::workspace_dto::{
CreateWorkspaceMember, CreateWorkspaceParam, WorkspaceMemberChangeset,
};
use client_api::entity::{AFRole, AFWorkspace, AuthProvider, CollabParams, CreateCollabParams};
use client_api::{Client, ClientConfiguration};
use collab::core::collab::CollabDocState;
@ -294,6 +296,30 @@ where
Ok(())
})
}
fn create_workspace(&self, workspace_name: &str) -> FutureResult<UserWorkspace, FlowyError> {
let try_get_client = self.server.try_get_client();
let workspace_name_owned = workspace_name.to_owned();
FutureResult::new(async move {
let client = try_get_client?;
let new_workspace = client
.create_workspace(CreateWorkspaceParam {
workspace_name: Some(workspace_name_owned),
})
.await?;
Ok(to_user_workspace(new_workspace))
})
}
fn delete_workspace(&self, workspace_id: &str) -> FutureResult<(), FlowyError> {
let try_get_client = self.server.try_get_client();
let workspace_id_owned = workspace_id.to_owned();
FutureResult::new(async move {
let client = try_get_client?;
client.delete_workspace(&workspace_id_owned).await?;
Ok(())
})
}
}
async fn get_admin_client(client: &Arc<AFCloudClient>) -> FlowyResult<Client> {

View File

@ -8,7 +8,7 @@ use lib_infra::future::FutureResult;
pub(crate) struct LocalServerDatabaseCloudServiceImpl();
impl DatabaseCloudService for LocalServerDatabaseCloudServiceImpl {
fn get_collab_doc_state_db(
fn get_database_object_doc_state(
&self,
_object_id: &str,
_collab_type: CollabType,
@ -17,7 +17,7 @@ impl DatabaseCloudService for LocalServerDatabaseCloudServiceImpl {
FutureResult::new(async move { Ok(vec![]) })
}
fn batch_get_collab_doc_state_db(
fn batch_get_database_object_doc_state(
&self,
_object_ids: Vec<String>,
_object_ty: CollabType,
@ -26,7 +26,7 @@ impl DatabaseCloudService for LocalServerDatabaseCloudServiceImpl {
FutureResult::new(async move { Ok(CollabDocStateByOid::default()) })
}
fn get_collab_snapshots(
fn get_database_collab_object_snapshots(
&self,
_object_id: &str,
_limit: usize,

View File

@ -53,7 +53,7 @@ impl FolderCloudService for LocalServerFolderCloudServiceImpl {
FutureResult::new(async move { Ok(vec![]) })
}
fn get_collab_doc_state_f(
fn get_folder_doc_state(
&self,
_workspace_id: &str,
_uid: i64,
@ -67,7 +67,7 @@ impl FolderCloudService for LocalServerFolderCloudServiceImpl {
})
}
fn batch_create_collab_object_f(
fn batch_create_folder_collab_objects(
&self,
_workspace_id: &str,
_objects: Vec<FolderCollabParams>,

View File

@ -174,6 +174,24 @@ impl UserCloudService for LocalServerUserAuthServiceImpl {
) -> FutureResult<(), Error> {
FutureResult::new(async { Err(anyhow!("local server doesn't support create collab object")) })
}
fn create_workspace(&self, _workspace_name: &str) -> FutureResult<UserWorkspace, FlowyError> {
FutureResult::new(async {
Err(
FlowyError::local_version_not_support()
.with_context("local server doesn't support mulitple workspaces"),
)
})
}
fn delete_workspace(&self, _workspace_id: &str) -> FutureResult<(), FlowyError> {
FutureResult::new(async {
Err(
FlowyError::local_version_not_support()
.with_context("local server doesn't support mulitple workspaces"),
)
})
}
}
fn make_user_workspace() -> UserWorkspace {

View File

@ -1,9 +1,11 @@
use client_api::ws::ConnectState;
use client_api::ws::WSConnectStateReceiver;
use client_api::ws::WebSocketChannel;
use flowy_storage::ObjectStorageService;
use std::sync::Arc;
use anyhow::Error;
use client_api::collab_sync::collab_msg::CollabMessage;
use client_api::ws::{ConnectState, WSConnectStateReceiver, WebSocketChannel};
use parking_lot::RwLock;
use tokio_stream::wrappers::WatchStream;
#[cfg(feature = "enable_supabase")]

View File

@ -26,7 +26,7 @@ impl<T> DatabaseCloudService for SupabaseDatabaseServiceImpl<T>
where
T: SupabaseServerService,
{
fn get_collab_doc_state_db(
fn get_database_object_doc_state(
&self,
object_id: &str,
collab_type: CollabType,
@ -50,7 +50,7 @@ where
FutureResult::new(async { rx.await? })
}
fn batch_get_collab_doc_state_db(
fn batch_get_database_object_doc_state(
&self,
object_ids: Vec<String>,
object_ty: CollabType,
@ -72,7 +72,7 @@ where
FutureResult::new(async { rx.await? })
}
fn get_collab_snapshots(
fn get_database_collab_object_snapshots(
&self,
object_id: &str,
limit: usize,

View File

@ -131,7 +131,7 @@ where
})
}
fn get_collab_doc_state_f(
fn get_folder_doc_state(
&self,
_workspace_id: &str,
_uid: i64,
@ -154,7 +154,7 @@ where
FutureResult::new(async { rx.await? })
}
fn batch_create_collab_object_f(
fn batch_create_folder_collab_objects(
&self,
_workspace_id: &str,
_objects: Vec<FolderCollabParams>,

View File

@ -354,6 +354,24 @@ where
))
})
}
fn create_workspace(&self, _workspace_name: &str) -> FutureResult<UserWorkspace, FlowyError> {
FutureResult::new(async {
Err(
FlowyError::local_version_not_support()
.with_context("supabase server doesn't support mulitple workspaces"),
)
})
}
fn delete_workspace(&self, _workspace_id: &str) -> FutureResult<(), FlowyError> {
FutureResult::new(async {
Err(
FlowyError::local_version_not_support()
.with_context("supabase server doesn't support mulitple workspaces"),
)
})
}
}
pub struct CreateCollabAction {

View File

@ -45,7 +45,7 @@ async fn supabase_create_database_test() {
}
let updates_by_oid = database_service
.batch_get_collab_doc_state_db(row_ids, CollabType::DatabaseRow, "fake_workspace_id")
.batch_get_database_object_doc_state(row_ids, CollabType::DatabaseRow, "fake_workspace_id")
.await
.unwrap();

View File

@ -69,7 +69,7 @@ async fn supabase_get_folder_test() {
// let updates = collab_service.get_all_updates(&collab_object).await.unwrap();
let updates = folder_service
.get_collab_doc_state_f(
.get_folder_doc_state(
&user.latest_workspace.id,
user.user_id,
CollabType::Folder,
@ -86,7 +86,7 @@ async fn supabase_get_folder_test() {
.unwrap();
}
let updates = folder_service
.get_collab_doc_state_f(
.get_folder_doc_state(
&user.latest_workspace.id,
user.user_id,
CollabType::Folder,
@ -157,7 +157,7 @@ async fn supabase_duplicate_updates_test() {
.await
.unwrap();
let first_init_sync_update = folder_service
.get_collab_doc_state_f(
.get_folder_doc_state(
&user.latest_workspace.id,
user.user_id,
CollabType::Folder,
@ -179,7 +179,7 @@ async fn supabase_duplicate_updates_test() {
.await
.unwrap();
let second_init_sync_update = folder_service
.get_collab_doc_state_f(
.get_folder_doc_state(
&user.latest_workspace.id,
user.user_id,
CollabType::Folder,
@ -271,7 +271,7 @@ async fn supabase_diff_state_vector_test() {
let old_version_doc = Doc::new();
let map = { old_version_doc.get_or_insert_map("map") };
let doc_state = folder_service
.get_collab_doc_state_f(
.get_folder_doc_state(
&user.latest_workspace.id,
user.user_id,
CollabType::Folder,