Browse Source

fix: row is not added into group when create a new row

appflowy 2 năm trước cách đây
mục cha
commit
3a27413dfc

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

@@ -62,6 +62,16 @@ impl std::convert::From<&RowRevision> for RowPB {
     }
 }
 
+impl std::convert::From<&mut RowRevision> for RowPB {
+    fn from(rev: &mut RowRevision) -> Self {
+        Self {
+            block_id: rev.block_id.clone(),
+            id: rev.id.clone(),
+            height: rev.height,
+        }
+    }
+}
+
 impl std::convert::From<&Arc<RowRevision>> for RowPB {
     fn from(rev: &Arc<RowRevision>) -> Self {
         Self {

+ 1 - 1
frontend/rust-lib/flowy-grid/src/services/block_editor.rs

@@ -127,7 +127,7 @@ impl GridBlockRevisionEditor {
         Ok(cell_revs)
     }
 
-    pub async fn get_row_info(&self, row_id: &str) -> FlowyResult<Option<RowPB>> {
+    pub async fn get_row_pb(&self, row_id: &str) -> FlowyResult<Option<RowPB>> {
         let row_ids = Some(vec![Cow::Borrowed(row_id)]);
         Ok(self.get_row_infos(row_ids).await?.pop())
     }

+ 9 - 7
frontend/rust-lib/flowy-grid/src/services/block_manager.rs

@@ -123,21 +123,23 @@ impl GridBlockManager {
     }
 
     #[tracing::instrument(level = "trace", skip_all, err)]
-    pub async fn delete_row(&self, row_id: &str) -> FlowyResult<()> {
+    pub async fn delete_row(&self, row_id: &str) -> FlowyResult<Option<Arc<RowRevision>>> {
         let row_id = row_id.to_owned();
         let block_id = self.persistence.get_block_id(&row_id)?;
         let editor = self.get_block_editor(&block_id).await?;
-        match editor.get_row_info(&row_id).await? {
-            None => {}
-            Some(row_info) => {
+        match editor.get_row_rev(&row_id).await? {
+            None => Ok(None),
+            Some(row_rev) => {
                 let _ = editor.delete_rows(vec![Cow::Borrowed(&row_id)]).await?;
                 let _ = self
-                    .notify_did_update_block(&block_id, GridBlockChangesetPB::delete(&block_id, vec![row_info.id]))
+                    .notify_did_update_block(
+                        &block_id,
+                        GridBlockChangesetPB::delete(&block_id, vec![row_rev.id.clone()]),
+                    )
                     .await?;
+                Ok(Some(row_rev))
             }
         }
-
-        Ok(())
     }
 
     pub(crate) async fn delete_rows(&self, row_orders: Vec<RowPB>) -> FlowyResult<Vec<GridBlockMetaRevisionChangeset>> {

+ 5 - 3
frontend/rust-lib/flowy-grid/src/services/grid_editor.rs

@@ -289,7 +289,7 @@ impl GridRevisionEditor {
     pub async fn create_row(&self, params: CreateRowParams) -> FlowyResult<RowPB> {
         let mut row_rev = self.create_row_rev().await?;
 
-        self.view_manager.fill_row(&mut row_rev, &params).await;
+        self.view_manager.will_create_row(&mut row_rev, &params).await;
 
         let row_pb = self.create_row_pb(row_rev, params.start_row_id.clone()).await?;
 
@@ -346,8 +346,10 @@ impl GridRevisionEditor {
     }
 
     pub async fn delete_row(&self, row_id: &str) -> FlowyResult<()> {
-        let _ = self.block_manager.delete_row(row_id).await?;
-        self.view_manager.did_delete_row(row_id).await;
+        let row_rev = self.block_manager.delete_row(row_id).await?;
+        if let Some(row_rev) = row_rev {
+            self.view_manager.did_delete_row(row_rev).await;
+        }
         Ok(())
     }
 

+ 20 - 31
frontend/rust-lib/flowy-grid/src/services/grid_view_editor.rs

@@ -59,23 +59,18 @@ impl GridViewRevisionEditor {
         })
     }
 
-    pub(crate) async fn fill_row(&self, row_rev: &mut RowRevision, params: &CreateRowParams) {
-        match params.layout {
-            GridLayout::Table => {
-                // Table can be grouped too
+    pub(crate) async fn will_create_row(&self, row_rev: &mut RowRevision, params: &CreateRowParams) {
+        match params.group_id.as_ref() {
+            None => {}
+            Some(group_id) => {
+                self.group_service
+                    .read()
+                    .await
+                    .will_create_row(row_rev, group_id, |field_id| {
+                        self.field_delegate.get_field_rev(&field_id)
+                    })
+                    .await;
             }
-            GridLayout::Board => match params.group_id.as_ref() {
-                None => {}
-                Some(group_id) => {
-                    self.group_service
-                        .read()
-                        .await
-                        .fill_row(row_rev, group_id, |field_id| {
-                            self.field_delegate.get_field_rev(&field_id)
-                        })
-                        .await;
-                }
-            },
         }
     }
 
@@ -94,12 +89,16 @@ impl GridViewRevisionEditor {
         }
     }
 
-    pub(crate) async fn did_delete_row(&self, row_id: &str) {
+    pub(crate) async fn did_delete_row(&self, row_rev: &RowRevision) {
         // Send the group notification if the current view has groups;
-        match self.group_id_of_row(row_id).await {
-            None => {}
-            Some(group_id) => {
-                let changeset = GroupRowsChangesetPB::delete(group_id, vec![row_id.to_owned()]);
+        if let Some(changesets) = self
+            .group_service
+            .write()
+            .await
+            .did_delete_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;
             }
         }
@@ -119,16 +118,6 @@ 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.contains_row(row_id) {
-                return Some(group.id.clone());
-            }
-        }
-        None
-    }
-
     // async fn get_mut_group<F>(&self, group_id: &str, f: F) -> FlowyResult<()>
     // where
     //     F: Fn(&mut Group) -> FlowyResult<()>,

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

@@ -66,9 +66,15 @@ impl GridViewManager {
         })
     }
 
-    pub(crate) async fn fill_row(&self, row_rev: &mut RowRevision, params: &CreateRowParams) {
+    pub(crate) async fn will_create_row(&self, row_rev: &mut RowRevision, params: &CreateRowParams) {
         for view_editor in self.view_editors.iter() {
-            view_editor.fill_row(row_rev, params).await;
+            view_editor.will_create_row(row_rev, params).await;
+        }
+    }
+
+    pub(crate) async fn did_create_row(&self, row_pb: &RowPB, params: &CreateRowParams) {
+        for view_editor in self.view_editors.iter() {
+            view_editor.did_create_row(row_pb, params).await;
         }
     }
 
@@ -85,15 +91,9 @@ impl GridViewManager {
         }
     }
 
-    pub(crate) async fn did_create_row(&self, row_pb: &RowPB, params: &CreateRowParams) {
-        for view_editor in self.view_editors.iter() {
-            view_editor.did_create_row(row_pb, params).await;
-        }
-    }
-
-    pub(crate) async fn did_delete_row(&self, row_id: &str) {
+    pub(crate) async fn did_delete_row(&self, row_rev: Arc<RowRevision>) {
         for view_editor in self.view_editors.iter() {
-            view_editor.did_delete_row(row_id).await;
+            view_editor.did_delete_row(&row_rev).await;
         }
     }
 

+ 22 - 2
frontend/rust-lib/flowy-grid/src/services/group/group_generator/checkbox_group.rs

@@ -19,13 +19,33 @@ impl Groupable for CheckboxGroupController {
         false
     }
 
-    fn group_row(&mut self, _row_rev: &RowRevision, _cell_data: &Self::CellDataType) -> Vec<GroupRowsChangesetPB> {
+    fn add_row_if_match(
+        &mut self,
+        _row_rev: &RowRevision,
+        _cell_data: &Self::CellDataType,
+    ) -> Vec<GroupRowsChangesetPB> {
+        todo!()
+    }
+
+    fn remove_row_if_match(
+        &mut self,
+        row_rev: &RowRevision,
+        cell_data: &Self::CellDataType,
+    ) -> Vec<GroupRowsChangesetPB> {
+        todo!()
+    }
+
+    fn move_row_if_match(
+        &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) {
+    fn will_create_row(&mut self, _row_rev: &mut RowRevision, _field_rev: &FieldRevision, _group_id: &str) {
         todo!()
     }
 }

+ 31 - 3
frontend/rust-lib/flowy-grid/src/services/group/group_generator/generator.rs → frontend/rust-lib/flowy-grid/src/services/group/group_generator/group_controller.rs

@@ -22,11 +22,19 @@ pub trait GroupGenerator {
 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>;
+    fn add_row_if_match(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType) -> Vec<GroupRowsChangesetPB>;
+    fn remove_row_if_match(
+        &mut self,
+        row_rev: &RowRevision,
+        cell_data: &Self::CellDataType,
+    ) -> Vec<GroupRowsChangesetPB>;
+
+    fn move_row_if_match(&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);
+    fn will_create_row(&mut self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str);
 }
 
 pub trait GroupControllerSharedAction: Send + Sync {
@@ -39,6 +47,12 @@ pub trait GroupControllerSharedAction: Send + Sync {
         row_rev: &RowRevision,
         field_rev: &FieldRevision,
     ) -> FlowyResult<Vec<GroupRowsChangesetPB>>;
+
+    fn did_delete_row(
+        &mut self,
+        row_rev: &RowRevision,
+        field_rev: &FieldRevision,
+    ) -> FlowyResult<Vec<GroupRowsChangesetPB>>;
 }
 
 const DEFAULT_GROUP_ID: &str = "default_group";
@@ -203,7 +217,21 @@ 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);
             let cell_data = cell_bytes.parser::<P>()?;
-            Ok(self.group_row(row_rev, &cell_data))
+            Ok(self.add_row_if_match(row_rev, &cell_data))
+        } else {
+            Ok(vec![])
+        }
+    }
+
+    fn did_delete_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.remove_row_if_match(row_rev, &cell_data))
         } else {
             Ok(vec![])
         }

+ 2 - 2
frontend/rust-lib/flowy-grid/src/services/group/group_generator/mod.rs

@@ -1,7 +1,7 @@
 mod checkbox_group;
-mod generator;
+mod group_controller;
 mod select_option_group;
 
 pub use checkbox_group::*;
-pub use generator::*;
+pub use group_controller::*;
 pub use select_option_group::*;

+ 70 - 11
frontend/rust-lib/flowy-grid/src/services/group/group_generator/select_option_group.rs

@@ -21,23 +21,44 @@ impl Groupable for SingleSelectGroupController {
         cell_data.select_options.iter().any(|option| option.id == content)
     }
 
-    fn group_row(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType) -> Vec<GroupRowsChangesetPB> {
+    fn add_row_if_match(&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);
+            add_row(group, &mut changesets, cell_data, row_rev);
         });
         changesets
     }
+
+    fn remove_row_if_match(
+        &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)| {
+            remove_row(group, &mut changesets, cell_data, row_rev);
+        });
+        changesets
+    }
+
+    fn move_row_if_match(
+        &mut self,
+        row_rev: &RowRevision,
+        cell_data: &Self::CellDataType,
+    ) -> Vec<GroupRowsChangesetPB> {
+        todo!()
+    }
 }
 
 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);
