فهرست منبع

chore: fix some bugs

appflowy 2 سال پیش
والد
کامیت
0ecb15cfa3

+ 6 - 0
frontend/rust-lib/flowy-grid/src/entities/block_entities.rs

@@ -112,6 +112,12 @@ pub struct InsertedRowPB {
     pub index: Option<i32>,
 }
 
+impl InsertedRowPB {
+    pub fn new(row: RowPB) -> Self {
+        Self { row, index: None }
+    }
+}
+
 impl std::convert::From<RowPB> for InsertedRowPB {
     fn from(row: RowPB) -> Self {
         Self { row, index: None }

+ 3 - 0
frontend/rust-lib/flowy-grid/src/entities/group_entities/group_changeset.rs

@@ -17,6 +17,9 @@ pub struct GroupRowsChangesetPB {
 }
 
 impl GroupRowsChangesetPB {
+    pub fn is_empty(&self) -> bool {
+        self.inserted_rows.is_empty() && self.deleted_rows.is_empty() && self.updated_rows.is_empty()
+    }
     pub fn insert(group_id: String, inserted_rows: Vec<InsertedRowPB>) -> Self {
         Self {
             group_id,

+ 4 - 2
frontend/rust-lib/flowy-grid/src/services/grid_editor.rs

@@ -3,7 +3,7 @@ use crate::entities::GridCellIdParams;
 use crate::entities::*;
 use crate::manager::{GridTaskSchedulerRwLock, GridUser};
 use crate::services::block_manager::GridBlockManager;
-use crate::services::block_manager_trait_impl::*;
+
 use crate::services::cell::{apply_cell_data_changeset, decode_any_cell_data, CellBytes};
 use crate::services::field::{default_type_option_builder_from_type, type_option_builder_from_bytes, FieldBuilder};
 use crate::services::filter::GridFilterService;
@@ -405,7 +405,7 @@ impl GridRevisionEditor {
                 content = Some(apply_cell_data_changeset(content.unwrap(), cell_rev, field_rev)?);
                 let cell_changeset = CellChangesetPB {
                     grid_id,
-                    row_id,
+                    row_id: row_id.clone(),
                     field_id,
                     content,
                 };
@@ -413,6 +413,8 @@ impl GridRevisionEditor {
                     .block_manager
                     .update_cell(cell_changeset, make_row_from_row_rev)
                     .await?;
+
+                self.view_manager.did_update_row(&row_id).await;
                 Ok(())
             }
         }

+ 12 - 7
frontend/rust-lib/flowy-grid/src/services/grid_view_editor.rs

@@ -5,7 +5,7 @@ use crate::entities::{
 };
 use crate::services::grid_editor_task::GridServiceTaskScheduler;
 use crate::services::grid_view_manager::{GridViewFieldDelegate, GridViewRowDelegate};
-use crate::services::group::{default_group_configuration, Group, GroupConfigurationDelegate, GroupService};
+use crate::services::group::{default_group_configuration, GroupConfigurationDelegate, GroupService};
 use crate::services::setting::make_grid_setting;
 use flowy_error::{FlowyError, FlowyResult};
 use flowy_grid_data_model::revision::{FieldRevision, GroupConfigurationRevision, RowRevision};
@@ -105,11 +105,16 @@ impl GridViewRevisionEditor {
         }
     }
 
-    pub(crate) async fn did_update_row(&self, row_rev: Arc<RowRevision>) {
-        match self.group_id_of_row(&row_rev.id).await {
-            None => {}
-            Some(group_id) => {
-                // self.get_mut_group(&group_id, |group| Ok(()));
+    pub(crate) async fn did_update_row(&self, row_rev: &RowRevision) {
+        if let Some(changesets) = self
+            .group_service
+            .write()
+            .await
+            .did_update_row(row_rev, |field_id| self.field_delegate.get_field_rev(&field_id))
+            .await
+        {
+            for changeset in changesets {
+                self.notify_did_update_group(changeset).await;
             }
         }
     }
@@ -117,7 +122,7 @@ impl GridViewRevisionEditor {
     async fn group_id_of_row(&self, row_id: &str) -> Option<String> {
         let read_guard = &self.group_service.read().await.groups;
         for group in read_guard.iter() {
-            if group.rows.iter().any(|row| row.id == row_id) {
+            if group.contains_row(row_id) {
                 return Some(group.id.clone());
             }
         }

+ 13 - 5
frontend/rust-lib/flowy-grid/src/services/grid_view_manager.rs

@@ -2,7 +2,7 @@ use crate::entities::{
     CreateRowParams, GridFilterConfiguration, GridLayout, GridSettingPB, MoveRowParams, RepeatedGridGroupPB, RowPB,
 };
 use crate::manager::GridUser;
-use crate::services::block_manager::GridBlockManager;
+
 use crate::services::grid_editor_task::GridServiceTaskScheduler;
 use crate::services::grid_view_editor::GridViewRevisionEditor;
 use bytes::Bytes;
@@ -11,13 +11,12 @@ use flowy_error::FlowyResult;
 use flowy_grid_data_model::revision::{FieldRevision, RowRevision};
 use flowy_revision::disk::SQLiteGridViewRevisionPersistence;
 use flowy_revision::{RevisionCompactor, RevisionManager, RevisionPersistence, SQLiteRevisionSnapshotPersistence};
-use flowy_sync::client_grid::GridRevisionPad;
+
 use flowy_sync::entities::grid::GridSettingChangesetParams;
 use flowy_sync::entities::revision::Revision;
 use flowy_sync::util::make_text_delta_from_revisions;
-use lib_infra::future::{wrap_future, AFFuture};
+use lib_infra::future::AFFuture;
 use std::sync::Arc;
-use tokio::sync::RwLock;
 
 type ViewId = String;
 
@@ -74,7 +73,16 @@ impl GridViewManager {
     }
 
     pub(crate) async fn did_update_row(&self, row_id: &str) {
-        let row = self.row_delegate.gv_get_row_rev(row_id).await;
+        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_row(&row_rev).await;
+                }
+            }
+        }
     }
 
     pub(crate) async fn did_create_row(&self, row_pb: &RowPB, params: &CreateRowParams) {

+ 15 - 32
frontend/rust-lib/flowy-grid/src/services/group/group_generator/checkbox_group.rs

@@ -1,13 +1,16 @@
-use crate::entities::CheckboxGroupConfigurationPB;
-use flowy_error::FlowyResult;
+use crate::entities::{CheckboxGroupConfigurationPB, GroupRowsChangesetPB};
+
 use flowy_grid_data_model::revision::{FieldRevision, RowRevision};
-use std::sync::Arc;
 
 use crate::services::field::{CheckboxCellData, CheckboxCellDataParser, CheckboxTypeOptionPB, CHECK, UNCHECK};
-use crate::services::group::{Group, GroupActionHandler, GroupController, GroupGenerator, Groupable};
+use crate::services::group::{GenericGroupController, Group, GroupController, GroupGenerator, Groupable};
 
-pub type CheckboxGroupController =
-    GroupController<CheckboxGroupConfigurationPB, CheckboxTypeOptionPB, CheckboxGroupGenerator, CheckboxCellDataParser>;
+pub type CheckboxGroupController = GenericGroupController<
+    CheckboxGroupConfigurationPB,
+    CheckboxTypeOptionPB,
+    CheckboxGroupGenerator,
+    CheckboxCellDataParser,
+>;
 
 impl Groupable for CheckboxGroupController {
     type CellDataType = CheckboxCellData;
@@ -15,21 +18,13 @@ impl Groupable for CheckboxGroupController {
     fn can_group(&self, _content: &str, _cell_data: &Self::CellDataType) -> bool {
         false
     }
-}
 
-impl GroupActionHandler for CheckboxGroupController {
-    fn field_id(&self) -> &str {
-        &self.field_id
-    }
-
-    fn build_groups(&self) -> Vec<Group> {
-        self.make_groups()
-    }
-
-    fn group_rows(&mut self, row_revs: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<()> {
-        self.handle_rows(row_revs, field_rev)
+    fn group_row(&mut self, _row_rev: &RowRevision, _cell_data: &Self::CellDataType) -> Vec<GroupRowsChangesetPB> {
+        todo!()
     }
+}
 
+impl GroupController for CheckboxGroupController {
     fn fill_row(&self, _row_rev: &mut RowRevision, _field_rev: &FieldRevision, _group_id: &str) {
         todo!()
     }
@@ -44,20 +39,8 @@ impl GroupGenerator for CheckboxGroupGenerator {
         _configuration: &Option<Self::ConfigurationType>,
         _type_option: &Option<Self::TypeOptionType>,
     ) -> Vec<Group> {
-        let check_group = Group {
-            id: "true".to_string(),
-            desc: "".to_string(),
-            rows: vec![],
-            content: CHECK.to_string(),
-        };
-
-        let uncheck_group = Group {
-            id: "false".to_string(),
-            desc: "".to_string(),
-            rows: vec![],
-            content: UNCHECK.to_string(),
-        };
-
+        let check_group = Group::new("true".to_string(), "".to_string(), CHECK.to_string());
+        let uncheck_group = Group::new("false".to_string(), "".to_string(), UNCHECK.to_string());
         vec![check_group, uncheck_group]
     }
 }

+ 129 - 34
frontend/rust-lib/flowy-grid/src/services/group/group_generator/generator.rs

@@ -1,13 +1,11 @@
-use crate::entities::{GroupPB, RowPB};
+use crate::entities::{GroupPB, GroupRowsChangesetPB, RowPB};
 use crate::services::cell::{decode_any_cell_data, CellBytesParser};
 use bytes::Bytes;
 use flowy_error::FlowyResult;
 use flowy_grid_data_model::revision::{
     FieldRevision, GroupConfigurationRevision, RowRevision, TypeOptionDataDeserializer,
 };
-
 use indexmap::IndexMap;
-
 use std::marker::PhantomData;
 use std::sync::Arc;
 
@@ -21,30 +19,35 @@ pub trait GroupGenerator {
     ) -> Vec<Group>;
 }
 
-pub trait Groupable {
+pub trait Groupable: Send + Sync {
     type CellDataType;
     fn can_group(&self, content: &str, cell_data: &Self::CellDataType) -> bool;
+    fn group_row(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType) -> Vec<GroupRowsChangesetPB>;
+}
+
+pub trait GroupController: GroupControllerSharedAction + Send + Sync {
+    fn fill_row(&self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str);
 }
 
-pub trait GroupActionHandler: 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<Group>;
     fn group_rows(&mut self, row_revs: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<()>;
-    fn fill_row(&self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str);
-}
-
-pub trait GroupActionHandler2: Send + Sync {
-    fn create_card(&self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str);
+    fn did_update_row(
+        &mut self,
+        row_rev: &RowRevision,
+        field_rev: &FieldRevision,
+    ) -> FlowyResult<Vec<GroupRowsChangesetPB>>;
 }
 
 const DEFAULT_GROUP_ID: &str = "default_group";
 
 /// C: represents the group configuration structure
 /// T: the type option data deserializer that impl [TypeOptionDataDeserializer]
-/// G: the group container generator
+/// G: the group generator, [GroupGenerator]
 /// P: the parser that impl [CellBytesParser] for the CellBytes
-pub struct GroupController<C, T, G, P> {
+pub struct GenericGroupController<C, T, G, P> {
     pub field_id: String,
     pub groups_map: IndexMap<String, Group>,
     default_group: Group,
@@ -58,7 +61,7 @@ pub struct GroupController<C, T, G, P> {
 pub struct Group {
     pub id: String,
     pub desc: String,
-    pub rows: Vec<RowPB>,
+    rows: Vec<RowPB>,
     pub content: String,
 }
 
@@ -72,7 +75,40 @@ impl std::convert::From<Group> for GroupPB {
     }
 }
 
-impl<C, T, G, P> GroupController<C, T, G, P>
+impl Group {
+    pub fn new(id: String, desc: String, content: String) -> Self {
+        Self {
+            id,
+            desc,
+            rows: vec![],
+            content,
+        }
+    }
+
+    pub fn contains_row(&self, row_id: &str) -> bool {
+        self.rows.iter().any(|row| row.id == row_id)
+    }
+
+    pub fn remove_row(&mut self, row_id: &str) {
+        match self.rows.iter().position(|row| row.id == row_id) {
+            None => {}
+            Some(pos) => {
+                self.rows.remove(pos);
+            }
+        }
+    }
+
+    pub fn add_row(&mut self, row_pb: RowPB) {
+        match self.rows.iter().find(|row| row.id == row_pb.id) {
+            None => {
+                self.rows.push(row_pb);
+            }
+            Some(_) => {}
+        }
+    }
+}
+
+impl<C, T, G, P> GenericGroupController<C, T, G, P>
 where
     C: TryFrom<Bytes, Error = protobuf::ProtobufError>,
     T: TypeOptionDataDeserializer,
@@ -87,12 +123,11 @@ where
         let type_option = field_rev.get_type_option_entry::<T>(field_type_rev);
         let groups = G::generate_groups(&configuration, &type_option);
 
-        let default_group = Group {
-            id: DEFAULT_GROUP_ID.to_owned(),
-            desc: format!("No {}", field_rev.name),
-            rows: vec![],
-            content: "".to_string(),
-        };
+        let default_group = Group::new(
+            DEFAULT_GROUP_ID.to_owned(),
+            format!("No {}", field_rev.name),
+            "".to_string(),
+        );
 
         Ok(Self {
             field_id: field_rev.id.clone(),
@@ -104,8 +139,18 @@ where
             cell_parser_phantom: PhantomData,
         })
     }
+}
 
-    pub fn make_groups(&self) -> Vec<Group> {
+impl<C, T, G, P> GroupControllerSharedAction for GenericGroupController<C, T, G, P>
+where
+    P: CellBytesParser,
+    Self: Groupable<CellDataType = P::Object>,
+{
+    fn field_id(&self) -> &str {
+        &self.field_id
+    }
+
+    fn build_groups(&self) -> Vec<Group> {
         let default_group = self.default_group.clone();
         let mut groups: Vec<Group> = self.groups_map.values().cloned().collect();
         if !default_group.rows.is_empty() {
@@ -113,35 +158,28 @@ where
         }
         groups
     }
-}
 
-impl<C, T, G, P> GroupController<C, T, G, P>
-where
-    P: CellBytesParser,
-    Self: Groupable<CellDataType = P::Object>,
-{
-    pub fn handle_rows(&mut self, rows: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<()> {
-        // The field_rev might be None if corresponding field_rev is deleted.
+    fn group_rows(&mut self, row_revs: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<()> {
         if self.configuration.is_none() {
             return Ok(());
         }
 
-        for row in rows {
-            if let Some(cell_rev) = row.cells.get(&self.field_id) {
+        for row_rev in row_revs {
+            if let Some(cell_rev) = row_rev.cells.get(&self.field_id) {
                 let mut records: Vec<GroupRecord> = vec![];
                 let cell_bytes = decode_any_cell_data(cell_rev.data.clone(), field_rev);
                 let cell_data = cell_bytes.parser::<P>()?;
                 for group in self.groups_map.values() {
                     if self.can_group(&group.content, &cell_data) {
                         records.push(GroupRecord {
-                            row: row.into(),
+                            row: row_rev.into(),
                             group_id: group.id.clone(),
                         });
                     }
                 }
 
                 if records.is_empty() {
-                    self.default_group.rows.push(row.into());
+                    self.default_group.rows.push(row_rev.into());
                 } else {
                     for record in records {
                         if let Some(group) = self.groups_map.get_mut(&record.group_id) {
@@ -150,14 +188,71 @@ where
                     }
                 }
             } else {
-                self.default_group.rows.push(row.into());
+                self.default_group.rows.push(row_rev.into());
             }
         }
 
         Ok(())
     }
+
+    fn did_update_row(
+        &mut self,
+        row_rev: &RowRevision,
+        field_rev: &FieldRevision,
+    ) -> FlowyResult<Vec<GroupRowsChangesetPB>> {
+        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);
+            let cell_data = cell_bytes.parser::<P>()?;
+            Ok(self.group_row(row_rev, &cell_data))
+        } else {
+            Ok(vec![])
+        }
+    }
 }
 
+// impl<C, T, G, P> GroupController<C, T, G, P>
+// where
+//     P: CellBytesParser,
+//     Self: Groupable<CellDataType = P::Object>,
+// {
+//     pub fn handle_rows(&mut self, rows: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<()> {
+//         // The field_rev might be None if corresponding field_rev is deleted.
+//         if self.configuration.is_none() {
+//             return Ok(());
+//         }
+//
+//         for row in rows {
+//             if let Some(cell_rev) = row.cells.get(&self.field_id) {
+//                 let mut records: Vec<GroupRecord> = vec![];
+//                 let cell_bytes = decode_any_cell_data(cell_rev.data.clone(), field_rev);
+//                 let cell_data = cell_bytes.parser::<P>()?;
+//                 for group in self.groups_map.values() {
+//                     if self.can_group(&group.content, &cell_data) {
+//                         records.push(GroupRecord {
+//                             row: row.into(),
+//                             group_id: group.id.clone(),
+//                         });
+//                     }
+//                 }
+//
+//                 if records.is_empty() {
+//                     self.default_group.rows.push(row.into());
+//                 } else {
+//                     for record in records {
+//                         if let Some(group) = self.groups_map.get_mut(&record.group_id) {
+//                             group.rows.push(record.row);
+//                         }
+//                     }
+//                 }
+//             } else {
+//                 self.default_group.rows.push(row.into());
+//             }
+//         }
+//
+//         Ok(())
+//     }
+// }
+
 struct GroupRecord {
     row: RowPB,
     group_id: String,

+ 48 - 44
frontend/rust-lib/flowy-grid/src/services/group/group_generator/select_option_group.rs

@@ -1,17 +1,14 @@
-use crate::entities::SelectOptionGroupConfigurationPB;
+use crate::entities::{GroupRowsChangesetPB, InsertedRowPB, RowPB, SelectOptionGroupConfigurationPB};
 use crate::services::cell::insert_select_option_cell;
-use flowy_error::FlowyResult;
-use flowy_grid_data_model::revision::{FieldRevision, RowRevision};
-
-use std::sync::Arc;
-
 use crate::services::field::{
     MultiSelectTypeOptionPB, SelectOptionCellDataPB, SelectOptionCellDataParser, SingleSelectTypeOptionPB,
 };
-use crate::services::group::{Group, GroupActionHandler, GroupController, GroupGenerator, Groupable};
+use crate::services::group::{GenericGroupController, Group, GroupController, GroupGenerator, Groupable};
+
+use flowy_grid_data_model::revision::{FieldRevision, RowRevision};
 
 // SingleSelect
-pub type SingleSelectGroupController = GroupController<
+pub type SingleSelectGroupController = GenericGroupController<
     SelectOptionGroupConfigurationPB,
     SingleSelectTypeOptionPB,
     SingleSelectGroupGenerator,
@@ -23,21 +20,17 @@ impl Groupable for SingleSelectGroupController {
     fn can_group(&self, content: &str, cell_data: &SelectOptionCellDataPB) -> bool {
         cell_data.select_options.iter().any(|option| option.id == content)
     }
-}
 
-impl GroupActionHandler for SingleSelectGroupController {
-    fn field_id(&self) -> &str {
-        &self.field_id
-    }
-
-    fn build_groups(&self) -> Vec<Group> {
-        self.make_groups()
-    }
-
-    fn group_rows(&mut self, row_revs: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<()> {
-        self.handle_rows(row_revs, field_rev)
+    fn group_row(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType) -> Vec<GroupRowsChangesetPB> {
+        let mut changesets = vec![];
+        self.groups_map.iter_mut().for_each(|(_, group): (_, &mut Group)| {
+            group_select_option_row(group, &mut changesets, cell_data, row_rev);
+        });
+        changesets
     }
+}
 
+impl GroupController for SingleSelectGroupController {
     fn fill_row(&self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str) {
         let group: Option<&Group> = self.groups_map.get(group_id);
         match group {
@@ -63,19 +56,14 @@ impl GroupGenerator for SingleSelectGroupGenerator {
             Some(type_option) => type_option
                 .options
                 .iter()
-                .map(|option| Group {
-                    id: option.id.clone(),
-                    desc: option.name.clone(),
-                    rows: vec![],
-                    content: option.id.clone(),
-                })
+                .map(|option| Group::new(option.id.clone(), option.name.clone(), option.id.clone()))
                 .collect(),
         }
     }
 }
 
 // MultiSelect
-pub type MultiSelectGroupController = GroupController<
+pub type MultiSelectGroupController = GenericGroupController<
     SelectOptionGroupConfigurationPB,
     MultiSelectTypeOptionPB,
     MultiSelectGroupGenerator,
@@ -84,24 +72,22 @@ pub type MultiSelectGroupController = GroupController<
 
 impl Groupable 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)
     }
-}
 
-impl GroupActionHandler for MultiSelectGroupController {
-    fn field_id(&self) -> &str {
-        &self.field_id
-    }
-
-    fn build_groups(&self) -> Vec<Group> {
-        self.make_groups()
-    }
+    fn group_row(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType) -> Vec<GroupRowsChangesetPB> {
+        let mut changesets = vec![];
 
-    fn group_rows(&mut self, row_revs: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<()> {
-        self.handle_rows(row_revs, field_rev)
+        self.groups_map.iter_mut().for_each(|(_, group): (_, &mut Group)| {
+            group_select_option_row(group, &mut changesets, cell_data, row_rev);
+        });
+        changesets
     }
+}
 
+impl GroupController for MultiSelectGroupController {
     fn fill_row(&self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str) {
         let group: Option<&Group> = self.groups_map.get(group_id);
         match group {
@@ -128,13 +114,31 @@ impl GroupGenerator for MultiSelectGroupGenerator {
             Some(type_option) => type_option
                 .options
                 .iter()
-                .map(|option| Group {
-                    id: option.id.clone(),
-                    desc: option.name.clone(),
-                    rows: vec![],
-                    content: option.id.clone(),
-                })
+                .map(|option| Group::new(option.id.clone(), option.name.clone(), option.id.clone()))
                 .collect(),
         }
     }
 }
+
+fn group_select_option_row(
+    group: &mut Group,
+    changesets: &mut Vec<GroupRowsChangesetPB>,
+    cell_data: &SelectOptionCellDataPB,
+    row_rev: &RowRevision,
+) {
+    cell_data.select_options.iter().for_each(|option| {
+        if option.id == group.id {
+            if !group.contains_row(&row_rev.id) {
+                let row_pb = RowPB::from(row_rev);
+                changesets.push(GroupRowsChangesetPB::insert(
+                    group.id.clone(),
+                    vec![InsertedRowPB::new(row_pb.clone())],
+                ));
+                group.add_row(row_pb);
+            }
+        } else if group.contains_row(&row_rev.id) {
+            group.remove_row(&row_rev.id);
+            changesets.push(GroupRowsChangesetPB::delete(group.id.clone(), vec![row_rev.id.clone()]));
+        }
+    });
+}

+ 35 - 16
frontend/rust-lib/flowy-grid/src/services/group/group_service.rs

@@ -1,9 +1,9 @@
 use crate::entities::{
-    CheckboxGroupConfigurationPB, DateGroupConfigurationPB, FieldType, NumberGroupConfigurationPB,
-    SelectOptionGroupConfigurationPB, TextGroupConfigurationPB, UrlGroupConfigurationPB,
+    CheckboxGroupConfigurationPB, DateGroupConfigurationPB, FieldType, GroupRowsChangesetPB,
+    NumberGroupConfigurationPB, SelectOptionGroupConfigurationPB, TextGroupConfigurationPB, UrlGroupConfigurationPB,
 };
 use crate::services::group::{
-    CheckboxGroupController, Group, GroupActionHandler, MultiSelectGroupController, SingleSelectGroupController,
+    CheckboxGroupController, Group, GroupController, MultiSelectGroupController, SingleSelectGroupController,
 };
 use bytes::Bytes;
 use flowy_error::FlowyResult;
@@ -20,7 +20,7 @@ pub trait GroupConfigurationDelegate: Send + Sync + 'static {
 pub(crate) struct GroupService {
     pub groups: Vec<Group>,
     delegate: Box<dyn GroupConfigurationDelegate>,
-    group_action: Option<Arc<RwLock<dyn GroupActionHandler>>>,
+    group_controller: Option<Arc<RwLock<dyn GroupController>>>,
 }
 
 impl GroupService {
@@ -28,7 +28,7 @@ impl GroupService {
         Self {
             groups: vec![],
             delegate,
-            group_action: None,
+            group_controller: None,
         }
     }
 
@@ -52,24 +52,43 @@ impl GroupService {
         }
     }
 
-    pub(crate) async fn fill_row<F, O>(&self, row_rev: &mut RowRevision, group_id: &str, f: F)
+    pub(crate) async fn fill_row<F, O>(&self, row_rev: &mut RowRevision, group_id: &str, get_field_fn: F)
     where
         F: FnOnce(String) -> O,
         O: Future<Output = Option<Arc<FieldRevision>>> + Send + Sync + 'static,
     {
-        if let Some(group_action) = self.group_action.as_ref() {
-            let field_id = group_action.read().await.field_id().to_owned();
-            match f(field_id).await {
+        if let Some(group_controller) = self.group_controller.as_ref() {
+            let field_id = group_controller.read().await.field_id().to_owned();
+            match get_field_fn(field_id).await {
                 None => {}
                 Some(field_rev) => {
-                    group_action.write().await.fill_row(row_rev, &field_rev, group_id);
+                    group_controller.write().await.fill_row(row_rev, &field_rev, group_id);
                 }
             }
         }
     }
 
-    pub(crate) async fn did_update_row(&self, row_rev: Arc<RowRevision>) {
-        if let Some(group_action) = self.group_action.as_ref() {}
+    #[tracing::instrument(level = "trace", skip_all)]
+    pub(crate) async fn did_update_row<F, O>(
+        &self,
+        row_rev: &RowRevision,
+        get_field_fn: F,
+    ) -> Option<Vec<GroupRowsChangesetPB>>
+    where
+        F: FnOnce(String) -> O,
+        O: Future<Output = Option<Arc<FieldRevision>>> + Send + Sync + 'static,
+    {
+        let group_controller = self.group_controller.as_ref()?;
+        let field_id = group_controller.read().await.field_id().to_owned();
+        let field_rev = get_field_fn(field_id).await?;
+
+        match group_controller.write().await.did_update_row(row_rev, &field_rev) {
+            Ok(changeset) => Some(changeset),
+            Err(e) => {
+                tracing::error!("Update group data failed, {:?}", e);
+                None
+            }
+        }
     }
 
     #[tracing::instrument(level = "trace", skip_all, err)]
@@ -92,15 +111,15 @@ impl GroupService {
             }
             FieldType::SingleSelect => {
                 let controller = SingleSelectGroupController::new(field_rev, configuration)?;
-                self.group_action = Some(Arc::new(RwLock::new(controller)));
+                self.group_controller = Some(Arc::new(RwLock::new(controller)));
             }
             FieldType::MultiSelect => {
                 let controller = MultiSelectGroupController::new(field_rev, configuration)?;
-                self.group_action = Some(Arc::new(RwLock::new(controller)));
+                self.group_controller = Some(Arc::new(RwLock::new(controller)));
             }
             FieldType::Checkbox => {
                 let controller = CheckboxGroupController::new(field_rev, configuration)?;
-                self.group_action = Some(Arc::new(RwLock::new(controller)));
+                self.group_controller = Some(Arc::new(RwLock::new(controller)));
             }
             FieldType::URL => {
                 // let generator = GroupGenerator::<UrlGroupConfigurationPB>::from_configuration(configuration);
@@ -108,7 +127,7 @@ impl GroupService {
         };
 
         let mut groups = vec![];
-        if let Some(group_action_handler) = self.group_action.as_ref() {
+        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();

+ 1 - 1
frontend/rust-lib/flowy-sdk/src/lib.rs

@@ -75,7 +75,7 @@ fn crate_log_filter(level: String) -> String {
     filters.push(format!("lib_ws={}", level));
     filters.push(format!("lib_infra={}", level));
     filters.push(format!("flowy_sync={}", level));
-    filters.push(format!("flowy_revision={}", level));
+    // filters.push(format!("flowy_revision={}", level));
     // filters.push(format!("lib_dispatch={}", level));
 
     filters.push(format!("dart_ffi={}", "info"));