diff --git a/frontend/app_flowy/lib/plugins/board/presentation/card/board_text_cell.dart b/frontend/app_flowy/lib/plugins/board/presentation/card/board_text_cell.dart index 5148b2c438..2da156ded8 100644 --- a/frontend/app_flowy/lib/plugins/board/presentation/card/board_text_cell.dart +++ b/frontend/app_flowy/lib/plugins/board/presentation/card/board_text_cell.dart @@ -1,10 +1,8 @@ import 'package:app_flowy/plugins/board/application/card/board_text_cell_bloc.dart'; import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart'; -import 'package:flowy_infra/image.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:flutter_svg/svg.dart'; class BoardTextCell extends StatefulWidget { final GridCellControllerBuilder cellControllerBuilder; diff --git a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs index b8a028b293..8ad370916e 100644 --- a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs +++ b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs @@ -1,5 +1,5 @@ pub use crate::entities::view::ViewDataTypePB; -use crate::entities::{ViewInfoPB, ViewLayoutTypePB}; +use crate::entities::ViewInfoPB; use crate::manager::{ViewDataProcessor, ViewDataProcessorMap}; use crate::{ dart_notification::{send_dart_notification, FolderNotification}, diff --git a/frontend/rust-lib/flowy-folder/tests/workspace/folder_test.rs b/frontend/rust-lib/flowy-folder/tests/workspace/folder_test.rs index ea2322cf94..9872641d9a 100644 --- a/frontend/rust-lib/flowy-folder/tests/workspace/folder_test.rs +++ b/frontend/rust-lib/flowy-folder/tests/workspace/folder_test.rs @@ -1,6 +1,7 @@ use crate::script::{invalid_workspace_name_test_case, FolderScript::*, FolderTest}; use flowy_folder::entities::view::ViewDataTypePB; use flowy_folder::entities::workspace::CreateWorkspacePayloadPB; +use flowy_folder::entities::ViewLayoutTypePB; use flowy_revision::disk::RevisionState; use flowy_test::{event_builder::*, FlowySDKTest}; @@ -135,11 +136,13 @@ async fn app_create_with_view() { name: "View A".to_owned(), desc: "View A description".to_owned(), data_type: ViewDataTypePB::Text, + layout: ViewLayoutTypePB::Document, }, CreateView { name: "Grid".to_owned(), desc: "Grid description".to_owned(), data_type: ViewDataTypePB::Database, + layout: ViewLayoutTypePB::Document, }, ReadApp(app.id), ]) @@ -199,11 +202,13 @@ async fn view_delete_all() { name: "View A".to_owned(), desc: "View A description".to_owned(), data_type: ViewDataTypePB::Text, + layout: ViewLayoutTypePB::Document, }, CreateView { name: "Grid".to_owned(), desc: "Grid description".to_owned(), data_type: ViewDataTypePB::Database, + layout: ViewLayoutTypePB::Document, }, ReadApp(app.id.clone()), ]) @@ -232,6 +237,7 @@ async fn view_delete_all_permanent() { name: "View A".to_owned(), desc: "View A description".to_owned(), data_type: ViewDataTypePB::Text, + layout: ViewLayoutTypePB::Document, }, ReadApp(app.id.clone()), ]) @@ -331,6 +337,7 @@ async fn folder_sync_revision_with_new_view() { name: view_name.clone(), desc: view_desc.clone(), data_type: ViewDataTypePB::Text, + layout: ViewLayoutTypePB::Document, }, AssertCurrentRevId(3), AssertNextSyncRevId(Some(3)), diff --git a/frontend/rust-lib/flowy-grid/src/entities/group_entities/group.rs b/frontend/rust-lib/flowy-grid/src/entities/group_entities/group.rs index 4a0f56e425..fc32cb79ba 100644 --- a/frontend/rust-lib/flowy-grid/src/entities/group_entities/group.rs +++ b/frontend/rust-lib/flowy-grid/src/entities/group_entities/group.rs @@ -28,7 +28,20 @@ impl std::convert::From<&GroupConfigurationRevision> for GridGroupConfigurationP #[derive(ProtoBuf, Debug, Default, Clone)] pub struct RepeatedGridGroupPB { #[pb(index = 1)] - pub(crate) items: Vec, + pub items: Vec, +} + +impl std::ops::Deref for RepeatedGridGroupPB { + type Target = Vec; + fn deref(&self) -> &Self::Target { + &self.items + } +} + +impl std::ops::DerefMut for RepeatedGridGroupPB { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.items + } } #[derive(ProtoBuf, Debug, Default, Clone)] diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index e796929ce6..7c7ef00c2e 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -9,9 +9,7 @@ use crate::services::field::{default_type_option_builder_from_type, type_option_ use crate::services::filter::GridFilterService; use crate::services::grid_view_manager::GridViewManager; use crate::services::persistence::block_index::BlockIndexCache; -use crate::services::row::{ - make_grid_blocks, make_row_from_row_rev, make_rows_from_row_revs, GridBlockSnapshot, RowRevisionBuilder, -}; +use crate::services::row::{make_grid_blocks, make_rows_from_row_revs, GridBlockSnapshot, RowRevisionBuilder}; use bytes::Bytes; use flowy_error::{ErrorCode, FlowyError, FlowyResult}; use flowy_grid_data_model::revision::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_view_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_view_editor.rs index 40a96a7255..ee121913cc 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_view_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_view_editor.rs @@ -13,6 +13,7 @@ use flowy_sync::client_grid::{GridViewRevisionChangeset, GridViewRevisionPad}; use flowy_sync::entities::grid::GridSettingChangesetParams; use flowy_sync::entities::revision::Revision; use lib_infra::future::{wrap_future, AFFuture, FutureResult}; +use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use tokio::sync::RwLock; @@ -26,6 +27,7 @@ pub struct GridViewRevisionEditor { row_delegate: Arc, group_service: Arc>, scheduler: Arc, + did_load_group: AtomicBool, } impl GridViewRevisionEditor { @@ -46,6 +48,7 @@ impl GridViewRevisionEditor { let rev_manager = Arc::new(rev_manager); let group_service = GroupService::new(Box::new(pad.clone())).await; let user_id = user_id.to_owned(); + let did_load_group = AtomicBool::new(false); Ok(Self { pad, user_id, @@ -55,6 +58,7 @@ impl GridViewRevisionEditor { field_delegate, row_delegate, group_service: Arc::new(RwLock::new(group_service)), + did_load_group, }) } @@ -140,19 +144,25 @@ impl GridViewRevisionEditor { } pub(crate) async fn load_groups(&self) -> FlowyResult> { - let field_revs = self.field_delegate.get_field_revs().await; - let row_revs = self.row_delegate.gv_row_revs().await; + let groups = if !self.did_load_group.load(Ordering::SeqCst) { + self.did_load_group.store(true, Ordering::SeqCst); + let field_revs = self.field_delegate.get_field_revs().await; + let row_revs = self.row_delegate.gv_row_revs().await; + match self + .group_service + .write() + .await + .load_groups(&field_revs, row_revs) + .await + { + None => vec![], + Some(groups) => groups, + } + } else { + self.group_service.read().await.groups().await + }; - match self - .group_service - .write() - .await - .load_groups(&field_revs, row_revs) - .await - { - None => Ok(vec![]), - Some(groups) => Ok(groups.into_iter().map(GroupPB::from).collect()), - } + Ok(groups.into_iter().map(GroupPB::from).collect()) } pub(crate) async fn get_setting(&self) -> GridSettingPB { diff --git a/frontend/rust-lib/flowy-grid/src/services/group/group_generator/checkbox_group.rs b/frontend/rust-lib/flowy-grid/src/services/group/group_generator/checkbox_group.rs index c1f4261bb5..c1284dd659 100644 --- a/frontend/rust-lib/flowy-grid/src/services/group/group_generator/checkbox_group.rs +++ b/frontend/rust-lib/flowy-grid/src/services/group/group_generator/checkbox_group.rs @@ -37,9 +37,9 @@ impl Groupable for CheckboxGroupController { fn move_row_if_match( &mut self, - field_rev: &FieldRevision, + _field_rev: &FieldRevision, _row_rev: &RowRevision, - row_changeset: &mut RowChangeset, + _row_changeset: &mut RowChangeset, _cell_data: &Self::CellDataType, _to_row_id: &str, ) -> Vec { diff --git a/frontend/rust-lib/flowy-grid/src/services/group/group_generator/group_controller.rs b/frontend/rust-lib/flowy-grid/src/services/group/group_generator/group_controller.rs index 67d4ad0f9b..05924bcfef 100644 --- a/frontend/rust-lib/flowy-grid/src/services/group/group_generator/group_controller.rs +++ b/frontend/rust-lib/flowy-grid/src/services/group/group_generator/group_controller.rs @@ -47,7 +47,7 @@ pub trait GroupController: GroupControllerSharedAction + Send + Sync { pub trait GroupControllerSharedAction: Send + Sync { // The field that is used for grouping the rows fn field_id(&self) -> &str; - fn build_groups(&self) -> Vec; + fn groups(&self) -> Vec; fn group_rows(&mut self, row_revs: &[Arc], field_rev: &FieldRevision) -> FlowyResult<()>; fn did_update_row( &mut self, @@ -194,7 +194,7 @@ where &self.field_id } - fn build_groups(&self) -> Vec { + fn groups(&self) -> Vec { let default_group = self.default_group.clone(); let mut groups: Vec = self.groups_map.values().cloned().collect(); if !default_group.rows.is_empty() { diff --git a/frontend/rust-lib/flowy-grid/src/services/group/group_generator/select_option_group.rs b/frontend/rust-lib/flowy-grid/src/services/group/group_generator/select_option_group.rs index ffee185ea4..625f1fa643 100644 --- a/frontend/rust-lib/flowy-grid/src/services/group/group_generator/select_option_group.rs +++ b/frontend/rust-lib/flowy-grid/src/services/group/group_generator/select_option_group.rs @@ -249,11 +249,9 @@ fn move_row( ) { cell_data.select_options.iter().for_each(|option| { // Remove the row in which group contains the row - if option.id == group.id { - if group.contains_row(&row_rev.id) { - group_changeset.push(GroupRowsChangesetPB::delete(group.id.clone(), vec![row_rev.id.clone()])); - group.remove_row(&row_rev.id); - } + if option.id == group.id && group.contains_row(&row_rev.id) { + group_changeset.push(GroupRowsChangesetPB::delete(group.id.clone(), vec![row_rev.id.clone()])); + group.remove_row(&row_rev.id); } // Find the inserted group diff --git a/frontend/rust-lib/flowy-grid/src/services/group/group_service.rs b/frontend/rust-lib/flowy-grid/src/services/group/group_service.rs index af0ec90ba4..4424b0edcc 100644 --- a/frontend/rust-lib/flowy-grid/src/services/group/group_service.rs +++ b/frontend/rust-lib/flowy-grid/src/services/group/group_service.rs @@ -7,7 +7,9 @@ use crate::services::group::{ }; use bytes::Bytes; use flowy_error::FlowyResult; -use flowy_grid_data_model::revision::{gen_grid_group_id, FieldRevision, GroupConfigurationRevision, RowRevision, RowChangeset}; +use flowy_grid_data_model::revision::{ + gen_grid_group_id, FieldRevision, GroupConfigurationRevision, RowChangeset, RowRevision, +}; use lib_infra::future::AFFuture; use std::future::Future; use std::sync::Arc; @@ -18,7 +20,6 @@ pub trait GroupConfigurationDelegate: Send + Sync + 'static { } pub(crate) struct GroupService { - pub groups: Vec, delegate: Box, group_controller: Option>>, } @@ -26,12 +27,19 @@ pub(crate) struct GroupService { impl GroupService { pub(crate) async fn new(delegate: Box) -> Self { Self { - groups: vec![], delegate, group_controller: None, } } + pub(crate) async fn groups(&self) -> Vec { + if let Some(group_action_handler) = self.group_controller.as_ref() { + group_action_handler.read().await.groups() + } else { + vec![] + } + } + pub(crate) async fn load_groups( &mut self, field_revs: &[Arc], @@ -44,10 +52,7 @@ impl GroupService { .build_groups(&field_type, &field_rev, row_revs, configuration) .await { - Ok(groups) => { - self.groups = groups.clone(); - Some(groups) - } + Ok(groups) => Some(groups), Err(_) => None, } } @@ -183,7 +188,7 @@ impl GroupService { if let Some(group_action_handler) = self.group_controller.as_ref() { let mut write_guard = group_action_handler.write().await; let _ = write_guard.group_rows(&row_revs, field_rev)?; - groups = write_guard.build_groups(); + groups = write_guard.groups(); drop(write_guard); } diff --git a/frontend/rust-lib/flowy-grid/tests/grid/block_test/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/block_test/script.rs index 3830d7f1fe..3aa22cc488 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/block_test/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/block_test/script.rs @@ -56,7 +56,7 @@ pub struct GridRowTest { impl GridRowTest { pub async fn new() -> Self { - let editor_test = GridEditorTest::new().await; + let editor_test = GridEditorTest::new_table().await; Self { inner: editor_test } } diff --git a/frontend/rust-lib/flowy-grid/tests/grid/cell_test/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/cell_test/script.rs index 4def72696d..670ba6327c 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/cell_test/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/cell_test/script.rs @@ -11,7 +11,7 @@ pub struct GridCellTest { impl GridCellTest { pub async fn new() -> Self { - let inner = GridEditorTest::new().await; + let inner = GridEditorTest::new_table().await; Self { inner } } diff --git a/frontend/rust-lib/flowy-grid/tests/grid/field_test/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/field_test/script.rs index 6d910f3516..ebe3d3adf2 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/field_test/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/field_test/script.rs @@ -26,7 +26,7 @@ pub struct GridFieldTest { impl GridFieldTest { pub async fn new() -> Self { - let editor_test = GridEditorTest::new().await; + let editor_test = GridEditorTest::new_table().await; Self { inner: editor_test } } diff --git a/frontend/rust-lib/flowy-grid/tests/grid/filter_test/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/filter_test/script.rs index cfbc8c8926..d629b78fb0 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/filter_test/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/filter_test/script.rs @@ -36,7 +36,7 @@ pub struct GridFilterTest { impl GridFilterTest { pub async fn new() -> Self { - let editor_test = GridEditorTest::new().await; + let editor_test = GridEditorTest::new_table().await; Self { inner: editor_test } diff --git a/frontend/rust-lib/flowy-grid/tests/grid/grid_editor.rs b/frontend/rust-lib/flowy-grid/tests/grid/grid_editor.rs index a83c3121a5..7300c524bb 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_editor.rs @@ -36,12 +36,25 @@ pub struct GridEditorTest { } impl GridEditorTest { - pub async fn new() -> Self { + pub async fn new_table() -> Self { + Self::new(GridLayout::Table).await + } + + pub async fn new_board() -> Self { + Self::new(GridLayout::Board).await + } + + pub async fn new(layout: GridLayout) -> Self { let sdk = FlowySDKTest::default(); let _ = sdk.init_user().await; let build_context = make_test_grid(); let view_data: Bytes = build_context.into(); - let test = ViewTest::new_grid_view(&sdk, view_data.to_vec()).await; + + let test = match layout { + GridLayout::Table => ViewTest::new_grid_view(&sdk, view_data.to_vec()).await, + GridLayout::Board => ViewTest::new_board_view(&sdk, view_data.to_vec()).await, + }; + let editor = sdk.grid_manager.open_grid(&test.view.id).await.unwrap(); let field_revs = editor.get_field_revs(None).await.unwrap(); let block_meta_revs = editor.get_block_meta_revs().await.unwrap(); diff --git a/frontend/rust-lib/flowy-grid/tests/grid/group_test/mod.rs b/frontend/rust-lib/flowy-grid/tests/grid/group_test/mod.rs index 1e31e92a96..63d424afaf 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/group_test/mod.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/group_test/mod.rs @@ -1 +1,2 @@ mod script; +mod test; diff --git a/frontend/rust-lib/flowy-grid/tests/grid/group_test/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/group_test/script.rs index f338770324..7c3bc3b629 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/group_test/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/group_test/script.rs @@ -1,9 +1,23 @@ use crate::grid::grid_editor::GridEditorTest; -use flowy_grid::entities::MoveRowParams; +use flowy_grid::entities::{GroupPB, MoveRowParams, RowPB}; pub enum GroupScript { - MoveCard { from_row_id: String, to_row_id: String }, + AssertGroup { + group_index: usize, + row_count: usize, + }, AssertGroupCount(usize), + AssertGroupRow { + group_index: usize, + row_index: usize, + row: RowPB, + }, + MoveRow { + from_group_index: usize, + from_row_index: usize, + to_group_index: usize, + to_row_index: usize, + }, } pub struct GridGroupTest { @@ -12,7 +26,7 @@ pub struct GridGroupTest { impl GridGroupTest { pub async fn new() -> Self { - let editor_test = GridEditorTest::new().await; + let editor_test = GridEditorTest::new_board().await; Self { inner: editor_test } } @@ -24,19 +38,48 @@ impl GridGroupTest { pub async fn run_script(&mut self, script: GroupScript) { match script { - GroupScript::MoveCard { from_row_id, to_row_id } => { - let params = MoveRowParams { - view_id: self.inner.grid_id.clone(), - from_row_id, - to_row_id, - }; - let _ = self.editor.move_row(params).await.unwrap(); + GroupScript::AssertGroup { group_index, row_count } => { + assert_eq!(row_count, self.group_at_index(group_index).await.rows.len()); } GroupScript::AssertGroupCount(count) => { + let groups = self.editor.load_groups().await.unwrap(); + assert_eq!(count, groups.len()); + } + GroupScript::MoveRow { + from_group_index, + from_row_index, + to_group_index, + to_row_index, + } => { + let groups: Vec = self.editor.load_groups().await.unwrap().items; + let from_row = groups.get(from_group_index).unwrap().rows.get(from_row_index).unwrap(); + let to_row = groups.get(to_group_index).unwrap().rows.get(to_row_index).unwrap(); + let params = MoveRowParams { + view_id: self.inner.grid_id.clone(), + from_row_id: from_row.id.clone(), + to_row_id: to_row.id.clone(), + }; + + self.editor.move_row(params).await.unwrap(); + } + GroupScript::AssertGroupRow { + group_index, + row_index, + row, + } => { // + let group = self.group_at_index(group_index).await; + let compare_row = group.rows.get(row_index).unwrap().clone(); + + assert_eq!(row.id, compare_row.id); } } } + + pub async fn group_at_index(&self, index: usize) -> GroupPB { + let groups = self.editor.load_groups().await.unwrap().items; + groups.get(index).unwrap().clone() + } } impl std::ops::Deref for GridGroupTest { diff --git a/frontend/rust-lib/flowy-grid/tests/grid/group_test/test.rs b/frontend/rust-lib/flowy-grid/tests/grid/group_test/test.rs new file mode 100644 index 0000000000..f568dfb816 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/tests/grid/group_test/test.rs @@ -0,0 +1,51 @@ +use crate::grid::group_test::script::GridGroupTest; +use crate::grid::group_test::script::GroupScript::*; + +#[tokio::test] +async fn board_init_test() { + let mut test = GridGroupTest::new().await; + let scripts = vec![ + AssertGroupCount(3), + AssertGroup { + group_index: 0, + row_count: 2, + }, + AssertGroup { + group_index: 1, + row_count: 2, + }, + AssertGroup { + group_index: 2, + row_count: 1, + }, + ]; + test.run_scripts(scripts).await; +} + +#[tokio::test] +async fn board_move_row_test() { + let mut test = GridGroupTest::new().await; + let group = test.group_at_index(0).await; + let scripts = vec![ + MoveRow { + from_group_index: 0, + from_row_index: 0, + to_group_index: 1, + to_row_index: 1, + }, + AssertGroup { + group_index: 0, + row_count: 1, + }, + AssertGroup { + group_index: 1, + row_count: 3, + }, + AssertGroupRow { + group_index: 1, + row_index: 1, + row: group.rows.get(0).unwrap().clone(), + }, + ]; + test.run_scripts(scripts).await; +} diff --git a/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs b/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs index d997d71be4..3fb08e484a 100644 --- a/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs +++ b/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs @@ -184,7 +184,7 @@ impl ViewDataProcessor for TextBlockViewDataProcessor { &self, user_id: &str, view_id: &str, - sub_data_type: ViewLayoutTypePB, + _sub_data_type: ViewLayoutTypePB, ) -> FutureResult { let user_id = user_id.to_string(); let view_id = view_id.to_string(); diff --git a/shared-lib/flowy-sync/src/client_grid/block_revision_pad.rs b/shared-lib/flowy-sync/src/client_grid/block_revision_pad.rs index f563f4b6fc..edb6ef37e5 100644 --- a/shared-lib/flowy-sync/src/client_grid/block_revision_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/block_revision_pad.rs @@ -275,7 +275,7 @@ impl std::default::Default for GridBlockRevisionPad { #[cfg(test)] mod tests { use crate::client_grid::GridBlockRevisionPad; - use flowy_grid_data_model::revision::{RowMetaChangeset, RowRevision}; + use flowy_grid_data_model::revision::{RowChangeset, RowRevision}; use lib_ot::core::TextDelta; use std::borrow::Cow; @@ -400,7 +400,7 @@ mod tests { visibility: false, }; - let changeset = RowMetaChangeset { + let changeset = RowChangeset { row_id: row.id.clone(), height: Some(100), visibility: Some(true),