+    fn will_create_row(&mut self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str) {
+        let group: Option<&mut Group> = self.groups_map.get_mut(group_id);
         match group {
             None => {}
             Some(group) => {
                 let cell_rev = insert_select_option_cell(group.id.clone(), field_rev);
                 row_rev.cells.insert(field_rev.id.clone(), cell_rev);
+                group.add_row(RowPB::from(row_rev));
             }
         }
     }
@@ -77,18 +98,38 @@ impl Groupable for MultiSelectGroupController {
         cell_data.select_options.iter().any(|option| option.id == content)
     }
 
-    fn group_row(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType) -> Vec<GroupRowsChangesetPB> {
+    fn add_row_if_match(&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);
+            add_row(group, &mut changesets, cell_data, row_rev);
+        });
+        changesets
+    }
+
+    fn remove_row_if_match(
+        &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)| {
+            remove_row(group, &mut changesets, cell_data, row_rev);
         });
         changesets
     }
+
+    fn move_row_if_match(
+        &mut self,
+        row_rev: &RowRevision,
+        cell_data: &Self::CellDataType,
+    ) -> Vec<GroupRowsChangesetPB> {
+        todo!()
+    }
 }
 
 impl GroupController for MultiSelectGroupController {
-    fn fill_row(&self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str) {
+    fn will_create_row(&mut self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str) {
         let group: Option<&Group> = self.groups_map.get(group_id);
         match group {
             None => tracing::warn!("Can not find the group: {}", group_id),
@@ -120,7 +161,7 @@ impl GroupGenerator for MultiSelectGroupGenerator {
     }
 }
 
-fn group_select_option_row(
+fn add_row(
     group: &mut Group,
     changesets: &mut Vec<GroupRowsChangesetPB>,
     cell_data: &SelectOptionCellDataPB,
@@ -136,9 +177,27 @@ fn group_select_option_row(
                 ));
                 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()]));
+        }
+
+        // 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()]));
+        // }
+    });
+}
+
+fn remove_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) {
+                changesets.push(GroupRowsChangesetPB::delete(group.id.clone(), vec![row_rev.id.clone()]));
+                group.remove_row(&row_rev.id);
+            }
         }
     });
 }

+ 27 - 2
frontend/rust-lib/flowy-grid/src/services/group/group_service.rs

@@ -52,7 +52,7 @@ impl GroupService {
         }
     }
 
-    pub(crate) async fn fill_row<F, O>(&self, row_rev: &mut RowRevision, group_id: &str, get_field_fn: F)
+    pub(crate) async fn will_create_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,
@@ -62,12 +62,37 @@ impl GroupService {
             match get_field_fn(field_id).await {
                 None => {}
                 Some(field_rev) => {
-                    group_controller.write().await.fill_row(row_rev, &field_rev, group_id);
+                    group_controller
+                        .write()
+                        .await
+                        .will_create_row(row_rev, &field_rev, group_id);
                 }
             }
         }
     }
 
+    pub(crate) async fn did_delete_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_delete_row(row_rev, &field_rev) {
+            Ok(changesets) => Some(changesets),
+            Err(e) => {
+                tracing::error!("Update group data failed, {:?}", e);
+                None
+            }
+        }
+    }
+
     #[tracing::instrument(level = "trace", skip_all)]
     pub(crate) async fn did_update_row<F, O>(
         &self,