| 
									
										
										
										
											2021-07-20 14:03:21 +08:00
										 |  |  | use crate::{
 | 
					
						
							|  |  |  |     entities::{app::App, workspace::*},
 | 
					
						
							|  |  |  |     errors::*,
 | 
					
						
							|  |  |  |     module::{WorkspaceDatabase, WorkspaceUser},
 | 
					
						
							| 
									
										
										
										
											2021-07-21 22:41:44 +08:00
										 |  |  |     observable::{send_observable, WorkspaceObservable},
 | 
					
						
							| 
									
										
										
										
											2021-07-20 14:03:21 +08:00
										 |  |  |     services::AppController,
 | 
					
						
							|  |  |  |     sql_tables::workspace::{WorkspaceSql, WorkspaceTable, WorkspaceTableChangeset},
 | 
					
						
							|  |  |  | };
 | 
					
						
							| 
									
										
										
										
											2021-07-19 16:15:20 +08:00
										 |  |  | use flowy_dispatch::prelude::DispatchFuture;
 | 
					
						
							| 
									
										
										
										
											2021-08-28 23:08:12 +08:00
										 |  |  | use flowy_infra::kv::KVStore;
 | 
					
						
							| 
									
										
										
										
											2021-08-24 21:38:53 +08:00
										 |  |  | use flowy_net::request::HttpRequestBuilder;
 | 
					
						
							| 
									
										
										
										
											2021-07-13 23:08:20 +08:00
										 |  |  | use std::sync::Arc;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | pub struct WorkspaceController {
 | 
					
						
							| 
									
										
										
										
											2021-07-18 23:56:36 +08:00
										 |  |  |     pub user: Arc<dyn WorkspaceUser>,
 | 
					
						
							| 
									
										
										
										
											2021-07-20 14:03:21 +08:00
										 |  |  |     pub sql: Arc<WorkspaceSql>,
 | 
					
						
							|  |  |  |     pub app_controller: Arc<AppController>,
 | 
					
						
							| 
									
										
										
										
											2021-07-13 23:08:20 +08:00
										 |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | impl WorkspaceController {
 | 
					
						
							| 
									
										
										
										
											2021-07-20 14:03:21 +08:00
										 |  |  |     pub fn new(
 | 
					
						
							|  |  |  |         user: Arc<dyn WorkspaceUser>,
 | 
					
						
							|  |  |  |         database: Arc<dyn WorkspaceDatabase>,
 | 
					
						
							|  |  |  |         app_controller: Arc<AppController>,
 | 
					
						
							|  |  |  |     ) -> Self {
 | 
					
						
							|  |  |  |         let sql = Arc::new(WorkspaceSql { database });
 | 
					
						
							|  |  |  |         Self {
 | 
					
						
							|  |  |  |             user,
 | 
					
						
							|  |  |  |             sql,
 | 
					
						
							|  |  |  |             app_controller,
 | 
					
						
							|  |  |  |         }
 | 
					
						
							|  |  |  |     }
 | 
					
						
							| 
									
										
										
										
											2021-07-13 23:08:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-23 14:37:18 +08:00
										 |  |  |     pub async fn create_workspace(
 | 
					
						
							| 
									
										
										
										
											2021-07-14 08:07:25 +08:00
										 |  |  |         &self,
 | 
					
						
							| 
									
										
										
										
											2021-08-29 22:00:42 +08:00
										 |  |  |         params: CreateWorkspaceParams,
 | 
					
						
							| 
									
										
										
										
											2021-07-19 22:44:37 +08:00
										 |  |  |     ) -> Result<Workspace, WorkspaceError> {
 | 
					
						
							| 
									
										
										
										
											2021-08-29 22:00:42 +08:00
										 |  |  |         let user_id = params.user_id.clone();
 | 
					
						
							| 
									
										
										
										
											2021-08-25 17:34:20 +08:00
										 |  |  |         // TODO: server
 | 
					
						
							| 
									
										
										
										
											2021-08-24 21:38:53 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-26 13:51:41 +08:00
										 |  |  |         let workspace_table = WorkspaceTable::new(params, &user_id);
 | 
					
						
							| 
									
										
										
										
											2021-07-29 22:22:35 +08:00
										 |  |  |         let workspace: Workspace = workspace_table.clone().into();
 | 
					
						
							| 
									
										
										
										
											2021-07-23 14:37:18 +08:00
										 |  |  |         let _ = self.sql.create_workspace(workspace_table)?;
 | 
					
						
							| 
									
										
										
										
											2021-07-29 22:22:35 +08:00
										 |  |  |         send_observable(&user_id, WorkspaceObservable::UserCreateWorkspace);
 | 
					
						
							|  |  |  |         Ok(workspace)
 | 
					
						
							| 
									
										
										
										
											2021-07-13 23:08:20 +08:00
										 |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-20 14:03:21 +08:00
										 |  |  |     pub fn update_workspace(&self, params: UpdateWorkspaceParams) -> Result<(), WorkspaceError> {
 | 
					
						
							|  |  |  |         let changeset = WorkspaceTableChangeset::new(params);
 | 
					
						
							| 
									
										
										
										
											2021-07-21 22:41:44 +08:00
										 |  |  |         let workspace_id = changeset.id.clone();
 | 
					
						
							| 
									
										
										
										
											2021-07-20 14:03:21 +08:00
										 |  |  |         let _ = self.sql.update_workspace(changeset)?;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-29 22:22:35 +08:00
										 |  |  |         send_observable(&workspace_id, WorkspaceObservable::WorkspaceUpdated);
 | 
					
						
							| 
									
										
										
										
											2021-07-20 14:03:21 +08:00
										 |  |  |         Ok(())
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-29 22:22:35 +08:00
										 |  |  |     pub fn delete_workspace(&self, workspace_id: &str) -> Result<(), WorkspaceError> {
 | 
					
						
							|  |  |  |         let user_id = self.user.user_id()?;
 | 
					
						
							|  |  |  |         let _ = self.sql.delete_workspace(workspace_id)?;
 | 
					
						
							|  |  |  |         send_observable(&user_id, WorkspaceObservable::UserDeleteWorkspace);
 | 
					
						
							|  |  |  |         Ok(())
 | 
					
						
							| 
									
										
										
										
											2021-07-20 14:03:21 +08:00
										 |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-27 23:53:53 +08:00
										 |  |  |     pub async fn open_workspace(&self, workspace_id: &str) -> Result<Workspace, WorkspaceError> {
 | 
					
						
							|  |  |  |         let user_id = self.user.user_id()?;
 | 
					
						
							|  |  |  |         let result = self
 | 
					
						
							|  |  |  |             .read_workspace_table(Some(workspace_id.to_owned()), user_id)
 | 
					
						
							| 
									
										
										
										
											2021-08-28 23:08:12 +08:00
										 |  |  |             .await?;
 | 
					
						
							| 
									
										
										
										
											2021-08-27 23:53:53 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-28 23:08:12 +08:00
										 |  |  |         match result.first() {
 | 
					
						
							| 
									
										
										
										
											2021-08-27 23:53:53 +08:00
										 |  |  |             None => Err(ErrorBuilder::new(WsErrCode::RecordNotFound).build()),
 | 
					
						
							|  |  |  |             Some(workspace_table) => {
 | 
					
						
							| 
									
										
										
										
											2021-08-28 23:08:12 +08:00
										 |  |  |                 let workspace: Workspace = workspace_table.clone().into();
 | 
					
						
							|  |  |  |                 set_current_workspace(&workspace.id);
 | 
					
						
							| 
									
										
										
										
											2021-08-27 23:53:53 +08:00
										 |  |  |                 Ok(workspace)
 | 
					
						
							|  |  |  |             },
 | 
					
						
							|  |  |  |         }
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     pub async fn read_workspaces(
 | 
					
						
							|  |  |  |         &self,
 | 
					
						
							|  |  |  |         workspace_id: Option<String>,
 | 
					
						
							|  |  |  |     ) -> Result<RepeatedWorkspace, WorkspaceError> {
 | 
					
						
							|  |  |  |         let user_id = self.user.user_id()?;
 | 
					
						
							|  |  |  |         let workspace_tables = self.read_workspace_table(workspace_id, user_id).await?;
 | 
					
						
							|  |  |  |         let mut workspaces = vec![];
 | 
					
						
							| 
									
										
										
										
											2021-08-28 23:08:12 +08:00
										 |  |  |         for table in workspace_tables {
 | 
					
						
							|  |  |  |             let apps = self.read_apps(&table.id).await?;
 | 
					
						
							|  |  |  |             let mut workspace: Workspace = table.into();
 | 
					
						
							|  |  |  |             workspace.apps.items = apps;
 | 
					
						
							| 
									
										
										
										
											2021-08-27 23:53:53 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-28 23:08:12 +08:00
										 |  |  |             workspaces.push(workspace);
 | 
					
						
							|  |  |  |         }
 | 
					
						
							| 
									
										
										
										
											2021-08-27 23:53:53 +08:00
										 |  |  |         Ok(RepeatedWorkspace { items: workspaces })
 | 
					
						
							| 
									
										
										
										
											2021-07-20 14:03:21 +08:00
										 |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-28 23:08:12 +08:00
										 |  |  |     pub async fn read_cur_workspace(&self) -> Result<Workspace, WorkspaceError> {
 | 
					
						
							|  |  |  |         let workspace_id = get_current_workspace()?;
 | 
					
						
							|  |  |  |         let mut repeated_workspace = self.read_workspaces(Some(workspace_id.clone())).await?;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if repeated_workspace.is_empty() {
 | 
					
						
							|  |  |  |             return Err(ErrorBuilder::new(WsErrCode::RecordNotFound).build());
 | 
					
						
							|  |  |  |         }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         debug_assert_eq!(repeated_workspace.len(), 1);
 | 
					
						
							|  |  |  |         let workspace = repeated_workspace
 | 
					
						
							|  |  |  |             .drain(..1)
 | 
					
						
							|  |  |  |             .collect::<Vec<Workspace>>()
 | 
					
						
							|  |  |  |             .pop()
 | 
					
						
							|  |  |  |             .unwrap();
 | 
					
						
							|  |  |  |         Ok(workspace)
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     pub async fn read_cur_apps(&self) -> Result<Vec<App>, WorkspaceError> {
 | 
					
						
							|  |  |  |         let workspace_id = get_current_workspace()?;
 | 
					
						
							|  |  |  |         let apps = self.read_apps(&workspace_id).await?;
 | 
					
						
							|  |  |  |         Ok(apps)
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-23 14:37:18 +08:00
										 |  |  |     pub async fn read_apps(&self, workspace_id: &str) -> Result<Vec<App>, WorkspaceError> {
 | 
					
						
							| 
									
										
										
										
											2021-07-20 14:03:21 +08:00
										 |  |  |         let apps = self
 | 
					
						
							|  |  |  |             .sql
 | 
					
						
							|  |  |  |             .read_apps_belong_to_workspace(workspace_id)?
 | 
					
						
							|  |  |  |             .into_iter()
 | 
					
						
							|  |  |  |             .map(|app_table| app_table.into())
 | 
					
						
							|  |  |  |             .collect::<Vec<App>>();
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Ok(apps)
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-23 14:37:18 +08:00
										 |  |  |     fn read_workspace_table(
 | 
					
						
							| 
									
										
										
										
											2021-07-19 16:15:20 +08:00
										 |  |  |         &self,
 | 
					
						
							| 
									
										
										
										
											2021-08-27 23:53:53 +08:00
										 |  |  |         workspace_id: Option<String>,
 | 
					
						
							|  |  |  |         user_id: String,
 | 
					
						
							|  |  |  |     ) -> DispatchFuture<Result<Vec<WorkspaceTable>, WorkspaceError>> {
 | 
					
						
							| 
									
										
										
										
											2021-07-20 14:03:21 +08:00
										 |  |  |         let sql = self.sql.clone();
 | 
					
						
							| 
									
										
										
										
											2021-07-19 16:15:20 +08:00
										 |  |  |         let workspace_id = workspace_id.to_owned();
 | 
					
						
							|  |  |  |         DispatchFuture {
 | 
					
						
							|  |  |  |             fut: Box::pin(async move {
 | 
					
						
							| 
									
										
										
										
											2021-08-27 23:53:53 +08:00
										 |  |  |                 let workspace = sql.read_workspaces(workspace_id, &user_id)?;
 | 
					
						
							| 
									
										
										
										
											2021-07-19 16:15:20 +08:00
										 |  |  |                 // TODO: fetch workspace from remote server
 | 
					
						
							|  |  |  |                 Ok(workspace)
 | 
					
						
							|  |  |  |             }),
 | 
					
						
							|  |  |  |         }
 | 
					
						
							|  |  |  |     }
 | 
					
						
							| 
									
										
										
										
											2021-07-13 23:08:20 +08:00
										 |  |  | }
 | 
					
						
							| 
									
										
										
										
											2021-08-24 21:38:53 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-28 23:08:12 +08:00
										 |  |  | const CURRENT_WORKSPACE_ID: &str = "current_workspace_id";
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | fn set_current_workspace(workspace: &str) {
 | 
					
						
							|  |  |  |     KVStore::set_str(CURRENT_WORKSPACE_ID, workspace.to_owned());
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | fn get_current_workspace() -> Result<String, WorkspaceError> {
 | 
					
						
							|  |  |  |     match KVStore::get_str(CURRENT_WORKSPACE_ID) {
 | 
					
						
							|  |  |  |         None => Err(ErrorBuilder::new(WsErrCode::CurrentWorkspaceNotFound).build()),
 | 
					
						
							|  |  |  |         Some(workspace_id) => Ok(workspace_id),
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-24 21:38:53 +08:00
										 |  |  | pub async fn create_workspace_request(
 | 
					
						
							|  |  |  |     params: CreateWorkspaceParams,
 | 
					
						
							|  |  |  |     url: &str,
 | 
					
						
							|  |  |  | ) -> Result<Workspace, WorkspaceError> {
 | 
					
						
							|  |  |  |     let workspace = HttpRequestBuilder::post(&url.to_owned())
 | 
					
						
							|  |  |  |         .protobuf(params)?
 | 
					
						
							|  |  |  |         .send()
 | 
					
						
							|  |  |  |         .await?
 | 
					
						
							| 
									
										
										
										
											2021-08-25 17:34:20 +08:00
										 |  |  |         .response()
 | 
					
						
							|  |  |  |         .await?;
 | 
					
						
							| 
									
										
										
										
											2021-08-24 21:38:53 +08:00
										 |  |  |     Ok(workspace)
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-27 23:53:53 +08:00
										 |  |  | pub async fn read_workspaces_request(
 | 
					
						
							| 
									
										
										
										
											2021-08-24 21:38:53 +08:00
										 |  |  |     params: QueryWorkspaceParams,
 | 
					
						
							|  |  |  |     url: &str,
 | 
					
						
							| 
									
										
										
										
											2021-08-27 23:53:53 +08:00
										 |  |  | ) -> Result<RepeatedWorkspace, WorkspaceError> {
 | 
					
						
							| 
									
										
										
										
											2021-08-25 17:34:20 +08:00
										 |  |  |     let result = HttpRequestBuilder::get(&url.to_owned())
 | 
					
						
							| 
									
										
										
										
											2021-08-24 21:38:53 +08:00
										 |  |  |         .protobuf(params)?
 | 
					
						
							|  |  |  |         .send()
 | 
					
						
							|  |  |  |         .await?
 | 
					
						
							| 
									
										
										
										
											2021-08-27 23:53:53 +08:00
										 |  |  |         .response::<RepeatedWorkspace>()
 | 
					
						
							| 
									
										
										
										
											2021-08-25 17:34:20 +08:00
										 |  |  |         .await;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     match result {
 | 
					
						
							| 
									
										
										
										
											2021-08-27 23:53:53 +08:00
										 |  |  |         Ok(repeated_workspace) => Ok(repeated_workspace),
 | 
					
						
							|  |  |  |         Err(e) => Err(e.into()),
 | 
					
						
							| 
									
										
										
										
											2021-08-25 17:34:20 +08:00
										 |  |  |     }
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | pub async fn update_workspace_request(
 | 
					
						
							|  |  |  |     params: UpdateWorkspaceParams,
 | 
					
						
							|  |  |  |     url: &str,
 | 
					
						
							|  |  |  | ) -> Result<(), WorkspaceError> {
 | 
					
						
							|  |  |  |     let _ = HttpRequestBuilder::patch(&url.to_owned())
 | 
					
						
							|  |  |  |         .protobuf(params)?
 | 
					
						
							|  |  |  |         .send()
 | 
					
						
							|  |  |  |         .await?;
 | 
					
						
							|  |  |  |     Ok(())
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | pub async fn delete_workspace_request(
 | 
					
						
							|  |  |  |     params: DeleteWorkspaceParams,
 | 
					
						
							|  |  |  |     url: &str,
 | 
					
						
							|  |  |  | ) -> Result<(), WorkspaceError> {
 | 
					
						
							| 
									
										
										
										
											2021-08-26 17:58:59 +08:00
										 |  |  |     let _ = HttpRequestBuilder::delete(url)
 | 
					
						
							| 
									
										
										
										
											2021-08-25 17:34:20 +08:00
										 |  |  |         .protobuf(params)?
 | 
					
						
							|  |  |  |         .send()
 | 
					
						
							|  |  |  |         .await?;
 | 
					
						
							|  |  |  |     Ok(())
 | 
					
						
							| 
									
										
										
										
											2021-08-24 21:38:53 +08:00
										 |  |  | }
 | 
					
						
							| 
									
										
										
										
											2021-08-26 17:58:59 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | pub async fn read_workspace_list_request(url: &str) -> Result<RepeatedWorkspace, WorkspaceError> {
 | 
					
						
							|  |  |  |     let workspaces = HttpRequestBuilder::get(url)
 | 
					
						
							|  |  |  |         .send()
 | 
					
						
							|  |  |  |         .await?
 | 
					
						
							|  |  |  |         .response::<RepeatedWorkspace>()
 | 
					
						
							|  |  |  |         .await?;
 | 
					
						
							|  |  |  |     Ok(workspaces)
 | 
					
						
							|  |  |  | }
 |