diff --git a/frontend/rust-lib/flowy-error/src/errors.rs b/frontend/rust-lib/flowy-error/src/errors.rs index e19ebb15b2..bc453054aa 100644 --- a/frontend/rust-lib/flowy-error/src/errors.rs +++ b/frontend/rust-lib/flowy-error/src/errors.rs @@ -66,6 +66,7 @@ impl FlowyError { static_flowy_error!(user_not_exist, ErrorCode::UserNotExist); static_flowy_error!(text_too_long, ErrorCode::TextTooLong); static_flowy_error!(invalid_data, ErrorCode::InvalidData); + static_flowy_error!(out_of_bounds, ErrorCode::OutOfBounds); } impl std::convert::From for FlowyError { diff --git a/frontend/rust-lib/flowy-grid/src/entities/group_entities/group_changeset.rs b/frontend/rust-lib/flowy-grid/src/entities/group_entities/group_changeset.rs index dbee60dca9..a3ebee9cb7 100644 --- a/frontend/rust-lib/flowy-grid/src/entities/group_entities/group_changeset.rs +++ b/frontend/rust-lib/flowy-grid/src/entities/group_entities/group_changeset.rs @@ -109,10 +109,19 @@ pub struct GroupViewChangesetPB { pub view_id: String, #[pb(index = 2)] - pub inserted_groups: Vec, + pub inserted_groups: Vec, #[pb(index = 3)] pub deleted_groups: Vec, } impl GroupViewChangesetPB {} + +#[derive(Debug, Default, ProtoBuf)] +pub struct InsertedGroupPB { + #[pb(index = 1)] + pub group: GroupPB, + + #[pb(index = 2)] + pub index: i32, +} 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 ff58585584..617c9a30d5 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 @@ -1,14 +1,12 @@ use crate::dart_notification::{send_dart_notification, GridNotification}; use crate::entities::{ CreateFilterParams, CreateRowParams, DeleteFilterParams, GridFilterConfiguration, GridLayout, GridLayoutPB, - GridSettingChangesetParams, GridSettingPB, GroupPB, GroupRowsChangesetPB, GroupViewChangesetPB, InsertedRowPB, + GridSettingPB, GroupPB, GroupRowsChangesetPB, GroupViewChangesetPB, InsertedGroupPB, InsertedRowPB, MoveGroupParams, RepeatedGridConfigurationFilterPB, RepeatedGridGroupConfigurationPB, RowPB, }; use crate::services::grid_editor_task::GridServiceTaskScheduler; use crate::services::grid_view_manager::{GridViewFieldDelegate, GridViewRowDelegate}; -use crate::services::group::{ - default_group_configuration, GroupConfigurationReader, GroupConfigurationWriter, GroupService, -}; +use crate::services::group::{GroupConfigurationReader, GroupConfigurationWriter, GroupService}; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::revision::{ gen_grid_filter_id, FieldRevision, FieldTypeRevision, FilterConfigurationRevision, GroupConfigurationRevision, @@ -19,6 +17,7 @@ use flowy_sync::client_grid::{GridViewRevisionChangeset, GridViewRevisionPad}; use flowy_sync::entities::revision::Revision; use lib_infra::future::{wrap_future, AFFuture, FutureResult}; use std::collections::HashMap; + use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use tokio::sync::RwLock; @@ -37,6 +36,7 @@ pub struct GridViewRevisionEditor { } impl GridViewRevisionEditor { + #[tracing::instrument(level = "trace", skip_all, err)] pub(crate) async fn new( user_id: &str, token: &str, @@ -109,7 +109,7 @@ impl GridViewRevisionEditor { // Send the group notification if the current view has groups; if let Some(changesets) = self .group_service - .write() + .read() .await .did_delete_row(row_rev, |field_id| self.field_delegate.get_field_rev(&field_id)) .await @@ -123,7 +123,7 @@ impl GridViewRevisionEditor { pub(crate) async fn did_update_row(&self, row_rev: &RowRevision) { if let Some(changesets) = self .group_service - .write() + .read() .await .did_update_row(row_rev, |field_id| self.field_delegate.get_field_rev(&field_id)) .await @@ -142,7 +142,7 @@ impl GridViewRevisionEditor { ) { if let Some(changesets) = self .group_service - .write() + .read() .await .did_move_row(row_rev, row_changeset, upper_row_id, |field_id| { self.field_delegate.get_field_rev(&field_id) @@ -156,11 +156,13 @@ impl GridViewRevisionEditor { } } + #[tracing::instrument(level = "trace", skip(self))] pub(crate) async fn load_groups(&self) -> FlowyResult> { 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() @@ -174,11 +176,37 @@ impl GridViewRevisionEditor { } else { self.group_service.read().await.groups().await }; + + tracing::trace!("Number of groups: {}", groups.len()); Ok(groups.into_iter().map(GroupPB::from).collect()) } pub(crate) async fn move_group(&self, params: MoveGroupParams) -> FlowyResult<()> { - todo!() + let _ = self + .group_service + .read() + .await + .move_group(¶ms.from_group_id, ¶ms.to_group_id) + .await?; + + match self.group_service.read().await.get_group(¶ms.from_group_id).await { + None => {} + Some((index, group)) => { + let inserted_group = InsertedGroupPB { + group: GroupPB::from(group), + index: index as i32, + }; + + let changeset = GroupViewChangesetPB { + view_id: "".to_string(), + inserted_groups: vec![inserted_group], + deleted_groups: vec![params.from_group_id.clone()], + }; + + self.notify_did_update_view(changeset).await; + } + } + Ok(()) } pub(crate) async fn get_setting(&self) -> GridSettingPB { @@ -291,17 +319,19 @@ impl RevisionObjectBuilder for GridViewRevisionPadBuilder { struct GroupConfigurationReaderImpl(Arc>); impl GroupConfigurationReader for GroupConfigurationReaderImpl { - fn get_group_configuration(&self, field_rev: Arc) -> AFFuture> { + fn get_group_configuration( + &self, + field_rev: Arc, + ) -> AFFuture>> { let view_pad = self.0.clone(); wrap_future(async move { - let view_pad = view_pad.read().await; - let configurations = view_pad.get_groups(&field_rev.id, &field_rev.ty); - match configurations { - None => { - let default_configuration = default_group_configuration(&field_rev); - Arc::new(default_configuration) - } - Some(configuration) => configuration, + let mut groups = view_pad.read().await.groups.get_objects(&field_rev.id, &field_rev.ty)?; + + if groups.is_empty() { + None + } else { + debug_assert_eq!(groups.len(), 1); + Some(groups.pop().unwrap()) } }) } @@ -328,17 +358,25 @@ impl GroupConfigurationWriter for GroupConfigurationWriterImpl { let field_id = field_id.to_owned(); wrap_future(async move { - match view_pad.write().await.get_mut_group( - &field_id, - &field_type, - &configuration_id, - |group_configuration| { - group_configuration.content = content; - }, - )? { - None => Ok(()), - Some(changeset) => apply_change(&user_id, rev_manager, changeset).await, + let is_contained = view_pad.read().await.contains_group(&field_id, &field_type); + let changeset = if is_contained { + view_pad.write().await.with_mut_group( + &field_id, + &field_type, + &configuration_id, + |group_configuration| { + group_configuration.content = content; + }, + )? + } else { + let group_rev = GroupConfigurationRevision::new(field_id.clone(), field_type, content)?; + view_pad.write().await.insert_group(&field_id, &field_type, group_rev)? + }; + + if let Some(changeset) = changeset { + let _ = apply_change(&user_id, rev_manager, changeset).await?; } + Ok(()) }) } } @@ -371,3 +409,17 @@ pub fn make_grid_setting(view_pad: &GridViewRevisionPad, field_revs: &[Arc FlowyResult<()> { let view_editor = self.get_default_view_editor().await?; - let _s = view_editor.move_group(params).await?; + let _ = view_editor.move_group(params).await?; Ok(()) } @@ -175,12 +175,11 @@ async fn make_view_editor( row_delegate: Arc, scheduler: Arc, ) -> FlowyResult { - tracing::trace!("Open view:{} editor", view_id); - let rev_manager = make_grid_view_rev_manager(user, view_id).await?; let user_id = user.user_id()?; let token = user.token()?; let view_id = view_id.to_owned(); + GridViewRevisionEditor::new( &user_id, &token, @@ -194,7 +193,6 @@ async fn make_view_editor( } pub async fn make_grid_view_rev_manager(user: &Arc, view_id: &str) -> FlowyResult { - tracing::trace!("Open view:{} editor", view_id); let user_id = user.user_id()?; let pool = user.db_pool()?; diff --git a/frontend/rust-lib/flowy-grid/src/services/group/configuration.rs b/frontend/rust-lib/flowy-grid/src/services/group/configuration.rs index 9c1562769c..f4a25d7304 100644 --- a/frontend/rust-lib/flowy-grid/src/services/group/configuration.rs +++ b/frontend/rust-lib/flowy-grid/src/services/group/configuration.rs @@ -1,5 +1,5 @@ -use crate::services::group::Group; -use flowy_error::FlowyResult; +use crate::services::group::{default_group_configuration, Group}; +use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::revision::{ FieldRevision, FieldTypeRevision, GroupConfigurationContent, GroupConfigurationRevision, GroupRecordRevision, }; @@ -9,7 +9,10 @@ use lib_infra::future::AFFuture; use std::sync::Arc; pub trait GroupConfigurationReader: Send + Sync + 'static { - fn get_group_configuration(&self, field_rev: Arc) -> AFFuture>; + fn get_group_configuration( + &self, + field_rev: Arc, + ) -> AFFuture>>; } pub trait GroupConfigurationWriter: Send + Sync + 'static { @@ -39,7 +42,22 @@ where reader: Arc, writer: Arc, ) -> FlowyResult { - let configuration_rev = reader.get_group_configuration(field_rev.clone()).await; + let configuration_rev = match reader.get_group_configuration(field_rev.clone()).await { + None => { + let default_group_configuration = default_group_configuration(&field_rev); + writer + .save_group_configuration( + &field_rev.id, + field_rev.ty, + &default_group_configuration.id, + default_group_configuration.content.clone(), + ) + .await?; + Arc::new(default_group_configuration) + } + Some(configuration) => configuration, + }; + let configuration_id = configuration_rev.id.clone(); let configuration = C::from_configuration_content(&configuration_rev.content)?; Ok(Self { @@ -63,6 +81,8 @@ where let (group_revs, groups) = merge_groups(self.configuration.get_groups(), groups); self.configuration.set_groups(group_revs); let _ = self.save_configuration().await?; + + tracing::trace!("merge new groups: {}", groups.len()); groups.into_iter().for_each(|group| { self.groups_map.insert(group.id.clone(), group); }); @@ -97,8 +117,25 @@ where self.groups_map.get_mut(group_id) } - pub(crate) fn get_group(&mut self, group_id: &str) -> Option<&Group> { - self.groups_map.get(group_id) + pub(crate) fn move_group(&mut self, from_group_id: &str, to_group_id: &str) -> FlowyResult<()> { + let from_group_index = self.groups_map.get_index_of(from_group_id); + let to_group_index = self.groups_map.get_index_of(to_group_id); + match (from_group_index, to_group_index) { + (Some(from_index), Some(to_index)) => { + self.groups_map.swap_indices(from_index, to_index); + self.configuration.swap_group(from_group_id, to_group_id); + Ok(()) + } + _ => Err(FlowyError::out_of_bounds()), + } + } + + // Returns the index and group specified by the group_id + pub(crate) fn get_group(&self, group_id: &str) -> Option<(usize, &Group)> { + match (self.groups_map.get_index_of(group_id), self.groups_map.get(group_id)) { + (Some(index), Some(group)) => Some((index, group)), + _ => None, + } } pub async fn save_configuration(&self) -> FlowyResult<()> { @@ -111,17 +148,17 @@ where } } -impl GroupConfigurationReader for Arc -where - T: GroupConfigurationReader, -{ - fn get_group_configuration(&self, field_rev: Arc) -> AFFuture> { - (**self).get_group_configuration(field_rev) - } -} +// impl GroupConfigurationReader for Arc +// where +// T: GroupConfigurationReader, +// { +// fn get_group_configuration(&self, field_rev: Arc) -> AFFuture> { +// (**self).get_group_configuration(field_rev) +// } +// } fn merge_groups(old_group_revs: &[GroupRecordRevision], groups: Vec) -> (Vec, Vec) { - // tracing::trace!("Merge group: old: {}, new: {}", old_group.len(), groups.len()); + tracing::trace!("Merge group: old: {}, new: {}", old_group_revs.len(), groups.len()); if old_group_revs.is_empty() { let new_groups = groups .iter() diff --git a/frontend/rust-lib/flowy-grid/src/services/group/controller.rs b/frontend/rust-lib/flowy-grid/src/services/group/controller.rs index 1cba496b51..af4d676b02 100644 --- a/frontend/rust-lib/flowy-grid/src/services/group/controller.rs +++ b/frontend/rust-lib/flowy-grid/src/services/group/controller.rs @@ -36,7 +36,9 @@ pub trait GroupControllerSharedOperation: Send + Sync { // The field that is used for grouping the rows fn field_id(&self) -> &str; fn groups(&self) -> Vec; + fn get_group(&self, group_id: &str) -> Option<(usize, Group)>; fn fill_groups(&mut self, row_revs: &[Arc], field_rev: &FieldRevision) -> FlowyResult>; + fn move_group(&mut self, from_group_id: &str, to_group_id: &str) -> FlowyResult<()>; fn did_update_row( &mut self, row_rev: &RowRevision, @@ -118,6 +120,11 @@ where self.configuration.clone_groups() } + fn get_group(&self, group_id: &str) -> Option<(usize, Group)> { + let group = self.configuration.get_group(group_id)?; + Some((group.0, group.1.clone())) + } + fn fill_groups(&mut self, row_revs: &[Arc], field_rev: &FieldRevision) -> FlowyResult> { for row_rev in row_revs { if let Some(cell_rev) = row_rev.cells.get(&self.field_id) { @@ -156,6 +163,10 @@ where Ok(groups) } + fn move_group(&mut self, from_group_id: &str, to_group_id: &str) -> FlowyResult<()> { + self.configuration.move_group(from_group_id, to_group_id) + } + fn did_update_row( &mut self, row_rev: &RowRevision, diff --git a/frontend/rust-lib/flowy-grid/src/services/group/controller_impls/select_option_controller/multi_select_controller.rs b/frontend/rust-lib/flowy-grid/src/services/group/controller_impls/select_option_controller/multi_select_controller.rs index 47e7dfbce9..7a208a884f 100644 --- a/frontend/rust-lib/flowy-grid/src/services/group/controller_impls/select_option_controller/multi_select_controller.rs +++ b/frontend/rust-lib/flowy-grid/src/services/group/controller_impls/select_option_controller/multi_select_controller.rs @@ -71,10 +71,9 @@ impl GroupAction for MultiSelectGroupController { impl GroupController for MultiSelectGroupController { fn will_create_row(&mut self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str) { - let group: Option<&Group> = self.configuration.get_group(group_id); - match group { + match self.configuration.get_group(group_id) { None => tracing::warn!("Can not find the group: {}", group_id), - Some(group) => { + Some((_, group)) => { let cell_rev = insert_select_option_cell(group.id.clone(), field_rev); row_rev.cells.insert(field_rev.id.clone(), cell_rev); } 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 a1cdd597af..7050c2c087 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 @@ -43,6 +43,14 @@ impl GroupService { } } + pub(crate) async fn get_group(&self, group_id: &str) -> Option<(usize, Group)> { + if let Some(group_controller) = self.group_controller.as_ref() { + group_controller.read().await.get_group(group_id) + } else { + None + } + } + pub(crate) async fn load_groups( &mut self, field_revs: &[Arc], @@ -164,9 +172,20 @@ impl GroupService { } } + #[tracing::instrument(level = "trace", skip_all)] + pub(crate) async fn move_group(&self, from_group_id: &str, to_group_id: &str) -> FlowyResult<()> { + match self.group_controller.as_ref() { + None => Ok(()), + Some(group_controller) => { + let _ = group_controller.write().await.move_group(from_group_id, to_group_id)?; + Ok(()) + } + } + } + #[tracing::instrument(level = "trace", skip_all)] async fn make_group_controller( - &mut self, + &self, field_type: &FieldType, field_rev: &Arc, ) -> FlowyResult>>> { 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 118d417c31..d284e69c76 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 @@ -4,11 +4,15 @@ use flowy_grid::services::cell::insert_select_option_cell; use flowy_grid_data_model::revision::RowChangeset; pub enum GroupScript { - AssertGroup { + AssertGroupRowCount { group_index: usize, row_count: usize, }, AssertGroupCount(usize), + AssertGroup { + group_index: usize, + expected_group: GroupPB, + }, AssertRow { group_index: usize, row_index: usize, @@ -56,7 +60,7 @@ impl GridGroupTest { pub async fn run_script(&mut self, script: GroupScript) { match script { - GroupScript::AssertGroup { group_index, row_count } => { + GroupScript::AssertGroupRowCount { group_index, row_count } => { assert_eq!(row_count, self.group_at_index(group_index).await.rows.len()); } GroupScript::AssertGroupCount(count) => { @@ -142,6 +146,13 @@ impl GridGroupTest { self.editor.move_group(params).await.unwrap(); // } + GroupScript::AssertGroup { + group_index, + expected_group: group_pb, + } => { + let group = self.group_at_index(group_index).await; + assert_eq!(group.group_id, group_pb.group_id); + } } } 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 index 798f478439..6092e97a5e 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/group_test/test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/group_test/test.rs @@ -6,15 +6,15 @@ async fn board_init_test() { let mut test = GridGroupTest::new().await; let scripts = vec![ AssertGroupCount(3), - AssertGroup { + AssertGroupRowCount { group_index: 0, row_count: 2, }, - AssertGroup { + AssertGroupRowCount { group_index: 1, row_count: 2, }, - AssertGroup { + AssertGroupRowCount { group_index: 2, row_count: 1, }, @@ -34,7 +34,7 @@ async fn board_move_row_test() { to_group_index: 0, to_row_index: 1, }, - AssertGroup { + AssertGroupRowCount { group_index: 0, row_count: 2, }, @@ -58,11 +58,11 @@ async fn board_move_row_to_other_group_test() { to_group_index: 1, to_row_index: 1, }, - AssertGroup { + AssertGroupRowCount { group_index: 0, row_count: 1, }, - AssertGroup { + AssertGroupRowCount { group_index: 1, row_count: 3, }, @@ -106,13 +106,13 @@ async fn board_create_row_test() { let mut test = GridGroupTest::new().await; let scripts = vec![ CreateRow { group_index: 0 }, - AssertGroup { + AssertGroupRowCount { group_index: 0, row_count: 3, }, CreateRow { group_index: 1 }, CreateRow { group_index: 1 }, - AssertGroup { + AssertGroupRowCount { group_index: 1, row_count: 4, }, @@ -128,7 +128,7 @@ async fn board_delete_row_test() { group_index: 0, row_index: 0, }, - AssertGroup { + AssertGroupRowCount { group_index: 0, row_count: 1, }, @@ -148,7 +148,7 @@ async fn board_delete_all_row_test() { group_index: 0, row_index: 0, }, - AssertGroup { + AssertGroupRowCount { group_index: 0, row_count: 0, }, @@ -166,11 +166,11 @@ async fn board_update_row_test() { row_index: 0, to_group_index: 1, }, - AssertGroup { + AssertGroupRowCount { group_index: 0, row_count: 1, }, - AssertGroup { + AssertGroupRowCount { group_index: 1, row_count: 3, }, @@ -188,14 +188,36 @@ async fn board_reorder_group_test() { row_index: 0, to_group_index: 1, }, - AssertGroup { + AssertGroupRowCount { group_index: 0, row_count: 1, }, - AssertGroup { + AssertGroupRowCount { group_index: 1, row_count: 3, }, ]; test.run_scripts(scripts).await; } + +#[tokio::test] +async fn board_move_group_test() { + let mut test = GridGroupTest::new().await; + let group_0 = test.group_at_index(0).await; + let group_1 = test.group_at_index(1).await; + let scripts = vec![ + MoveGroup { + from_group_index: 0, + to_group_index: 1, + }, + AssertGroup { + group_index: 0, + expected_group: group_1, + }, + AssertGroup { + group_index: 1, + expected_group: group_0, + }, + ]; + test.run_scripts(scripts).await; +} diff --git a/frontend/rust-lib/flowy-sdk/src/lib.rs b/frontend/rust-lib/flowy-sdk/src/lib.rs index ce5920e532..e0bd601987 100644 --- a/frontend/rust-lib/flowy-sdk/src/lib.rs +++ b/frontend/rust-lib/flowy-sdk/src/lib.rs @@ -74,7 +74,7 @@ fn crate_log_filter(level: String) -> String { filters.push(format!("lib_ot={}", level)); filters.push(format!("lib_ws={}", level)); filters.push(format!("lib_infra={}", level)); - // filters.push(format!("flowy_sync={}", level)); + filters.push(format!("flowy_sync={}", level)); // filters.push(format!("flowy_revision={}", level)); // filters.push(format!("lib_dispatch={}", level)); diff --git a/shared-lib/flowy-error-code/src/code.rs b/shared-lib/flowy-error-code/src/code.rs index 63f7ac7749..c5e89a99f3 100644 --- a/shared-lib/flowy-error-code/src/code.rs +++ b/shared-lib/flowy-error-code/src/code.rs @@ -125,6 +125,9 @@ pub enum ErrorCode { #[display(fmt = "Invalid data")] InvalidData = 1000, + + #[display(fmt = "Out of bounds")] + OutOfBounds = 10001, } impl ErrorCode { diff --git a/shared-lib/flowy-grid-data-model/src/revision/grid_setting_rev.rs b/shared-lib/flowy-grid-data-model/src/revision/grid_setting_rev.rs index 01ca80a380..829ebe4c07 100644 --- a/shared-lib/flowy-grid-data-model/src/revision/grid_setting_rev.rs +++ b/shared-lib/flowy-grid-data-model/src/revision/grid_setting_rev.rs @@ -49,7 +49,7 @@ where .get_mut(field_id) .and_then(|object_rev_map| object_rev_map.get_mut(field_type)); if value.is_none() { - tracing::warn!("Can't find the {:?} with", std::any::type_name::()); + tracing::warn!("[Configuration] Can't find the {:?} with", std::any::type_name::()); } value } diff --git a/shared-lib/flowy-grid-data-model/src/revision/grid_view.rs b/shared-lib/flowy-grid-data-model/src/revision/grid_view.rs index 9d4df3067e..74c3c72511 100644 --- a/shared-lib/flowy-grid-data-model/src/revision/grid_view.rs +++ b/shared-lib/flowy-grid-data-model/src/revision/grid_view.rs @@ -1,11 +1,7 @@ -use crate::revision::{ - FieldRevision, FieldTypeRevision, FilterConfiguration, FilterConfigurationRevision, FilterConfigurationsByFieldId, - GroupConfiguration, GroupConfigurationRevision, GroupConfigurationsByFieldId, -}; +use crate::revision::{FilterConfiguration, GroupConfiguration}; use nanoid::nanoid; use serde::{Deserialize, Serialize}; use serde_repr::*; -use std::sync::Arc; #[allow(dead_code)] pub fn gen_grid_view_id() -> String { @@ -40,15 +36,15 @@ pub struct GridViewRevision { pub layout: LayoutRevision, + #[serde(default)] pub filters: FilterConfiguration, #[serde(default)] pub groups: GroupConfiguration, - - // For the moment, we just use the order returned from the GridRevision - #[allow(dead_code)] - #[serde(skip, rename = "row")] - pub row_orders: Vec, + // // For the moment, we just use the order returned from the GridRevision + // #[allow(dead_code)] + // #[serde(skip, rename = "rows")] + // pub row_orders: Vec, } impl GridViewRevision { @@ -59,78 +55,33 @@ impl GridViewRevision { layout: Default::default(), filters: Default::default(), groups: Default::default(), - row_orders: vec![], + // row_orders: vec![], } } - - pub fn get_all_groups(&self, field_revs: &[Arc]) -> Option { - self.groups.get_all_objects(field_revs) - } - - pub fn get_groups( - &self, - field_id: &str, - field_type_rev: &FieldTypeRevision, - ) -> Option> { - let mut groups = self.groups.get_objects(field_id, field_type_rev)?; - if groups.is_empty() { - debug_assert_eq!(groups.len(), 1); - Some(groups.pop().unwrap()) - } else { - None - } - } - - pub fn get_mut_groups( - &mut self, - field_id: &str, - field_type: &FieldTypeRevision, - ) -> Option<&mut Vec>> { - self.groups.get_mut_objects(field_id, field_type) - } - - pub fn insert_group( - &mut self, - field_id: &str, - field_type: &FieldTypeRevision, - group_rev: GroupConfigurationRevision, - ) { - // only one group can be set - self.groups.remove_all(); - self.groups.insert_object(field_id, field_type, group_rev); - } - - pub fn get_all_filters(&self, field_revs: &[Arc]) -> Option { - self.filters.get_all_objects(field_revs) - } - - pub fn get_filters( - &self, - field_id: &str, - field_type_rev: &FieldTypeRevision, - ) -> Option>> { - self.filters.get_objects(field_id, field_type_rev) - } - - pub fn get_mut_filters( - &mut self, - field_id: &str, - field_type: &FieldTypeRevision, - ) -> Option<&mut Vec>> { - self.filters.get_mut_objects(field_id, field_type) - } - - pub fn insert_filter( - &mut self, - field_id: &str, - field_type: &FieldTypeRevision, - filter_rev: FilterConfigurationRevision, - ) { - self.filters.insert_object(field_id, field_type, filter_rev); - } } #[derive(Debug, Clone, Default, Serialize, Deserialize)] pub struct RowOrderRevision { pub row_id: String, } + +#[cfg(test)] +mod tests { + use crate::revision::GridViewRevision; + + #[test] + fn grid_view_revision_serde_test() { + let grid_view_revision = GridViewRevision { + view_id: "1".to_string(), + grid_id: "1".to_string(), + layout: Default::default(), + filters: Default::default(), + groups: Default::default(), + }; + let s = serde_json::to_string(&grid_view_revision).unwrap(); + assert_eq!( + s, + r#"{"view_id":"1","grid_id":"1","layout":0,"filters":[],"groups":[]}"# + ); + } +} diff --git a/shared-lib/flowy-grid-data-model/src/revision/group_rev.rs b/shared-lib/flowy-grid-data-model/src/revision/group_rev.rs index b8c9567cb4..caaa1b43a9 100644 --- a/shared-lib/flowy-grid-data-model/src/revision/group_rev.rs +++ b/shared-lib/flowy-grid-data-model/src/revision/group_rev.rs @@ -12,8 +12,23 @@ pub trait GroupConfigurationContent: Sized { &[] } + fn mut_groups(&mut self) -> &mut Vec { + todo!() + } + fn set_groups(&mut self, _new_groups: Vec) {} + fn swap_group(&mut self, from_group_id: &str, to_group_id: &str) { + let from_index = self + .get_groups() + .iter() + .position(|group| group.group_id == from_group_id); + let to_index = self.get_groups().iter().position(|group| group.group_id == to_group_id); + if let (Some(from), Some(to)) = (from_index, to_index) { + self.mut_groups().swap(from, to); + } + } + fn with_mut_group(&mut self, _group_id: &str, _f: F) where F: FnOnce(&mut GroupRecordRevision), @@ -120,6 +135,10 @@ impl GroupConfigurationContent for SelectOptionGroupConfigurationRevision { &self.groups } + fn mut_groups(&mut self) -> &mut Vec { + &mut self.groups + } + fn set_groups(&mut self, new_groups: Vec) { self.groups = new_groups; } diff --git a/shared-lib/flowy-sync/src/client_grid/view_revision_pad.rs b/shared-lib/flowy-sync/src/client_grid/view_revision_pad.rs index e63c5d2088..57bd783d75 100644 --- a/shared-lib/flowy-sync/src/client_grid/view_revision_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/view_revision_pad.rs @@ -52,7 +52,26 @@ impl GridViewRevisionPad { self.groups.get_all_objects(field_revs) } - pub fn get_mut_group( + #[tracing::instrument(level = "trace", skip_all, err)] + pub fn insert_group( + &mut self, + field_id: &str, + field_type: &FieldTypeRevision, + group_rev: GroupConfigurationRevision, + ) -> CollaborateResult> { + self.modify(|view| { + view.groups.insert_object(field_id, field_type, group_rev); + Ok(Some(())) + }) + } + + #[tracing::instrument(level = "trace", skip_all)] + pub fn contains_group(&self, field_id: &str, field_type: &FieldTypeRevision) -> bool { + self.view.groups.get_objects(field_id, field_type).is_some() + } + + #[tracing::instrument(level = "trace", skip_all, err)] + pub fn with_mut_group( &mut self, field_id: &str, field_type: &FieldTypeRevision, @@ -147,6 +166,8 @@ impl GridViewRevisionPad { None => Ok(None), Some(delta) => { self.delta = self.delta.compose(&delta)?; + tracing::info!("GridView: {:?}", delta); + let md5 = md5(&self.delta.json_bytes()); Ok(Some(GridViewRevisionChangeset { delta, md5 })) }