mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
fix: reorder view when sibling view was deleted (#2724)
* fix: reorder view when sibling view was deleted * ci: fix test * ci: rust fmt
This commit is contained in:
parent
e3eee76609
commit
381d2e6c71
@ -105,6 +105,7 @@ class AppBloc extends Bloc<AppEvent, AppState> {
|
||||
}
|
||||
|
||||
Future<void> _createView(CreateView value, Emitter<AppState> emit) async {
|
||||
// create a child view for the current view
|
||||
final result = await ViewBackendService.createView(
|
||||
parentViewId: state.view.id,
|
||||
name: value.name,
|
||||
|
@ -34,12 +34,12 @@ default = ["custom-protocol"]
|
||||
custom-protocol = ["tauri/custom-protocol"]
|
||||
|
||||
[patch.crates-io]
|
||||
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5c519e" }
|
||||
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5c519e" }
|
||||
collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5c519e" }
|
||||
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5c519e" }
|
||||
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5c519e" }
|
||||
appflowy-integrate = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5c519e" }
|
||||
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a647d9" }
|
||||
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a647d9" }
|
||||
collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a647d9" }
|
||||
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a647d9" }
|
||||
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a647d9" }
|
||||
appflowy-integrate = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a647d9" }
|
||||
|
||||
#collab = { path = "../../AppFlowy-Collab/collab" }
|
||||
#collab-folder = { path = "../../AppFlowy-Collab/collab-folder" }
|
||||
|
20
frontend/rust-lib/Cargo.lock
generated
20
frontend/rust-lib/Cargo.lock
generated
@ -85,7 +85,7 @@ checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4"
|
||||
[[package]]
|
||||
name = "appflowy-integrate"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5c519e#5c519e988e93f6fbc7d98ce4373c5ff30a547fb1"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a647d9#a647d922ef432510d6be0abb5f968d9a75dc7011"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"collab",
|
||||
@ -887,7 +887,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5c519e#5c519e988e93f6fbc7d98ce4373c5ff30a547fb1"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a647d9#a647d922ef432510d6be0abb5f968d9a75dc7011"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@ -905,7 +905,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-client-ws"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5c519e#5c519e988e93f6fbc7d98ce4373c5ff30a547fb1"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a647d9#a647d922ef432510d6be0abb5f968d9a75dc7011"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"collab-sync",
|
||||
@ -923,7 +923,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-database"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5c519e#5c519e988e93f6fbc7d98ce4373c5ff30a547fb1"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a647d9#a647d922ef432510d6be0abb5f968d9a75dc7011"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@ -949,7 +949,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-derive"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5c519e#5c519e988e93f6fbc7d98ce4373c5ff30a547fb1"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a647d9#a647d922ef432510d6be0abb5f968d9a75dc7011"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -961,7 +961,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-document"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5c519e#5c519e988e93f6fbc7d98ce4373c5ff30a547fb1"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a647d9#a647d922ef432510d6be0abb5f968d9a75dc7011"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"collab",
|
||||
@ -978,7 +978,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-folder"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5c519e#5c519e988e93f6fbc7d98ce4373c5ff30a547fb1"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a647d9#a647d922ef432510d6be0abb5f968d9a75dc7011"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"collab",
|
||||
@ -997,7 +997,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-persistence"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5c519e#5c519e988e93f6fbc7d98ce4373c5ff30a547fb1"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a647d9#a647d922ef432510d6be0abb5f968d9a75dc7011"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"chrono",
|
||||
@ -1017,7 +1017,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-plugins"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5c519e#5c519e988e93f6fbc7d98ce4373c5ff30a547fb1"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a647d9#a647d922ef432510d6be0abb5f968d9a75dc7011"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@ -1048,7 +1048,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-sync"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5c519e#5c519e988e93f6fbc7d98ce4373c5ff30a547fb1"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=a647d9#a647d922ef432510d6be0abb5f968d9a75dc7011"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"collab",
|
||||
|
@ -33,11 +33,11 @@ opt-level = 3
|
||||
incremental = false
|
||||
|
||||
[patch.crates-io]
|
||||
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5c519e" }
|
||||
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5c519e" }
|
||||
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5c519e" }
|
||||
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5c519e" }
|
||||
appflowy-integrate = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5c519e" }
|
||||
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a647d9" }
|
||||
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a647d9" }
|
||||
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a647d9" }
|
||||
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a647d9" }
|
||||
appflowy-integrate = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "a647d9" }
|
||||
|
||||
#collab = { path = "../AppFlowy-Collab/collab" }
|
||||
#collab-folder = { path = "../AppFlowy-Collab/collab-folder" }
|
||||
|
@ -25,7 +25,7 @@ impl SnapshotDB for SnapshotDBImpl {
|
||||
.and_then(|pool| Ok(pool.get()?))
|
||||
.and_then(|conn| {
|
||||
CollabSnapshotTableSql::get_all_snapshots(object_id, &conn)
|
||||
.and_then(|rows| Ok(rows.into_iter().map(|row| row.into()).collect()))
|
||||
.map(|rows| rows.into_iter().map(|row| row.into()).collect())
|
||||
})
|
||||
.unwrap_or_else(|_| vec![])
|
||||
}
|
||||
@ -34,6 +34,8 @@ impl SnapshotDB for SnapshotDBImpl {
|
||||
&self,
|
||||
uid: i64,
|
||||
object_id: &str,
|
||||
title: String,
|
||||
collab_type: String,
|
||||
snapshot: Snapshot,
|
||||
collab: Arc<MutexCollab>,
|
||||
) -> Result<(), PersistenceError> {
|
||||
@ -74,7 +76,9 @@ impl SnapshotDB for SnapshotDBImpl {
|
||||
CollabSnapshotRow {
|
||||
id: uuid::Uuid::new_v4().to_string(),
|
||||
object_id: object_id.clone(),
|
||||
title,
|
||||
desc,
|
||||
collab_type,
|
||||
timestamp: timestamp(),
|
||||
data: new_snapshot_data,
|
||||
},
|
||||
@ -97,7 +101,9 @@ impl SnapshotDB for SnapshotDBImpl {
|
||||
struct CollabSnapshotRow {
|
||||
id: String,
|
||||
object_id: String,
|
||||
title: String,
|
||||
desc: String,
|
||||
collab_type: String,
|
||||
timestamp: i64,
|
||||
data: Vec<u8>,
|
||||
}
|
||||
@ -118,7 +124,9 @@ impl CollabSnapshotTableSql {
|
||||
let values = (
|
||||
dsl::id.eq(row.id),
|
||||
dsl::object_id.eq(row.object_id),
|
||||
dsl::title.eq(row.title),
|
||||
dsl::desc.eq(row.desc),
|
||||
dsl::collab_type.eq(row.collab_type),
|
||||
dsl::data.eq(row.data),
|
||||
dsl::timestamp.eq(row.timestamp),
|
||||
);
|
||||
|
@ -84,7 +84,6 @@ impl DatabaseManager2 {
|
||||
self.get_database(&database_id).await
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(self), err)]
|
||||
pub async fn get_database_id_with_view_id(&self, view_id: &str) -> FlowyResult<String> {
|
||||
let database_id = self.with_user_database(Err(FlowyError::internal()), |database| {
|
||||
database
|
||||
|
@ -1,12 +1,15 @@
|
||||
use crate::entities::parser::view::{ViewDesc, ViewIdentify, ViewName, ViewThumbnail};
|
||||
use crate::view_operation::gen_view_id;
|
||||
use collab_folder::core::{View, ViewLayout};
|
||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||
use flowy_error::ErrorCode;
|
||||
use std::collections::HashMap;
|
||||
use std::convert::TryInto;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
use collab_folder::core::{View, ViewLayout};
|
||||
|
||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||
use flowy_error::ErrorCode;
|
||||
|
||||
use crate::entities::parser::view::{ViewDesc, ViewIdentify, ViewName, ViewThumbnail};
|
||||
use crate::view_operation::gen_view_id;
|
||||
|
||||
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
|
||||
pub struct ViewPB {
|
||||
#[pb(index = 1)]
|
||||
@ -284,7 +287,7 @@ pub struct MoveViewPayloadPB {
|
||||
}
|
||||
|
||||
pub struct MoveViewParams {
|
||||
pub item_id: String,
|
||||
pub view_id: String,
|
||||
pub from: usize,
|
||||
pub to: usize,
|
||||
}
|
||||
@ -295,7 +298,7 @@ impl TryInto<MoveViewParams> for MoveViewPayloadPB {
|
||||
fn try_into(self) -> Result<MoveViewParams, Self::Error> {
|
||||
let view_id = ViewIdentify::parse(self.view_id)?.0;
|
||||
Ok(MoveViewParams {
|
||||
item_id: view_id,
|
||||
view_id,
|
||||
from: self.from as usize,
|
||||
to: self.to as usize,
|
||||
})
|
||||
|
@ -72,8 +72,6 @@ pub async fn read_cur_workspace_setting_handler(
|
||||
folder: AFPluginState<Arc<Folder2Manager>>,
|
||||
) -> DataResult<WorkspaceSettingPB, FlowyError> {
|
||||
let workspace = folder.get_current_workspace().await?;
|
||||
let views = folder.get_workspace_views(&workspace.id).await?;
|
||||
let workspace: WorkspacePB = (workspace, views).into();
|
||||
let latest_view: Option<ViewPB> = folder.get_current_view().await;
|
||||
data_result_ok(WorkspaceSettingPB {
|
||||
workspace,
|
||||
@ -149,7 +147,7 @@ pub(crate) async fn move_view_handler(
|
||||
) -> Result<(), FlowyError> {
|
||||
let params: MoveViewParams = data.into_inner().try_into()?;
|
||||
folder
|
||||
.move_view(¶ms.item_id, params.from, params.to)
|
||||
.move_view(¶ms.view_id, params.from, params.to)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ use lib_infra::util::timestamp;
|
||||
use crate::deps::{FolderCloudService, FolderUser};
|
||||
use crate::entities::{
|
||||
view_pb_with_child_views, CreateViewParams, CreateWorkspaceParams, DeletedViewPB,
|
||||
RepeatedTrashPB, RepeatedViewPB, RepeatedWorkspacePB, UpdateViewParams, ViewPB,
|
||||
RepeatedTrashPB, RepeatedViewPB, RepeatedWorkspacePB, UpdateViewParams, ViewPB, WorkspacePB,
|
||||
};
|
||||
use crate::notification::{
|
||||
send_notification, send_workspace_notification, send_workspace_setting_notification,
|
||||
@ -61,11 +61,17 @@ impl Folder2Manager {
|
||||
Ok(manager)
|
||||
}
|
||||
|
||||
pub async fn get_current_workspace(&self) -> FlowyResult<Workspace> {
|
||||
match self.with_folder(None, |folder| folder.get_current_workspace()) {
|
||||
None => Err(FlowyError::record_not_found().context("Can not find the workspace")),
|
||||
Some(workspace) => Ok(workspace),
|
||||
}
|
||||
pub async fn get_current_workspace(&self) -> FlowyResult<WorkspacePB> {
|
||||
self.with_folder(Err(FlowyError::internal()), |folder| {
|
||||
match folder.get_current_workspace() {
|
||||
None => Err(FlowyError::record_not_found().context("Can not find the workspace")),
|
||||
Some(workspace) => {
|
||||
let views = get_workspace_view_pbs(&workspace.id, folder);
|
||||
let workspace: WorkspacePB = (workspace, views).into();
|
||||
Ok(workspace)
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Return a list of views of the current workspace.
|
||||
@ -307,18 +313,48 @@ impl Folder2Manager {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Move the view from one position to another position.
|
||||
#[tracing::instrument(level = "debug", skip(self), err)]
|
||||
/// Move the view with given id from one position to another position.
|
||||
/// The view will be moved to the new position in the same parent view.
|
||||
/// The passed in index is the index of the view that displayed in the UI.
|
||||
/// We need to convert the index to the real index of the view in the parent view.
|
||||
#[tracing::instrument(level = "trace", skip(self), err)]
|
||||
pub async fn move_view(&self, view_id: &str, from: usize, to: usize) -> FlowyResult<()> {
|
||||
let view = self.with_folder(None, |folder| {
|
||||
folder.move_view(view_id, from as u32, to as u32)
|
||||
});
|
||||
if let Some((is_workspace, parent_view_id, child_views)) = self.get_view_relation(view_id).await
|
||||
{
|
||||
// The display parent view is the view that is displayed in the UI
|
||||
let display_views = if is_workspace {
|
||||
self
|
||||
.get_current_workspace()
|
||||
.await?
|
||||
.views
|
||||
.into_iter()
|
||||
.map(|view| view.id)
|
||||
.collect::<Vec<_>>()
|
||||
} else {
|
||||
self
|
||||
.get_view(&parent_view_id)
|
||||
.await?
|
||||
.child_views
|
||||
.into_iter()
|
||||
.map(|view| view.id)
|
||||
.collect::<Vec<_>>()
|
||||
};
|
||||
|
||||
match view {
|
||||
None => tracing::error!("Couldn't find the view. It should not be empty"),
|
||||
Some(view) => {
|
||||
notify_parent_view_did_change(self.mutex_folder.clone(), vec![view.parent_view_id]);
|
||||
},
|
||||
if display_views.len() > to {
|
||||
let to_view_id = display_views[to].clone();
|
||||
|
||||
// Find the actual index of the view in the parent view
|
||||
let actual_from_index = child_views.iter().position(|id| id == view_id);
|
||||
let actual_to_index = child_views.iter().position(|id| id == &to_view_id);
|
||||
if let (Some(actual_from_index), Some(actual_to_index)) =
|
||||
(actual_from_index, actual_to_index)
|
||||
{
|
||||
self.with_folder((), |folder| {
|
||||
folder.move_view(view_id, actual_from_index as u32, actual_to_index as u32);
|
||||
});
|
||||
notify_parent_view_did_change(self.mutex_folder.clone(), vec![parent_view_id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@ -516,6 +552,40 @@ impl Folder2Manager {
|
||||
Some(processor) => Ok(processor.clone()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the relation of the view. The relation is a tuple of (is_workspace, parent_view_id,
|
||||
/// child_view_ids). If the view is a workspace, then the parent_view_id is the workspace id.
|
||||
/// Otherwise, the parent_view_id is the parent view id of the view. The child_view_ids is the
|
||||
/// child view ids of the view.
|
||||
async fn get_view_relation(&self, view_id: &str) -> Option<(bool, String, Vec<String>)> {
|
||||
self.with_folder(None, |folder| {
|
||||
let view = folder.views.get_view(view_id)?;
|
||||
match folder.views.get_view(&view.parent_view_id) {
|
||||
None => folder.get_current_workspace().map(|workspace| {
|
||||
(
|
||||
true,
|
||||
workspace.id,
|
||||
workspace
|
||||
.child_views
|
||||
.items
|
||||
.into_iter()
|
||||
.map(|view| view.id)
|
||||
.collect::<Vec<String>>(),
|
||||
)
|
||||
}),
|
||||
Some(parent_view) => Some((
|
||||
false,
|
||||
parent_view.id,
|
||||
parent_view
|
||||
.children
|
||||
.items
|
||||
.into_iter()
|
||||
.map(|view| view.id)
|
||||
.collect::<Vec<String>>(),
|
||||
)),
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Listen on the [ViewChange] after create/delete/update events happened
|
||||
@ -594,6 +664,7 @@ fn listen_on_trash_change(mut rx: TrashChangeReceiver, weak_mutex_folder: &Weak<
|
||||
});
|
||||
}
|
||||
|
||||
/// Return the views that belong to the workspace. The views are filtered by the trash.
|
||||
fn get_workspace_view_pbs(workspace_id: &str, folder: &Folder) -> Vec<ViewPB> {
|
||||
let trash_ids = folder
|
||||
.trash
|
||||
|
@ -2,7 +2,9 @@
|
||||
CREATE TABLE collab_snapshot (
|
||||
id TEXT NOT NULL PRIMARY KEY DEFAULT '',
|
||||
object_id TEXT NOT NULL DEFAULT '',
|
||||
title TEXT NOT NULL DEFAULT '',
|
||||
desc TEXT NOT NULL DEFAULT '',
|
||||
collab_type TEXT NOT NULL DEFAULT '',
|
||||
timestamp BIGINT NOT NULL DEFAULT 0,
|
||||
data BLOB NOT NULL DEFAULT (x'')
|
||||
);
|
@ -4,7 +4,9 @@ diesel::table! {
|
||||
collab_snapshot (id) {
|
||||
id -> Text,
|
||||
object_id -> Text,
|
||||
title -> Text,
|
||||
desc -> Text,
|
||||
collab_type -> Text,
|
||||
timestamp -> BigInt,
|
||||
data -> Binary,
|
||||
}
|
||||
|
@ -1,14 +1,18 @@
|
||||
use nanoid::nanoid;
|
||||
use parking_lot::RwLock;
|
||||
use std::env::temp_dir;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::event_builder::EventBuilder;
|
||||
use nanoid::nanoid;
|
||||
use parking_lot::RwLock;
|
||||
|
||||
use flowy_core::{AppFlowyCore, AppFlowyCoreConfig};
|
||||
use flowy_folder2::entities::{CreateViewPayloadPB, RepeatedViewIdPB, ViewPB, WorkspaceSettingPB};
|
||||
use flowy_folder2::entities::{
|
||||
CreateViewPayloadPB, RepeatedViewIdPB, ViewIdPB, ViewPB, WorkspaceSettingPB,
|
||||
};
|
||||
use flowy_user::entities::{AuthTypePB, UserProfilePB};
|
||||
|
||||
use crate::event_builder::EventBuilder;
|
||||
use crate::user_event::{async_sign_up, init_user_setting, SignUpContext};
|
||||
|
||||
pub mod event_builder;
|
||||
pub mod folder_event;
|
||||
pub mod user_event;
|
||||
@ -68,6 +72,15 @@ impl FlowyCoreTest {
|
||||
.parse::<flowy_folder2::entities::WorkspaceSettingPB>()
|
||||
}
|
||||
|
||||
pub async fn get_all_workspace_views(&self) -> Vec<ViewPB> {
|
||||
EventBuilder::new(self.clone())
|
||||
.event(flowy_folder2::event_map::FolderEvent::ReadWorkspaceViews)
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<flowy_folder2::entities::RepeatedViewPB>()
|
||||
.items
|
||||
}
|
||||
|
||||
pub async fn delete_view(&self, view_id: &str) {
|
||||
let payload = RepeatedViewIdPB {
|
||||
items: vec![view_id.to_string()],
|
||||
@ -99,6 +112,17 @@ impl FlowyCoreTest {
|
||||
.await
|
||||
.parse::<flowy_folder2::entities::ViewPB>()
|
||||
}
|
||||
|
||||
pub async fn get_view(&self, view_id: &str) -> ViewPB {
|
||||
EventBuilder::new(self.clone())
|
||||
.event(flowy_folder2::event_map::FolderEvent::ReadView)
|
||||
.payload(ViewIdPB {
|
||||
value: view_id.to_string(),
|
||||
})
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<flowy_folder2::entities::ViewPB>()
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for FlowyCoreTest {
|
||||
|
@ -240,13 +240,7 @@ async fn multiple_hierarchy_view_test() {
|
||||
}
|
||||
}
|
||||
|
||||
let mut views = EventBuilder::new(test.clone())
|
||||
.event(flowy_folder2::event_map::FolderEvent::ReadWorkspaceViews)
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<flowy_folder2::entities::RepeatedViewPB>()
|
||||
.items;
|
||||
|
||||
let mut views = test.get_all_workspace_views().await;
|
||||
// There will be one default view when AppFlowy is initialized. So there will be 4 views in total
|
||||
assert_eq!(views.len(), 4);
|
||||
views.remove(0);
|
||||
@ -294,15 +288,7 @@ async fn multiple_hierarchy_view_test() {
|
||||
|
||||
for (k, _child_view) in child_view.child_views.into_iter().enumerate() {
|
||||
// Get the last level view
|
||||
let sub_child = EventBuilder::new(test.clone())
|
||||
.event(flowy_folder2::event_map::FolderEvent::ReadView)
|
||||
.payload(ViewIdPB {
|
||||
value: child.id.clone(),
|
||||
})
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<flowy_folder2::entities::ViewPB>();
|
||||
|
||||
let sub_child = test.get_view(&child.id).await;
|
||||
assert_eq!(child.name, format!("My {}-{}-{} view", i + 1, j + 1, k + 1));
|
||||
assert!(sub_child.child_views.is_empty());
|
||||
}
|
||||
@ -324,13 +310,7 @@ async fn move_view_event_test() {
|
||||
.await;
|
||||
}
|
||||
}
|
||||
let views = EventBuilder::new(test.clone())
|
||||
.event(flowy_folder2::event_map::FolderEvent::ReadWorkspaceViews)
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<flowy_folder2::entities::RepeatedViewPB>()
|
||||
.items;
|
||||
|
||||
let views = test.get_all_workspace_views().await;
|
||||
// There will be one default view when AppFlowy is initialized. So there will be 4 views in total
|
||||
assert_eq!(views.len(), 4);
|
||||
assert_eq!(views[1].name, "My 1 view");
|
||||
@ -348,18 +328,95 @@ async fn move_view_event_test() {
|
||||
.async_send()
|
||||
.await;
|
||||
|
||||
let views = EventBuilder::new(test.clone())
|
||||
.event(flowy_folder2::event_map::FolderEvent::ReadWorkspaceViews)
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<flowy_folder2::entities::RepeatedViewPB>()
|
||||
.items;
|
||||
|
||||
let views = test.get_all_workspace_views().await;
|
||||
assert_eq!(views[1].name, "My 2 view");
|
||||
assert_eq!(views[2].name, "My 1 view");
|
||||
assert_eq!(views[3].name, "My 3 view");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn move_view_event_after_delete_view_test() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
let current_workspace = test.get_current_workspace().await.workspace;
|
||||
for i in 1..6 {
|
||||
let _ = test
|
||||
.create_view(¤t_workspace.id, format!("My {} view", i))
|
||||
.await;
|
||||
}
|
||||
let views = test.get_all_workspace_views().await;
|
||||
assert_eq!(views[1].name, "My 1 view");
|
||||
assert_eq!(views[2].name, "My 2 view");
|
||||
assert_eq!(views[3].name, "My 3 view");
|
||||
assert_eq!(views[4].name, "My 4 view");
|
||||
assert_eq!(views[5].name, "My 5 view");
|
||||
test.delete_view(&views[3].id).await;
|
||||
|
||||
// There will be one default view when AppFlowy is initialized. So there will be 4 views in total
|
||||
let views = test.get_all_workspace_views().await;
|
||||
assert_eq!(views[1].name, "My 1 view");
|
||||
assert_eq!(views[2].name, "My 2 view");
|
||||
assert_eq!(views[3].name, "My 4 view");
|
||||
assert_eq!(views[4].name, "My 5 view");
|
||||
|
||||
let payload = MoveViewPayloadPB {
|
||||
view_id: views[1].id.clone(),
|
||||
from: 1,
|
||||
to: 3,
|
||||
};
|
||||
let _ = EventBuilder::new(test.clone())
|
||||
.event(flowy_folder2::event_map::FolderEvent::MoveView)
|
||||
.payload(payload)
|
||||
.async_send()
|
||||
.await;
|
||||
|
||||
let views = test.get_all_workspace_views().await;
|
||||
assert_eq!(views[1].name, "My 2 view");
|
||||
assert_eq!(views[2].name, "My 4 view");
|
||||
assert_eq!(views[3].name, "My 1 view");
|
||||
assert_eq!(views[4].name, "My 5 view");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn move_view_event_after_delete_view_test2() {
|
||||
let test = FlowyCoreTest::new_with_user().await;
|
||||
let current_workspace = test.get_current_workspace().await.workspace;
|
||||
let parent = test
|
||||
.create_view(¤t_workspace.id, "My view".to_string())
|
||||
.await;
|
||||
|
||||
for j in 1..6 {
|
||||
let _ = test
|
||||
.create_view(&parent.id, format!("My 1-{} view", j))
|
||||
.await;
|
||||
}
|
||||
|
||||
let views = test.get_view(&parent.id).await.child_views;
|
||||
assert_eq!(views.len(), 5);
|
||||
assert_eq!(views[0].name, "My 1-1 view");
|
||||
assert_eq!(views[1].name, "My 1-2 view");
|
||||
assert_eq!(views[2].name, "My 1-3 view");
|
||||
assert_eq!(views[3].name, "My 1-4 view");
|
||||
assert_eq!(views[4].name, "My 1-5 view");
|
||||
test.delete_view(&views[2].id).await;
|
||||
|
||||
let payload = MoveViewPayloadPB {
|
||||
view_id: views[0].id.clone(),
|
||||
from: 0,
|
||||
to: 2,
|
||||
};
|
||||
let _ = EventBuilder::new(test.clone())
|
||||
.event(flowy_folder2::event_map::FolderEvent::MoveView)
|
||||
.payload(payload)
|
||||
.async_send()
|
||||
.await;
|
||||
|
||||
let views = test.get_view(&parent.id).await.child_views;
|
||||
assert_eq!(views[0].name, "My 1-2 view");
|
||||
assert_eq!(views[1].name, "My 1-4 view");
|
||||
assert_eq!(views[2].name, "My 1-1 view");
|
||||
assert_eq!(views[3].name, "My 1-5 view");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn create_parent_view_with_invalid_name() {
|
||||
for (name, code) in invalid_workspace_name_test_case() {
|
||||
|
Loading…
Reference in New Issue
Block a user