diff --git a/frontend/rust-lib/flowy-grid/src/services/block_manager.rs b/frontend/rust-lib/flowy-grid/src/services/block_manager.rs index ef5632b0c5..fe825c2ebc 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_manager.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_manager.rs @@ -54,7 +54,7 @@ impl GridBlockManager { pub(crate) async fn get_editor_from_row_id(&self, row_id: &str) -> FlowyResult> { let block_id = self.persistence.get_block_id(row_id)?; - Ok(self.get_block_editor(&block_id).await?) + self.get_block_editor(&block_id).await } #[tracing::instrument(level = "trace", skip(self, start_row_id), err)] diff --git a/frontend/rust-lib/flowy-grid/src/services/block_manager_trait_impl.rs b/frontend/rust-lib/flowy-grid/src/services/block_manager_trait_impl.rs index 3adea9a853..6342ba0099 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_manager_trait_impl.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_manager_trait_impl.rs @@ -30,8 +30,7 @@ impl GridViewRowDelegate for Arc { let blocks = block_manager.get_block_snapshots(None).await.unwrap(); blocks .into_iter() - .map(|block| block.row_revs) - .flatten() + .flat_map(|block| block.row_revs) .collect::>>() }) } diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/any_cell_data.rs b/frontend/rust-lib/flowy-grid/src/services/cell/any_cell_data.rs index f7ef205435..1f64ca9ebb 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/any_cell_data.rs +++ b/frontend/rust-lib/flowy-grid/src/services/cell/any_cell_data.rs @@ -113,11 +113,15 @@ impl AnyCellData { /// * Use URLCellData to parse the data when the FieldType is URL. /// * Use String to parse the data when the FieldType is RichText, Number, or Checkbox. /// * Check out the implementation of CellDataOperation trait for more information. -#[derive(Default)] +#[derive(Default, Debug)] pub struct CellBytes(pub Bytes); +pub trait CellDataIsEmpty { + fn is_empty(&self) -> bool; +} + pub trait CellBytesParser { - type Object; + type Object: CellDataIsEmpty; fn parser(bytes: &Bytes) -> FlowyResult; } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option/checkbox_type_option_entities.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option/checkbox_type_option_entities.rs index cfe6a7b65d..1cd64e3f4c 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option/checkbox_type_option_entities.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option/checkbox_type_option_entities.rs @@ -1,4 +1,4 @@ -use crate::services::cell::{CellBytesParser, FromCellString}; +use crate::services::cell::{CellBytesParser, CellDataIsEmpty, FromCellString}; use bytes::Bytes; use flowy_error::{FlowyError, FlowyResult}; use std::str::FromStr; @@ -61,6 +61,13 @@ impl ToString for CheckboxCellData { self.0.clone() } } + +impl CellDataIsEmpty for CheckboxCellData { + fn is_empty(&self) -> bool { + self.0.is_empty() + } +} + pub struct CheckboxCellDataParser(); impl CellBytesParser for CheckboxCellDataParser { type Object = CheckboxCellData; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option/date_type_option_entities.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option/date_type_option_entities.rs index ff2dc3fc4f..5b73176796 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option/date_type_option_entities.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option/date_type_option_entities.rs @@ -1,6 +1,6 @@ use crate::entities::CellChangesetPB; use crate::entities::{GridCellIdPB, GridCellIdParams}; -use crate::services::cell::{CellBytesParser, FromCellChangeset, FromCellString}; +use crate::services::cell::{CellBytesParser, CellDataIsEmpty, FromCellChangeset, FromCellString}; use bytes::Bytes; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; @@ -200,6 +200,12 @@ impl std::default::Default for TimeFormat { } } +impl CellDataIsEmpty for DateCellDataPB { + fn is_empty(&self) -> bool { + self.date.is_empty() + } +} + pub struct DateCellDataParser(); impl CellBytesParser for DateCellDataParser { type Object = DateCellDataPB; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option/number_type_option_entities.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option/number_type_option_entities.rs index aa372222b8..bdb227ad37 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option/number_type_option_entities.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option/number_type_option_entities.rs @@ -1,4 +1,4 @@ -use crate::services::cell::{CellBytesCustomParser, CellBytesParser}; +use crate::services::cell::{CellBytesCustomParser, CellBytesParser, CellDataIsEmpty}; use crate::services::field::number_currency::Currency; use crate::services::field::{strip_currency_symbol, NumberFormat, STRIP_SYMBOL}; use bytes::Bytes; @@ -93,6 +93,12 @@ impl ToString for NumberCellData { } } } + +impl CellDataIsEmpty for NumberCellData { + fn is_empty(&self) -> bool { + self.decimal.is_none() + } +} pub struct NumberCellDataParser(); impl CellBytesParser for NumberCellDataParser { type Object = NumberCellData; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option/multi_select_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option/multi_select_type_option.rs index 93d80e85c0..21eb2b7a54 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option/multi_select_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option/multi_select_type_option.rs @@ -117,12 +117,12 @@ impl TypeOptionBuilder for MultiSelectTypeOptionBuilder { match field_type { FieldType::Checkbox => { //Add Yes and No options if it's not exist. - if self.0.options.iter().find(|option| option.name == CHECK).is_none() { + if !self.0.options.iter().any(|option| option.name == CHECK) { let check_option = SelectOptionPB::with_color(CHECK, SelectOptionColorPB::Green); self.0.options.push(check_option); } - if self.0.options.iter().find(|option| option.name == UNCHECK).is_none() { + if !self.0.options.iter().any(|option| option.name == UNCHECK) { let uncheck_option = SelectOptionPB::with_color(UNCHECK, SelectOptionColorPB::Yellow); self.0.options.push(uncheck_option); } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option/select_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option/select_option.rs index c85dfd000b..db8156b865 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option/select_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option/select_option.rs @@ -1,5 +1,7 @@ use crate::entities::{CellChangesetPB, FieldType, GridCellIdPB, GridCellIdParams}; -use crate::services::cell::{CellBytes, CellBytesParser, CellData, CellDisplayable, FromCellChangeset, FromCellString}; +use crate::services::cell::{ + CellBytes, CellBytesParser, CellData, CellDataIsEmpty, CellDisplayable, FromCellChangeset, FromCellString, +}; use crate::services::field::{MultiSelectTypeOptionPB, SingleSelectTypeOptionPB}; use bytes::Bytes; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; @@ -233,7 +235,7 @@ impl ToString for SelectOptionIds { impl std::convert::From> for SelectOptionIds { fn from(s: Option) -> Self { match s { - None => Self { 0: vec![] }, + None => Self(vec![]), Some(s) => Self::from(s), } } @@ -252,6 +254,13 @@ impl std::ops::DerefMut for SelectOptionIds { &mut self.0 } } + +impl CellDataIsEmpty for SelectOptionIds { + fn is_empty(&self) -> bool { + self.0.is_empty() + } +} + pub struct SelectOptionIdsParser(); impl CellBytesParser for SelectOptionIdsParser { type Object = SelectOptionIds; @@ -263,6 +272,12 @@ impl CellBytesParser for SelectOptionIdsParser { } } +impl CellDataIsEmpty for SelectOptionCellDataPB { + fn is_empty(&self) -> bool { + self.select_options.is_empty() + } +} + pub struct SelectOptionCellDataParser(); impl CellBytesParser for SelectOptionCellDataParser { type Object = SelectOptionCellDataPB; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option/single_select_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option/single_select_type_option.rs index 78331c8c0f..2d6db7e61c 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option/single_select_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option/single_select_type_option.rs @@ -61,7 +61,6 @@ impl CellDataOperation for SingleSel _cell_rev: Option, ) -> Result { let content_changeset = changeset.try_into_inner()?; - let new_cell_data: String; let mut insert_option_ids = content_changeset .insert_option_ids @@ -73,14 +72,12 @@ impl CellDataOperation for SingleSel // Sometimes, the insert_option_ids may contain list of option ids. For example, // copy/paste a ids string. if insert_option_ids.is_empty() { - new_cell_data = "".to_string() + Ok("".to_string()) } else { // Just take the first select option let _ = insert_option_ids.drain(1..); - new_cell_data = insert_option_ids.pop().unwrap(); + Ok(insert_option_ids.pop().unwrap()) } - - Ok(new_cell_data) } } @@ -109,12 +106,12 @@ impl TypeOptionBuilder for SingleSelectTypeOptionBuilder { match field_type { FieldType::Checkbox => { //add Yes and No options if it's not exist. - if self.0.options.iter().find(|option| option.name == CHECK).is_none() { + if !self.0.options.iter().any(|option| option.name == CHECK) { let check_option = SelectOptionPB::with_color(CHECK, SelectOptionColorPB::Green); self.0.options.push(check_option); } - if self.0.options.iter().find(|option| option.name == UNCHECK).is_none() { + if !self.0.options.iter().any(|option| option.name == UNCHECK) { let uncheck_option = SelectOptionPB::with_color(UNCHECK, SelectOptionColorPB::Yellow); self.0.options.push(uncheck_option); } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option/text_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option/text_type_option.rs index 1375e4a799..d7a5b248c3 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option/text_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option/text_type_option.rs @@ -1,8 +1,8 @@ use crate::entities::FieldType; use crate::impl_type_option; use crate::services::cell::{ - decode_cell_data_to_string, CellBytes, CellBytesParser, CellData, CellDataChangeset, CellDataOperation, - CellDisplayable, FromCellString, + decode_cell_data_to_string, CellBytes, CellBytesParser, CellData, CellDataChangeset, CellDataIsEmpty, + CellDataOperation, CellDisplayable, FromCellString, }; use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; use bytes::Bytes; @@ -125,6 +125,12 @@ impl ToString for TextCellData { } } +impl CellDataIsEmpty for TextCellData { + fn is_empty(&self) -> bool { + self.0.is_empty() + } +} + pub struct TextCellDataParser(); impl CellBytesParser for TextCellDataParser { type Object = TextCellData; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/url_type_option/url_type_option_entities.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/url_type_option/url_type_option_entities.rs index 46e67fdf18..a368f48fd2 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/url_type_option/url_type_option_entities.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/url_type_option/url_type_option_entities.rs @@ -1,4 +1,4 @@ -use crate::services::cell::{CellBytesParser, FromCellString}; +use crate::services::cell::{CellBytesParser, CellDataIsEmpty, FromCellString}; use bytes::Bytes; use flowy_derive::ProtoBuf; use flowy_error::{internal_error, FlowyResult}; @@ -26,6 +26,12 @@ impl URLCellDataPB { } } +impl CellDataIsEmpty for URLCellDataPB { + fn is_empty(&self) -> bool { + self.content.is_empty() + } +} + pub struct URLCellDataParser(); impl CellBytesParser for URLCellDataParser { type Object = URLCellDataPB; 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 bc689fda52..1cd31bb697 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -410,7 +410,7 @@ impl GridRevisionEditor { pub async fn update_row(&self, changeset: RowChangeset) -> FlowyResult<()> { let row_id = changeset.row_id.clone(); let _ = self.block_manager.update_row(changeset).await?; - self.view_manager.did_update_row(&row_id).await; + self.view_manager.did_update_cell(&row_id).await; Ok(()) } @@ -504,7 +504,7 @@ impl GridRevisionEditor { content, }; let _ = self.block_manager.update_cell(cell_changeset).await?; - self.view_manager.did_update_cell(&row_id, &field_id).await; + self.view_manager.did_update_cell(&row_id).await; Ok(()) } } 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 4b52f928d9..6aa96a4e81 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 @@ -123,15 +123,15 @@ impl GridViewRevisionEditor { }) .await; + tracing::trace!("Delete row in view changeset: {:?}", changesets); if let Some(changesets) = changesets { - tracing::trace!("{:?}", changesets); for changeset in changesets { self.notify_did_update_group(changeset).await; } } } - pub(crate) async fn did_update_view_row(&self, row_rev: &RowRevision) { + pub(crate) async fn did_update_view_cell(&self, row_rev: &RowRevision) { let changesets = self .mut_group_controller(|group_controller, field_rev| { group_controller.did_update_group_row(row_rev, &field_rev) @@ -539,11 +539,10 @@ pub fn make_grid_setting(view_pad: &GridViewRevisionPad, field_revs: &[Arc>() }) .unwrap_or_default(); @@ -553,11 +552,10 @@ pub fn make_grid_setting(view_pad: &GridViewRevisionPad, field_revs: &[Arc>() }) .unwrap_or_default(); diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_view_manager.rs b/frontend/rust-lib/flowy-grid/src/services/grid_view_manager.rs index 0aa503ce83..b74419dab0 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_view_manager.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_view_manager.rs @@ -77,15 +77,15 @@ impl GridViewManager { } } - /// Insert/Delete the group's row if the corresponding data was changed. - pub(crate) async fn did_update_row(&self, row_id: &str) { + /// Insert/Delete the group's row if the corresponding cell data was changed. + pub(crate) async fn did_update_cell(&self, row_id: &str) { match self.row_delegate.gv_get_row_rev(row_id).await { None => { tracing::warn!("Can not find the row in grid view"); } Some(row_rev) => { for view_editor in self.view_editors.iter() { - view_editor.did_update_view_row(&row_rev).await; + view_editor.did_update_view_cell(&row_rev).await; } } } @@ -97,10 +97,6 @@ impl GridViewManager { Ok(()) } - pub(crate) async fn did_update_cell(&self, row_id: &str, _field_id: &str) { - self.did_update_row(row_id).await - } - pub(crate) async fn did_delete_row(&self, row_rev: Arc) { for view_editor in self.view_editors.iter() { view_editor.did_delete_view_row(&row_rev).await; diff --git a/frontend/rust-lib/flowy-grid/src/services/group/action.rs b/frontend/rust-lib/flowy-grid/src/services/group/action.rs index fd9adcb8b5..27f0a3d90c 100644 --- a/frontend/rust-lib/flowy-grid/src/services/group/action.rs +++ b/frontend/rust-lib/flowy-grid/src/services/group/action.rs @@ -1,19 +1,79 @@ -use crate::entities::GroupChangesetPB; - +use crate::entities::{GroupChangesetPB, GroupViewChangesetPB}; +use crate::services::cell::CellDataIsEmpty; use crate::services::group::controller::MoveGroupRowContext; -use flowy_grid_data_model::revision::{CellRevision, RowRevision}; +use crate::services::group::Group; +use flowy_error::FlowyResult; +use flowy_grid_data_model::revision::{CellRevision, FieldRevision, RowRevision}; +use std::sync::Arc; -pub trait GroupAction: Send + Sync { - type CellDataType; +/// Using polymorphism to provides the customs action for different group controller. +/// +/// For example, the `CheckboxGroupController` implements this trait to provide custom behavior. +/// +pub trait GroupControllerCustomActions: Send + Sync { + type CellDataType: CellDataIsEmpty; + /// Returns the a value of the cell, default value is None + /// + /// Determine which group the row is placed in based on the data of the cell. If the cell data + /// is None. The row will be put in to the `No status` group + /// fn default_cell_rev(&self) -> Option { None } - fn use_default_group(&self) -> bool { - true - } + + /// Returns a bool value to determine whether the group should contain this cell or not. fn can_group(&self, content: &str, cell_data: &Self::CellDataType) -> bool; - fn add_row_if_match(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType) -> Vec; - fn remove_row_if_match(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType) -> Vec; - // Move row from one group to another + + /// Adds or removes a row if the cell data match the group filter. + /// It gets called after editing the cell or row + /// + fn add_or_remove_row_in_groups_if_match( + &mut self, + row_rev: &RowRevision, + cell_data: &Self::CellDataType, + ) -> Vec; + + /// Deletes the row from the group + fn delete_row(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType) -> Vec; + + /// Move row from one group to another fn move_row(&mut self, cell_data: &Self::CellDataType, context: MoveGroupRowContext) -> Vec; } + +/// Defines the shared actions any group controller can perform. +pub trait GroupControllerSharedActions: Send + Sync { + /// The field that is used for grouping the rows + fn field_id(&self) -> &str; + + /// Returns number of groups the current field has + fn groups(&self) -> Vec; + + /// Returns the index and the group data with group_id + fn get_group(&self, group_id: &str) -> Option<(usize, Group)>; + + /// Separates the rows into different groups + fn fill_groups(&mut self, row_revs: &[Arc], field_rev: &FieldRevision) -> FlowyResult<()>; + + /// Remove the group with from_group_id and insert it to the index with to_group_id + fn move_group(&mut self, from_group_id: &str, to_group_id: &str) -> FlowyResult<()>; + + /// Insert/Remove the row to the group if the corresponding cell data is changed + fn did_update_group_row( + &mut self, + row_rev: &RowRevision, + field_rev: &FieldRevision, + ) -> FlowyResult>; + + /// Remove the row from the group if the row gets deleted + fn did_delete_delete_row( + &mut self, + row_rev: &RowRevision, + field_rev: &FieldRevision, + ) -> FlowyResult>; + + /// Move the row from one group to another group + fn move_group_row(&mut self, context: MoveGroupRowContext) -> FlowyResult>; + + /// Update the group if the corresponding field is changed + fn did_update_group_field(&mut self, field_rev: &FieldRevision) -> FlowyResult>; +} 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 6fd261fa8b..ab554f195e 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::entities::{GroupPB, GroupViewChangesetPB}; -use crate::services::group::{default_group_configuration, make_no_status_group, GeneratedGroupConfig, Group}; +use crate::services::group::{default_group_configuration, GeneratedGroupContext, Group}; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::revision::{ FieldRevision, FieldTypeRevision, GroupConfigurationContentSerde, GroupConfigurationRevision, GroupRevision, @@ -118,8 +118,16 @@ where } } - /// Iterate mut the groups. The default group will be the last one that get mutated. - pub(crate) fn iter_mut_all_groups(&mut self, mut each: impl FnMut(&mut Group)) { + /// Iterate mut the groups without `No status` group + pub(crate) fn iter_mut_status_groups(&mut self, mut each: impl FnMut(&mut Group)) { + self.groups_map.iter_mut().for_each(|(_, group)| { + if group.id != self.field_rev.id { + each(group); + } + }); + } + + pub(crate) fn iter_mut_groups(&mut self, mut each: impl FnMut(&mut Group)) { self.groups_map.iter_mut().for_each(|(_, group)| { each(group); }); @@ -172,14 +180,19 @@ where /// [GroupConfigurationRevision] as old groups. The old groups and the new groups will be merged /// while keeping the order of the old groups. /// - #[tracing::instrument(level = "trace", skip(self, generated_group_configs), err)] + #[tracing::instrument(level = "trace", skip(self, generated_group_context), err)] pub(crate) fn init_groups( &mut self, - generated_group_configs: Vec, + generated_group_context: GeneratedGroupContext, ) -> FlowyResult> { + let GeneratedGroupContext { + no_status_group, + group_configs, + } = generated_group_context; + let mut new_groups = vec![]; let mut filter_content_map = HashMap::new(); - generated_group_configs.into_iter().for_each(|generate_group| { + group_configs.into_iter().for_each(|generate_group| { filter_content_map.insert(generate_group.group_rev.id.clone(), generate_group.filter_content); new_groups.push(generate_group.group_rev); }); @@ -190,12 +203,9 @@ where old_groups.clear(); } - // When grouping by a new field, there is no `No status` group. So it needs - // to insert a `No status` group at index 0 // The `No status` group index is initialized to 0 - // - if !old_groups.iter().any(|group| group.id == self.field_rev.id) { - old_groups.insert(0, make_no_status_group(&self.field_rev)); + if let Some(no_status_group) = no_status_group { + old_groups.insert(0, no_status_group); } // The `all_group_revs` is the combination of the new groups and old groups @@ -236,9 +246,9 @@ where Some(pos) => { let mut old_group = configuration.groups.get_mut(pos).unwrap(); // Take the old group setting - group_rev.update_with_other(&old_group); + group_rev.update_with_other(old_group); if !is_changed { - is_changed = is_group_changed(group_rev, &old_group); + is_changed = is_group_changed(group_rev, old_group); } // Consider the the name of the `group_rev` as the newest. old_group.name = group_rev.name.clone(); 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 7826ce50c6..899193b5d4 100644 --- a/frontend/rust-lib/flowy-grid/src/services/group/controller.rs +++ b/frontend/rust-lib/flowy-grid/src/services/group/controller.rs @@ -1,6 +1,6 @@ use crate::entities::{GroupChangesetPB, GroupViewChangesetPB, InsertedRowPB, RowPB}; -use crate::services::cell::{decode_any_cell_data, CellBytesParser}; -use crate::services::group::action::GroupAction; +use crate::services::cell::{decode_any_cell_data, CellBytesParser, CellDataIsEmpty}; +use crate::services::group::action::{GroupControllerCustomActions, GroupControllerSharedActions}; use crate::services::group::configuration::GroupContext; use crate::services::group::entities::Group; use flowy_error::FlowyResult; @@ -18,7 +18,7 @@ use std::sync::Arc; /// If the [FieldType] doesn't implement its group controller, then the [DefaultGroupController] will /// be used. /// -pub trait GroupController: GroupControllerActions + Send + Sync { +pub trait GroupController: GroupControllerSharedActions + Send + Sync { fn will_create_row(&mut self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str); fn did_create_row(&mut self, row_pb: &RowPB, group_id: &str); } @@ -29,10 +29,15 @@ pub trait GroupGenerator { type TypeOptionType; fn generate_groups( - field_id: &str, + field_rev: &FieldRevision, group_ctx: &Self::Context, type_option: &Option, - ) -> Vec; + ) -> GeneratedGroupContext; +} + +pub struct GeneratedGroupContext { + pub no_status_group: Option, + pub group_configs: Vec, } pub struct GeneratedGroupConfig { @@ -47,45 +52,6 @@ pub struct MoveGroupRowContext<'a> { pub to_group_id: &'a str, pub to_row_id: Option, } - -/// Defines the shared actions each group controller can perform. -pub trait GroupControllerActions: Send + Sync { - /// The field that is used for grouping the rows - fn field_id(&self) -> &str; - - /// Returns number of groups the current field has - fn groups(&self) -> Vec; - - /// Returns the index and the group data with group_id - fn get_group(&self, group_id: &str) -> Option<(usize, Group)>; - - /// Separates the rows into different groups - fn fill_groups(&mut self, row_revs: &[Arc], field_rev: &FieldRevision) -> FlowyResult<()>; - - /// Remove the group with from_group_id and insert it to the index with to_group_id - fn move_group(&mut self, from_group_id: &str, to_group_id: &str) -> FlowyResult<()>; - - /// Insert the row to the group if the corresponding cell data is changed - fn did_update_group_row( - &mut self, - row_rev: &RowRevision, - field_rev: &FieldRevision, - ) -> FlowyResult>; - - /// Remove the row from the group if the corresponding cell data is changed - fn did_delete_delete_row( - &mut self, - row_rev: &RowRevision, - field_rev: &FieldRevision, - ) -> FlowyResult>; - - /// Move the row from one group to another group - fn move_group_row(&mut self, context: MoveGroupRowContext) -> FlowyResult>; - - /// Update the group if the corresponding field is changed - fn did_update_group_field(&mut self, field_rev: &FieldRevision) -> FlowyResult>; -} - /// C: represents the group configuration that impl [GroupConfigurationSerde] /// T: the type-option data deserializer that impl [TypeOptionDataDeserializer] /// G: the group generator, [GroupGenerator] @@ -106,8 +72,8 @@ where { pub async fn new(field_rev: &Arc, mut configuration: GroupContext) -> FlowyResult { let type_option = field_rev.get_type_option::(field_rev.ty); - let groups = G::generate_groups(&field_rev.id, &configuration, &type_option); - let _ = configuration.init_groups(groups)?; + let generated_group_context = G::generate_groups(field_rev, &configuration, &type_option); + let _ = configuration.init_groups(generated_group_context)?; Ok(Self { field_id: field_rev.id.clone(), @@ -186,30 +152,21 @@ where } } -impl GroupControllerActions for GenericGroupController +impl GroupControllerSharedActions for GenericGroupController where P: CellBytesParser, C: GroupConfigurationContentSerde, T: TypeOptionDataDeserializer, G: GroupGenerator, TypeOptionType = T>, - Self: GroupAction, + Self: GroupControllerCustomActions, { fn field_id(&self) -> &str { &self.field_id } fn groups(&self) -> Vec { - if self.use_default_group() { - self.group_ctx.groups().into_iter().cloned().collect() - } else { - self.group_ctx - .groups() - .into_iter() - .filter(|group| group.id != self.field_id) - .cloned() - .collect::>() - } + self.group_ctx.groups().into_iter().cloned().collect() } fn get_group(&self, group_id: &str) -> Option<(usize, Group)> { @@ -269,17 +226,14 @@ where if let Some(cell_rev) = row_rev.cells.get(&self.field_id) { let cell_bytes = decode_any_cell_data(cell_rev.data.clone(), field_rev).1; let cell_data = cell_bytes.parser::

()?; - let mut changesets = self.add_row_if_match(row_rev, &cell_data); + let mut changesets = self.add_or_remove_row_in_groups_if_match(row_rev, &cell_data); - if self.use_default_group() { - if let Some(default_group_changeset) = self.update_default_group(row_rev, &changesets) { - tracing::trace!("default_group_changeset: {}", default_group_changeset); - if !default_group_changeset.is_empty() { - changesets.push(default_group_changeset); - } + if let Some(default_group_changeset) = self.update_default_group(row_rev, &changesets) { + tracing::trace!("default_group_changeset: {}", default_group_changeset); + if !default_group_changeset.is_empty() { + changesets.push(default_group_changeset); } } - Ok(changesets) } else { Ok(vec![]) @@ -291,18 +245,30 @@ where row_rev: &RowRevision, field_rev: &FieldRevision, ) -> FlowyResult> { - // if the cell_rev is none, then the row must be crated from the default group. + // if the cell_rev is none, then the row must in the default group. if let Some(cell_rev) = row_rev.cells.get(&self.field_id) { let cell_bytes = decode_any_cell_data(cell_rev.data.clone(), field_rev).1; let cell_data = cell_bytes.parser::

()?; - Ok(self.remove_row_if_match(row_rev, &cell_data)) - } else if let Some(group) = self.group_ctx.get_no_status_group() { - Ok(vec![GroupChangesetPB::delete( - group.id.clone(), - vec![row_rev.id.clone()], - )]) - } else { - Ok(vec![]) + if !cell_data.is_empty() { + tracing::error!("did_delete_delete_row {:?}", cell_rev.data); + return Ok(self.delete_row(row_rev, &cell_data)); + } + } + + match self.group_ctx.get_no_status_group() { + None => { + tracing::error!("Unexpected None value. It should have the no status group"); + Ok(vec![]) + } + Some(no_status_group) => { + if !no_status_group.contains_row(&row_rev.id) { + tracing::error!("The row: {} should be in the no status group", row_rev.id); + } + Ok(vec![GroupChangesetPB::delete( + no_status_group.id.clone(), + vec![row_rev.id.clone()], + )]) + } } } diff --git a/frontend/rust-lib/flowy-grid/src/services/group/controller_impls/checkbox_controller.rs b/frontend/rust-lib/flowy-grid/src/services/group/controller_impls/checkbox_controller.rs index 7d41ccefc0..3187b216f4 100644 --- a/frontend/rust-lib/flowy-grid/src/services/group/controller_impls/checkbox_controller.rs +++ b/frontend/rust-lib/flowy-grid/src/services/group/controller_impls/checkbox_controller.rs @@ -1,13 +1,13 @@ use crate::entities::{GroupChangesetPB, InsertedRowPB, RowPB}; use crate::services::field::{CheckboxCellData, CheckboxCellDataParser, CheckboxTypeOptionPB, CHECK, UNCHECK}; -use crate::services::group::action::GroupAction; +use crate::services::group::action::GroupControllerCustomActions; use crate::services::group::configuration::GroupContext; use crate::services::group::controller::{ GenericGroupController, GroupController, GroupGenerator, MoveGroupRowContext, }; use crate::services::cell::insert_checkbox_cell; -use crate::services::group::{move_group_row, GeneratedGroupConfig}; +use crate::services::group::{move_group_row, GeneratedGroupConfig, GeneratedGroupContext}; use flowy_grid_data_model::revision::{ CellRevision, CheckboxGroupConfigurationRevision, FieldRevision, GroupRevision, RowRevision, }; @@ -21,16 +21,12 @@ pub type CheckboxGroupController = GenericGroupController< pub type CheckboxGroupContext = GroupContext; -impl GroupAction for CheckboxGroupController { +impl GroupControllerCustomActions for CheckboxGroupController { type CellDataType = CheckboxCellData; fn default_cell_rev(&self) -> Option { Some(CellRevision::new(UNCHECK.to_string())) } - fn use_default_group(&self) -> bool { - false - } - fn can_group(&self, content: &str, cell_data: &Self::CellDataType) -> bool { if cell_data.is_check() { content == CHECK @@ -39,9 +35,13 @@ impl GroupAction for CheckboxGroupController { } } - fn add_row_if_match(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType) -> Vec { + fn add_or_remove_row_in_groups_if_match( + &mut self, + row_rev: &RowRevision, + cell_data: &Self::CellDataType, + ) -> Vec { let mut changesets = vec![]; - self.group_ctx.iter_mut_all_groups(|group| { + self.group_ctx.iter_mut_status_groups(|group| { let mut changeset = GroupChangesetPB::new(group.id.clone()); let is_not_contained = !group.contains_row(&row_rev.id); if group.id == CHECK { @@ -81,9 +81,9 @@ impl GroupAction for CheckboxGroupController { changesets } - fn remove_row_if_match(&mut self, row_rev: &RowRevision, _cell_data: &Self::CellDataType) -> Vec { + fn delete_row(&mut self, row_rev: &RowRevision, _cell_data: &Self::CellDataType) -> Vec { let mut changesets = vec![]; - self.group_ctx.iter_mut_all_groups(|group| { + self.group_ctx.iter_mut_groups(|group| { let mut changeset = GroupChangesetPB::new(group.id.clone()); if group.contains_row(&row_rev.id) { changeset.deleted_rows.push(row_rev.id.clone()); @@ -99,7 +99,7 @@ impl GroupAction for CheckboxGroupController { fn move_row(&mut self, _cell_data: &Self::CellDataType, mut context: MoveGroupRowContext) -> Vec { let mut group_changeset = vec![]; - self.group_ctx.iter_mut_all_groups(|group| { + self.group_ctx.iter_mut_groups(|group| { if let Some(changeset) = move_group_row(group, &mut context) { group_changeset.push(changeset); } @@ -133,10 +133,10 @@ impl GroupGenerator for CheckboxGroupGenerator { type TypeOptionType = CheckboxTypeOptionPB; fn generate_groups( - _field_id: &str, + _field_rev: &FieldRevision, _group_ctx: &Self::Context, _type_option: &Option, - ) -> Vec { + ) -> GeneratedGroupContext { let check_group = GeneratedGroupConfig { group_rev: GroupRevision::new(CHECK.to_string(), "".to_string()), filter_content: CHECK.to_string(), @@ -146,6 +146,10 @@ impl GroupGenerator for CheckboxGroupGenerator { group_rev: GroupRevision::new(UNCHECK.to_string(), "".to_string()), filter_content: UNCHECK.to_string(), }; - vec![check_group, uncheck_group] + + GeneratedGroupContext { + no_status_group: None, + group_configs: vec![check_group, uncheck_group], + } } } diff --git a/frontend/rust-lib/flowy-grid/src/services/group/controller_impls/default_controller.rs b/frontend/rust-lib/flowy-grid/src/services/group/controller_impls/default_controller.rs index 02bd1a6fb8..d262d625c1 100644 --- a/frontend/rust-lib/flowy-grid/src/services/group/controller_impls/default_controller.rs +++ b/frontend/rust-lib/flowy-grid/src/services/group/controller_impls/default_controller.rs @@ -1,5 +1,6 @@ use crate::entities::{GroupChangesetPB, GroupViewChangesetPB, RowPB}; -use crate::services::group::{Group, GroupController, GroupControllerActions, MoveGroupRowContext}; +use crate::services::group::action::GroupControllerSharedActions; +use crate::services::group::{Group, GroupController, MoveGroupRowContext}; use flowy_error::FlowyResult; use flowy_grid_data_model::revision::{FieldRevision, RowRevision}; use std::sync::Arc; @@ -30,7 +31,7 @@ impl DefaultGroupController { } } -impl GroupControllerActions for DefaultGroupController { +impl GroupControllerSharedActions for DefaultGroupController { fn field_id(&self) -> &str { &self.field_id } 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 502c0be350..58bb4a23d0 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 @@ -1,14 +1,14 @@ use crate::entities::{GroupChangesetPB, RowPB}; use crate::services::cell::insert_select_option_cell; use crate::services::field::{MultiSelectTypeOptionPB, SelectOptionCellDataPB, SelectOptionCellDataParser}; -use crate::services::group::action::GroupAction; +use crate::services::group::action::GroupControllerCustomActions; use crate::services::group::controller::{ GenericGroupController, GroupController, GroupGenerator, MoveGroupRowContext, }; use crate::services::group::controller_impls::select_option_controller::util::*; -use crate::services::group::GeneratedGroupConfig; +use crate::services::group::{make_no_status_group, GeneratedGroupContext}; use flowy_grid_data_model::revision::{FieldRevision, RowRevision, SelectOptionGroupConfigurationRevision}; // MultiSelect @@ -19,26 +19,30 @@ pub type MultiSelectGroupController = GenericGroupController< SelectOptionCellDataParser, >; -impl GroupAction for MultiSelectGroupController { +impl GroupControllerCustomActions for MultiSelectGroupController { type CellDataType = SelectOptionCellDataPB; fn can_group(&self, content: &str, cell_data: &SelectOptionCellDataPB) -> bool { cell_data.select_options.iter().any(|option| option.id == content) } - fn add_row_if_match(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType) -> Vec { + fn add_or_remove_row_in_groups_if_match( + &mut self, + row_rev: &RowRevision, + cell_data: &Self::CellDataType, + ) -> Vec { let mut changesets = vec![]; - self.group_ctx.iter_mut_all_groups(|group| { - if let Some(changeset) = add_select_option_row(group, cell_data, row_rev) { + self.group_ctx.iter_mut_status_groups(|group| { + if let Some(changeset) = add_or_remove_select_option_row(group, cell_data, row_rev) { changesets.push(changeset); } }); changesets } - fn remove_row_if_match(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType) -> Vec { + fn delete_row(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType) -> Vec { let mut changesets = vec![]; - self.group_ctx.iter_mut_all_groups(|group| { + self.group_ctx.iter_mut_status_groups(|group| { if let Some(changeset) = remove_select_option_row(group, cell_data, row_rev) { changesets.push(changeset); } @@ -48,7 +52,7 @@ impl GroupAction for MultiSelectGroupController { fn move_row(&mut self, _cell_data: &Self::CellDataType, mut context: MoveGroupRowContext) -> Vec { let mut group_changeset = vec![]; - self.group_ctx.iter_mut_all_groups(|group| { + self.group_ctx.iter_mut_groups(|group| { if let Some(changeset) = move_group_row(group, &mut context) { group_changeset.push(changeset); } @@ -79,14 +83,20 @@ pub struct MultiSelectGroupGenerator(); impl GroupGenerator for MultiSelectGroupGenerator { type Context = SelectOptionGroupContext; type TypeOptionType = MultiSelectTypeOptionPB; + fn generate_groups( - field_id: &str, + field_rev: &FieldRevision, group_ctx: &Self::Context, type_option: &Option, - ) -> Vec { - match type_option { + ) -> GeneratedGroupContext { + let group_configs = match type_option { None => vec![], - Some(type_option) => generate_select_option_groups(field_id, group_ctx, &type_option.options), + Some(type_option) => generate_select_option_groups(&field_rev.id, group_ctx, &type_option.options), + }; + + GeneratedGroupContext { + no_status_group: Some(make_no_status_group(field_rev)), + group_configs, } } } diff --git a/frontend/rust-lib/flowy-grid/src/services/group/controller_impls/select_option_controller/single_select_controller.rs b/frontend/rust-lib/flowy-grid/src/services/group/controller_impls/select_option_controller/single_select_controller.rs index b7c7f5fd3a..203e4f1675 100644 --- a/frontend/rust-lib/flowy-grid/src/services/group/controller_impls/select_option_controller/single_select_controller.rs +++ b/frontend/rust-lib/flowy-grid/src/services/group/controller_impls/select_option_controller/single_select_controller.rs @@ -1,7 +1,7 @@ use crate::entities::{GroupChangesetPB, RowPB}; use crate::services::cell::insert_select_option_cell; use crate::services::field::{SelectOptionCellDataPB, SelectOptionCellDataParser, SingleSelectTypeOptionPB}; -use crate::services::group::action::GroupAction; +use crate::services::group::action::GroupControllerCustomActions; use crate::services::group::controller::{ GenericGroupController, GroupController, GroupGenerator, MoveGroupRowContext, @@ -9,7 +9,7 @@ use crate::services::group::controller::{ use crate::services::group::controller_impls::select_option_controller::util::*; use crate::services::group::entities::Group; -use crate::services::group::GeneratedGroupConfig; +use crate::services::group::{make_no_status_group, GeneratedGroupContext}; use flowy_grid_data_model::revision::{FieldRevision, RowRevision, SelectOptionGroupConfigurationRevision}; // SingleSelect @@ -20,25 +20,29 @@ pub type SingleSelectGroupController = GenericGroupController< SelectOptionCellDataParser, >; -impl GroupAction for SingleSelectGroupController { +impl GroupControllerCustomActions for SingleSelectGroupController { type CellDataType = SelectOptionCellDataPB; fn can_group(&self, content: &str, cell_data: &SelectOptionCellDataPB) -> bool { cell_data.select_options.iter().any(|option| option.id == content) } - fn add_row_if_match(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType) -> Vec { + fn add_or_remove_row_in_groups_if_match( + &mut self, + row_rev: &RowRevision, + cell_data: &Self::CellDataType, + ) -> Vec { let mut changesets = vec![]; - self.group_ctx.iter_mut_all_groups(|group| { - if let Some(changeset) = add_select_option_row(group, cell_data, row_rev) { + self.group_ctx.iter_mut_status_groups(|group| { + if let Some(changeset) = add_or_remove_select_option_row(group, cell_data, row_rev) { changesets.push(changeset); } }); changesets } - fn remove_row_if_match(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType) -> Vec { + fn delete_row(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType) -> Vec { let mut changesets = vec![]; - self.group_ctx.iter_mut_all_groups(|group| { + self.group_ctx.iter_mut_status_groups(|group| { if let Some(changeset) = remove_select_option_row(group, cell_data, row_rev) { changesets.push(changeset); } @@ -48,7 +52,7 @@ impl GroupAction for SingleSelectGroupController { fn move_row(&mut self, _cell_data: &Self::CellDataType, mut context: MoveGroupRowContext) -> Vec { let mut group_changeset = vec![]; - self.group_ctx.iter_mut_all_groups(|group| { + self.group_ctx.iter_mut_groups(|group| { if let Some(changeset) = move_group_row(group, &mut context) { group_changeset.push(changeset); } @@ -80,13 +84,18 @@ impl GroupGenerator for SingleSelectGroupGenerator { type Context = SelectOptionGroupContext; type TypeOptionType = SingleSelectTypeOptionPB; fn generate_groups( - field_id: &str, + field_rev: &FieldRevision, group_ctx: &Self::Context, type_option: &Option, - ) -> Vec { - match type_option { + ) -> GeneratedGroupContext { + let group_configs = match type_option { None => vec![], - Some(type_option) => generate_select_option_groups(field_id, group_ctx, &type_option.options), + Some(type_option) => generate_select_option_groups(&field_rev.id, group_ctx, &type_option.options), + }; + + GeneratedGroupContext { + no_status_group: Some(make_no_status_group(field_rev)), + group_configs, } } } diff --git a/frontend/rust-lib/flowy-grid/src/services/group/controller_impls/select_option_controller/util.rs b/frontend/rust-lib/flowy-grid/src/services/group/controller_impls/select_option_controller/util.rs index 71fbfb410e..29bbd8f0f9 100644 --- a/frontend/rust-lib/flowy-grid/src/services/group/controller_impls/select_option_controller/util.rs +++ b/frontend/rust-lib/flowy-grid/src/services/group/controller_impls/select_option_controller/util.rs @@ -10,7 +10,7 @@ use flowy_grid_data_model::revision::{ pub type SelectOptionGroupContext = GroupContext; -pub fn add_select_option_row( +pub fn add_or_remove_select_option_row( group: &mut Group, cell_data: &SelectOptionCellDataPB, row_rev: &RowRevision, diff --git a/frontend/rust-lib/flowy-grid/src/services/group/group_util.rs b/frontend/rust-lib/flowy-grid/src/services/group/group_util.rs index 5c6180c859..c8116d6897 100644 --- a/frontend/rust-lib/flowy-grid/src/services/group/group_util.rs +++ b/frontend/rust-lib/flowy-grid/src/services/group/group_util.rs @@ -97,7 +97,7 @@ pub fn default_group_configuration(field_rev: &FieldRevision) -> GroupConfigurat let field_id = field_rev.id.clone(); let field_type_rev = field_rev.ty; let field_type: FieldType = field_rev.ty.into(); - let mut group_configuration_rev = match field_type { + match field_type { FieldType::RichText => { GroupConfigurationRevision::new(field_id, field_type_rev, TextGroupConfigurationRevision::default()) .unwrap() @@ -130,11 +130,7 @@ pub fn default_group_configuration(field_rev: &FieldRevision) -> GroupConfigurat FieldType::URL => { GroupConfigurationRevision::new(field_id, field_type_rev, UrlGroupConfigurationRevision::default()).unwrap() } - }; - - // Append the no `status` group - group_configuration_rev.groups.push(make_no_status_group(field_rev)); - group_configuration_rev + } } pub fn make_no_status_group(field_rev: &FieldRevision) -> GroupRevision { diff --git a/frontend/rust-lib/flowy-net/src/http_server/document.rs b/frontend/rust-lib/flowy-net/src/http_server/document.rs index b286e5c102..1a6b66ca59 100644 --- a/frontend/rust-lib/flowy-net/src/http_server/document.rs +++ b/frontend/rust-lib/flowy-net/src/http_server/document.rs @@ -42,7 +42,7 @@ impl TextEditorCloudService for BlockHttpCloudService { pub async fn create_document_request(token: &str, params: CreateTextBlockParams, url: &str) -> Result<(), FlowyError> { let _ = request_builder() - .post(&url.to_owned()) + .post(url) .header(HEADER_TOKEN, token) .protobuf(params)? .send() @@ -56,7 +56,7 @@ pub async fn read_document_request( url: &str, ) -> Result, FlowyError> { let doc = request_builder() - .get(&url.to_owned()) + .get(url) .header(HEADER_TOKEN, token) .protobuf(params)? .option_response() @@ -67,7 +67,7 @@ pub async fn read_document_request( pub async fn reset_doc_request(token: &str, params: ResetTextBlockParams, url: &str) -> Result<(), FlowyError> { let _ = request_builder() - .patch(&url.to_owned()) + .patch(url) .header(HEADER_TOKEN, token) .protobuf(params)? .send() diff --git a/frontend/rust-lib/flowy-net/src/http_server/user.rs b/frontend/rust-lib/flowy-net/src/http_server/user.rs index 7768c91bb6..406de3d1bc 100644 --- a/frontend/rust-lib/flowy-net/src/http_server/user.rs +++ b/frontend/rust-lib/flowy-net/src/http_server/user.rs @@ -66,35 +66,23 @@ impl UserCloudService for UserHttpCloudService { } pub async fn user_sign_up_request(params: SignUpParams, url: &str) -> Result { - let response = request_builder() - .post(&url.to_owned()) - .protobuf(params)? - .response() - .await?; + let response = request_builder().post(url).protobuf(params)?.response().await?; Ok(response) } pub async fn user_sign_in_request(params: SignInParams, url: &str) -> Result { - let response = request_builder() - .post(&url.to_owned()) - .protobuf(params)? - .response() - .await?; + let response = request_builder().post(url).protobuf(params)?.response().await?; Ok(response) } pub async fn user_sign_out_request(token: &str, url: &str) -> Result<(), ServerError> { - let _ = request_builder() - .delete(&url.to_owned()) - .header(HEADER_TOKEN, token) - .send() - .await?; + let _ = request_builder().delete(url).header(HEADER_TOKEN, token).send().await?; Ok(()) } pub async fn get_user_profile_request(token: &str, url: &str) -> Result { let user_profile = request_builder() - .get(&url.to_owned()) + .get(url) .header(HEADER_TOKEN, token) .response() .await?; @@ -107,7 +95,7 @@ pub async fn update_user_profile_request( url: &str, ) -> Result<(), ServerError> { let _ = request_builder() - .patch(&url.to_owned()) + .patch(url) .header(HEADER_TOKEN, token) .protobuf(params)? .send() diff --git a/frontend/rust-lib/flowy-revision/src/rev_manager.rs b/frontend/rust-lib/flowy-revision/src/rev_manager.rs index 73592cad85..1776956d1c 100644 --- a/frontend/rust-lib/flowy-revision/src/rev_manager.rs +++ b/frontend/rust-lib/flowy-revision/src/rev_manager.rs @@ -164,7 +164,7 @@ impl RevisionManager { } pub async fn next_sync_revision(&self) -> FlowyResult> { - Ok(self.rev_persistence.next_sync_revision().await?) + self.rev_persistence.next_sync_revision().await } pub async fn get_revision(&self, rev_id: i64) -> Option { diff --git a/frontend/rust-lib/flowy-revision/src/rev_persistence.rs b/frontend/rust-lib/flowy-revision/src/rev_persistence.rs index 2124598400..9360182eba 100644 --- a/frontend/rust-lib/flowy-revision/src/rev_persistence.rs +++ b/frontend/rust-lib/flowy-revision/src/rev_persistence.rs @@ -130,7 +130,6 @@ impl RevisionPersistence { #[tracing::instrument(level = "trace", skip(self, revisions), err)] pub(crate) async fn reset(&self, revisions: Vec) -> FlowyResult<()> { let records = revisions - .to_vec() .into_iter() .map(|revision| RevisionRecord { revision, diff --git a/frontend/rust-lib/lib-log/src/layer.rs b/frontend/rust-lib/lib-log/src/layer.rs index 14efa4c90e..b2eaabcc22 100644 --- a/frontend/rust-lib/lib-log/src/layer.rs +++ b/frontend/rust-lib/lib-log/src/layer.rs @@ -114,11 +114,10 @@ fn format_event_message tracing_subscriber::registry::Lo let mut message = event_visitor .values() .get("message") - .map(|v| match v { + .and_then(|v| match v { Value::String(s) => Some(s.as_str()), _ => None, }) - .flatten() .unwrap_or_else(|| event.metadata().target()) .to_owned(); diff --git a/shared-lib/flowy-grid-data-model/src/revision/grid_block.rs b/shared-lib/flowy-grid-data-model/src/revision/grid_block.rs index ba113810f6..57bcf1b017 100644 --- a/shared-lib/flowy-grid-data-model/src/revision/grid_block.rs +++ b/shared-lib/flowy-grid-data-model/src/revision/grid_block.rs @@ -73,4 +73,8 @@ impl CellRevision { pub fn new(data: String) -> Self { Self { data } } + + pub fn is_empty(&self) -> bool { + self.data.is_empty() + } }