|
@@ -7,6 +7,7 @@ use appflowy_integrate::RocksCollabDB;
|
|
use bytes::Bytes;
|
|
use bytes::Bytes;
|
|
|
|
|
|
use flowy_database2::entities::DatabaseLayoutPB;
|
|
use flowy_database2::entities::DatabaseLayoutPB;
|
|
|
|
+use flowy_database2::services::share::csv::CSVFormat;
|
|
use flowy_database2::template::{make_default_board, make_default_calendar, make_default_grid};
|
|
use flowy_database2::template::{make_default_board, make_default_calendar, make_default_grid};
|
|
use flowy_database2::DatabaseManager2;
|
|
use flowy_database2::DatabaseManager2;
|
|
use flowy_document2::document_data::DocumentDataWrapper;
|
|
use flowy_document2::document_data::DocumentDataWrapper;
|
|
@@ -16,7 +17,7 @@ use flowy_error::FlowyError;
|
|
use flowy_folder2::deps::{FolderCloudService, FolderUser};
|
|
use flowy_folder2::deps::{FolderCloudService, FolderUser};
|
|
use flowy_folder2::entities::ViewLayoutPB;
|
|
use flowy_folder2::entities::ViewLayoutPB;
|
|
use flowy_folder2::manager::Folder2Manager;
|
|
use flowy_folder2::manager::Folder2Manager;
|
|
-use flowy_folder2::view_ext::{ViewDataProcessor, ViewDataProcessorMap};
|
|
|
|
|
|
+use flowy_folder2::view_ext::{FolderOperationHandler, FolderOperationHandlers};
|
|
use flowy_folder2::ViewLayout;
|
|
use flowy_folder2::ViewLayout;
|
|
use flowy_user::services::UserSession;
|
|
use flowy_user::services::UserSession;
|
|
use lib_dispatch::prelude::ToBytes;
|
|
use lib_dispatch::prelude::ToBytes;
|
|
@@ -33,29 +34,28 @@ impl Folder2DepsResolver {
|
|
) -> Arc<Folder2Manager> {
|
|
) -> Arc<Folder2Manager> {
|
|
let user: Arc<dyn FolderUser> = Arc::new(FolderUserImpl(user_session.clone()));
|
|
let user: Arc<dyn FolderUser> = Arc::new(FolderUserImpl(user_session.clone()));
|
|
|
|
|
|
- let view_processors =
|
|
|
|
- make_view_data_processor(document_manager.clone(), database_manager.clone());
|
|
|
|
|
|
+ let handlers = folder_operation_handlers(document_manager.clone(), database_manager.clone());
|
|
Arc::new(
|
|
Arc::new(
|
|
- Folder2Manager::new(user.clone(), collab_builder, view_processors, folder_cloud)
|
|
|
|
|
|
+ Folder2Manager::new(user.clone(), collab_builder, handlers, folder_cloud)
|
|
.await
|
|
.await
|
|
.unwrap(),
|
|
.unwrap(),
|
|
)
|
|
)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-fn make_view_data_processor(
|
|
|
|
|
|
+fn folder_operation_handlers(
|
|
document_manager: Arc<DocumentManager>,
|
|
document_manager: Arc<DocumentManager>,
|
|
database_manager: Arc<DatabaseManager2>,
|
|
database_manager: Arc<DatabaseManager2>,
|
|
-) -> ViewDataProcessorMap {
|
|
|
|
- let mut map: HashMap<ViewLayout, Arc<dyn ViewDataProcessor + Send + Sync>> = HashMap::new();
|
|
|
|
|
|
+) -> FolderOperationHandlers {
|
|
|
|
+ let mut map: HashMap<ViewLayout, Arc<dyn FolderOperationHandler + Send + Sync>> = HashMap::new();
|
|
|
|
|
|
- let document_processor = Arc::new(DocumentViewDataProcessor(document_manager));
|
|
|
|
- map.insert(ViewLayout::Document, document_processor);
|
|
|
|
|
|
+ let document_folder_operation = Arc::new(DocumentFolderOperation(document_manager));
|
|
|
|
+ map.insert(ViewLayout::Document, document_folder_operation);
|
|
|
|
|
|
- let database_processor = Arc::new(DatabaseViewDataProcessor(database_manager));
|
|
|
|
- map.insert(ViewLayout::Board, database_processor.clone());
|
|
|
|
- map.insert(ViewLayout::Grid, database_processor.clone());
|
|
|
|
- map.insert(ViewLayout::Calendar, database_processor);
|
|
|
|
|
|
+ let database_folder_operation = Arc::new(DatabaseFolderOperation(database_manager));
|
|
|
|
+ map.insert(ViewLayout::Board, database_folder_operation.clone());
|
|
|
|
+ map.insert(ViewLayout::Grid, database_folder_operation.clone());
|
|
|
|
+ map.insert(ViewLayout::Calendar, database_folder_operation);
|
|
Arc::new(map)
|
|
Arc::new(map)
|
|
}
|
|
}
|
|
|
|
|
|
@@ -80,8 +80,8 @@ impl FolderUser for FolderUserImpl {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-struct DocumentViewDataProcessor(Arc<DocumentManager>);
|
|
|
|
-impl ViewDataProcessor for DocumentViewDataProcessor {
|
|
|
|
|
|
+struct DocumentFolderOperation(Arc<DocumentManager>);
|
|
|
|
+impl FolderOperationHandler for DocumentFolderOperation {
|
|
/// Close the document view.
|
|
/// Close the document view.
|
|
fn close_view(&self, view_id: &str) -> FutureResult<(), FlowyError> {
|
|
fn close_view(&self, view_id: &str) -> FutureResult<(), FlowyError> {
|
|
let manager = self.0.clone();
|
|
let manager = self.0.clone();
|
|
@@ -92,10 +92,7 @@ impl ViewDataProcessor for DocumentViewDataProcessor {
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
|
|
- /// Get the view data.
|
|
|
|
- ///
|
|
|
|
- /// only use in the duplicate view.
|
|
|
|
- fn get_view_data(&self, view_id: &str) -> FutureResult<Bytes, FlowyError> {
|
|
|
|
|
|
+ fn duplicate_view(&self, view_id: &str) -> FutureResult<Bytes, FlowyError> {
|
|
let manager = self.0.clone();
|
|
let manager = self.0.clone();
|
|
let view_id = view_id.to_string();
|
|
let view_id = view_id.to_string();
|
|
FutureResult::new(async move {
|
|
FutureResult::new(async move {
|
|
@@ -106,49 +103,74 @@ impl ViewDataProcessor for DocumentViewDataProcessor {
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
|
|
- /// Create a view with built-in data.
|
|
|
|
- fn create_view_with_built_in_data(
|
|
|
|
|
|
+ fn create_view_with_view_data(
|
|
&self,
|
|
&self,
|
|
_user_id: i64,
|
|
_user_id: i64,
|
|
view_id: &str,
|
|
view_id: &str,
|
|
_name: &str,
|
|
_name: &str,
|
|
|
|
+ data: Vec<u8>,
|
|
layout: ViewLayout,
|
|
layout: ViewLayout,
|
|
_ext: HashMap<String, String>,
|
|
_ext: HashMap<String, String>,
|
|
) -> FutureResult<(), FlowyError> {
|
|
) -> FutureResult<(), FlowyError> {
|
|
debug_assert_eq!(layout, ViewLayout::Document);
|
|
debug_assert_eq!(layout, ViewLayout::Document);
|
|
-
|
|
|
|
|
|
+ // TODO: implement read the document data from custom data.
|
|
let view_id = view_id.to_string();
|
|
let view_id = view_id.to_string();
|
|
let manager = self.0.clone();
|
|
let manager = self.0.clone();
|
|
- // TODO: implement read the document data from json.
|
|
|
|
FutureResult::new(async move {
|
|
FutureResult::new(async move {
|
|
- manager.create_document(view_id, DocumentDataWrapper::default())?;
|
|
|
|
|
|
+ let data = DocumentDataPB::try_from(Bytes::from(data))?;
|
|
|
|
+ manager.create_document(view_id, data.into())?;
|
|
Ok(())
|
|
Ok(())
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
|
|
- fn create_view_with_custom_data(
|
|
|
|
|
|
+ /// Create a view with built-in data.
|
|
|
|
+ fn create_built_in_view(
|
|
&self,
|
|
&self,
|
|
_user_id: i64,
|
|
_user_id: i64,
|
|
view_id: &str,
|
|
view_id: &str,
|
|
_name: &str,
|
|
_name: &str,
|
|
- data: Vec<u8>,
|
|
|
|
layout: ViewLayout,
|
|
layout: ViewLayout,
|
|
_ext: HashMap<String, String>,
|
|
_ext: HashMap<String, String>,
|
|
) -> FutureResult<(), FlowyError> {
|
|
) -> FutureResult<(), FlowyError> {
|
|
debug_assert_eq!(layout, ViewLayout::Document);
|
|
debug_assert_eq!(layout, ViewLayout::Document);
|
|
- // TODO: implement read the document data from custom data.
|
|
|
|
|
|
+
|
|
let view_id = view_id.to_string();
|
|
let view_id = view_id.to_string();
|
|
let manager = self.0.clone();
|
|
let manager = self.0.clone();
|
|
|
|
+ // TODO: implement read the document data from json.
|
|
FutureResult::new(async move {
|
|
FutureResult::new(async move {
|
|
- let data = DocumentDataPB::try_from(Bytes::from(data))?;
|
|
|
|
|
|
+ manager.create_document(view_id, DocumentDataWrapper::default())?;
|
|
|
|
+ Ok(())
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fn import_from_bytes(
|
|
|
|
+ &self,
|
|
|
|
+ view_id: &str,
|
|
|
|
+ _name: &str,
|
|
|
|
+ bytes: Vec<u8>,
|
|
|
|
+ ) -> FutureResult<(), FlowyError> {
|
|
|
|
+ let view_id = view_id.to_string();
|
|
|
|
+ let manager = self.0.clone();
|
|
|
|
+ FutureResult::new(async move {
|
|
|
|
+ let data = DocumentDataPB::try_from(Bytes::from(bytes))?;
|
|
manager.create_document(view_id, data.into())?;
|
|
manager.create_document(view_id, data.into())?;
|
|
Ok(())
|
|
Ok(())
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ // will implement soon
|
|
|
|
+ fn import_from_file_path(
|
|
|
|
+ &self,
|
|
|
|
+ _view_id: &str,
|
|
|
|
+ _name: &str,
|
|
|
|
+ _path: String,
|
|
|
|
+ ) -> FutureResult<(), FlowyError> {
|
|
|
|
+ FutureResult::new(async move { Ok(()) })
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
-struct DatabaseViewDataProcessor(Arc<DatabaseManager2>);
|
|
|
|
-impl ViewDataProcessor for DatabaseViewDataProcessor {
|
|
|
|
|
|
+struct DatabaseFolderOperation(Arc<DatabaseManager2>);
|
|
|
|
+impl FolderOperationHandler for DatabaseFolderOperation {
|
|
fn close_view(&self, view_id: &str) -> FutureResult<(), FlowyError> {
|
|
fn close_view(&self, view_id: &str) -> FutureResult<(), FlowyError> {
|
|
let database_manager = self.0.clone();
|
|
let database_manager = self.0.clone();
|
|
let view_id = view_id.to_string();
|
|
let view_id = view_id.to_string();
|
|
@@ -158,7 +180,7 @@ impl ViewDataProcessor for DatabaseViewDataProcessor {
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
|
|
- fn get_view_data(&self, view_id: &str) -> FutureResult<Bytes, FlowyError> {
|
|
|
|
|
|
+ fn duplicate_view(&self, view_id: &str) -> FutureResult<Bytes, FlowyError> {
|
|
let database_manager = self.0.clone();
|
|
let database_manager = self.0.clone();
|
|
let view_id = view_id.to_owned();
|
|
let view_id = view_id.to_owned();
|
|
FutureResult::new(async move {
|
|
FutureResult::new(async move {
|
|
@@ -167,40 +189,10 @@ impl ViewDataProcessor for DatabaseViewDataProcessor {
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
|
|
- /// Create a database view with build-in data.
|
|
|
|
- /// If the ext contains the {"database_id": "xx"}, then it will link to
|
|
|
|
- /// the existing database. The data of the database will be shared within
|
|
|
|
- /// these references views.
|
|
|
|
- fn create_view_with_built_in_data(
|
|
|
|
- &self,
|
|
|
|
- _user_id: i64,
|
|
|
|
- view_id: &str,
|
|
|
|
- name: &str,
|
|
|
|
- layout: ViewLayout,
|
|
|
|
- _ext: HashMap<String, String>,
|
|
|
|
- ) -> FutureResult<(), FlowyError> {
|
|
|
|
- let name = name.to_string();
|
|
|
|
- let database_manager = self.0.clone();
|
|
|
|
- let data = match layout {
|
|
|
|
- ViewLayout::Grid => make_default_grid(view_id, &name),
|
|
|
|
- ViewLayout::Board => make_default_board(view_id, &name),
|
|
|
|
- ViewLayout::Calendar => make_default_calendar(view_id, &name),
|
|
|
|
- ViewLayout::Document => {
|
|
|
|
- return FutureResult::new(async move {
|
|
|
|
- Err(FlowyError::internal().context(format!("Can't handle {:?} layout type", layout)))
|
|
|
|
- });
|
|
|
|
- },
|
|
|
|
- };
|
|
|
|
- FutureResult::new(async move {
|
|
|
|
- database_manager.create_database_with_params(data).await?;
|
|
|
|
- Ok(())
|
|
|
|
- })
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
/// Create a database view with duplicated data.
|
|
/// Create a database view with duplicated data.
|
|
/// If the ext contains the {"database_id": "xx"}, then it will link
|
|
/// If the ext contains the {"database_id": "xx"}, then it will link
|
|
/// to the existing database.
|
|
/// to the existing database.
|
|
- fn create_view_with_custom_data(
|
|
|
|
|
|
+ fn create_view_with_view_data(
|
|
&self,
|
|
&self,
|
|
_user_id: i64,
|
|
_user_id: i64,
|
|
view_id: &str,
|
|
view_id: &str,
|
|
@@ -241,6 +233,68 @@ impl ViewDataProcessor for DatabaseViewDataProcessor {
|
|
},
|
|
},
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ /// Create a database view with build-in data.
|
|
|
|
+ /// If the ext contains the {"database_id": "xx"}, then it will link to
|
|
|
|
+ /// the existing database. The data of the database will be shared within
|
|
|
|
+ /// these references views.
|
|
|
|
+ fn create_built_in_view(
|
|
|
|
+ &self,
|
|
|
|
+ _user_id: i64,
|
|
|
|
+ view_id: &str,
|
|
|
|
+ name: &str,
|
|
|
|
+ layout: ViewLayout,
|
|
|
|
+ _meta: HashMap<String, String>,
|
|
|
|
+ ) -> FutureResult<(), FlowyError> {
|
|
|
|
+ let name = name.to_string();
|
|
|
|
+ let database_manager = self.0.clone();
|
|
|
|
+ let data = match layout {
|
|
|
|
+ ViewLayout::Grid => make_default_grid(view_id, &name),
|
|
|
|
+ ViewLayout::Board => make_default_board(view_id, &name),
|
|
|
|
+ ViewLayout::Calendar => make_default_calendar(view_id, &name),
|
|
|
|
+ ViewLayout::Document => {
|
|
|
|
+ return FutureResult::new(async move {
|
|
|
|
+ Err(FlowyError::internal().context(format!("Can't handle {:?} layout type", layout)))
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ };
|
|
|
|
+ FutureResult::new(async move {
|
|
|
|
+ database_manager.create_database_with_params(data).await?;
|
|
|
|
+ Ok(())
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fn import_from_bytes(
|
|
|
|
+ &self,
|
|
|
|
+ view_id: &str,
|
|
|
|
+ _name: &str,
|
|
|
|
+ bytes: Vec<u8>,
|
|
|
|
+ ) -> FutureResult<(), FlowyError> {
|
|
|
|
+ let database_manager = self.0.clone();
|
|
|
|
+ let view_id = view_id.to_string();
|
|
|
|
+ FutureResult::new(async move {
|
|
|
|
+ let content = String::from_utf8(bytes).map_err(|err| FlowyError::internal().context(err))?;
|
|
|
|
+ database_manager
|
|
|
|
+ .import_csv(view_id, content, CSVFormat::META)
|
|
|
|
+ .await?;
|
|
|
|
+ Ok(())
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fn import_from_file_path(
|
|
|
|
+ &self,
|
|
|
|
+ _view_id: &str,
|
|
|
|
+ _name: &str,
|
|
|
|
+ path: String,
|
|
|
|
+ ) -> FutureResult<(), FlowyError> {
|
|
|
|
+ let database_manager = self.0.clone();
|
|
|
|
+ FutureResult::new(async move {
|
|
|
|
+ database_manager
|
|
|
|
+ .import_csv_from_file(path, CSVFormat::META)
|
|
|
|
+ .await?;
|
|
|
|
+ Ok(())
|
|
|
|
+ })
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
#[derive(Debug, serde::Deserialize)]
|
|
#[derive(Debug, serde::Deserialize)]
|