From f792283e70a2a68b0b5a5b4eb1a09225241f1abc Mon Sep 17 00:00:00 2001
From: appflowy <annie@appflowy.io>
Date: Fri, 16 Sep 2022 13:15:13 +0800
Subject: [PATCH 1/6] chore: fix open application error when upgrade to 0.0.5.1

---
 .../src/services/persistence/migration.rs        |  7 +++----
 .../flowy-folder/src/services/persistence/mod.rs |  3 +--
 .../text_type_option/text_type_option.rs         |  1 +
 .../src/client_grid/view_revision_pad.rs         | 16 ++++++++++++++--
 4 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/frontend/rust-lib/flowy-folder/src/services/persistence/migration.rs b/frontend/rust-lib/flowy-folder/src/services/persistence/migration.rs
index 7b211fb54a..82ebcd9b65 100644
--- a/frontend/rust-lib/flowy-folder/src/services/persistence/migration.rs
+++ b/frontend/rust-lib/flowy-folder/src/services/persistence/migration.rs
@@ -78,7 +78,7 @@ impl FolderMigration {
 
         let folder = FolderPad::new(workspaces, trash)?;
         KV::set_bool(&key, true);
-        tracing::trace!("Run folder v1 migration");
+        tracing::info!("Run folder v1 migration");
         Ok(Some(folder))
     }
 
@@ -89,11 +89,10 @@ impl FolderMigration {
         }
         let _ = self.migration_folder_rev_struct(folder_id).await?;
         KV::set_bool(&key, true);
-        tracing::trace!("Run folder v2 migration");
+        // tracing::info!("Run folder v2 migration");
         Ok(())
     }
 
-    #[allow(dead_code)]
     pub async fn run_v3_migration(&self, folder_id: &FolderId) -> FlowyResult<()> {
         let key = migration_flag_key(&self.user_id, V3_MIGRATION);
         if KV::get_bool(&key) {
@@ -101,7 +100,7 @@ impl FolderMigration {
         }
         let _ = self.migration_folder_rev_struct(folder_id).await?;
         KV::set_bool(&key, true);
-        tracing::trace!("Run folder v3 migration");
+        tracing::info!("Run folder v3 migration");
         Ok(())
     }
 
diff --git a/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs b/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs
index 084ab06b99..1e0c5e9b28 100644
--- a/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs
+++ b/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs
@@ -101,8 +101,7 @@ impl FolderPersistence {
         }
 
         let _ = migrations.run_v2_migration(folder_id).await?;
-
-        // let _ = migrations.run_v3_migration(folder_id).await?;
+        let _ = migrations.run_v3_migration(folder_id).await?;
         Ok(())
     }
 
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 33c1f7eb9e..2890289254 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
@@ -29,6 +29,7 @@ impl TypeOptionBuilder for RichTextTypeOptionBuilder {
 #[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)]
 pub struct RichTextTypeOptionPB {
     #[pb(index = 1)]
+    #[serde(default)]
     data: String, //It's not used yet
 }
 impl_type_option!(RichTextTypeOptionPB, FieldType::RichText);
diff --git a/shared-lib/flowy-sync/src/client_grid/view_revision_pad.rs b/shared-lib/flowy-sync/src/client_grid/view_revision_pad.rs
index 36f058d798..9c0d8b4d1b 100644
--- a/shared-lib/flowy-sync/src/client_grid/view_revision_pad.rs
+++ b/shared-lib/flowy-sync/src/client_grid/view_revision_pad.rs
@@ -23,6 +23,8 @@ impl std::ops::Deref for GridViewRevisionPad {
 }
 
 impl GridViewRevisionPad {
+    // For the moment, the view_id is equal to grid_id. The grid_id represents the database id.
+    // A database can be referenced by multiple views.
     pub fn new(grid_id: String, view_id: String) -> Self {
         let view = Arc::new(GridViewRevision::new(grid_id, view_id));
         let json = serde_json::to_string(&view).unwrap();
@@ -30,11 +32,15 @@ impl GridViewRevisionPad {
         Self { view, delta }
     }
 
-    pub fn from_delta(delta: Delta) -> CollaborateResult<Self> {
+
+    pub fn from_delta(view_id: &str, delta: Delta) -> CollaborateResult<Self> {
+        if delta.is_empty() {
+            return Ok(GridViewRevisionPad::new(view_id.to_owned(), view_id.to_owned()));
+        }
         let s = delta.content()?;
         let view: GridViewRevision = serde_json::from_str(&s).map_err(|e| {
             let msg = format!("Deserialize delta to GridViewRevision failed: {}", e);
-            tracing::error!("{}", s);
+            tracing::error!("parsing json: {}", s);
             CollaborateError::internal().context(msg)
         })?;
         Ok(Self {
@@ -43,9 +49,15 @@ impl GridViewRevisionPad {
         })
     }
 
+<<<<<<< HEAD
     pub fn from_revisions(_grid_id: &str, revisions: Vec<Revision>) -> CollaborateResult<Self> {
         let delta: Delta = make_text_delta_from_revisions(revisions)?;
         Self::from_delta(delta)
+=======
+    pub fn from_revisions(view_id: &str, revisions: Vec<Revision>) -> CollaborateResult<Self> {
+        let delta: TextDelta = make_text_delta_from_revisions(revisions)?;
+        Self::from_delta(view_id, delta)
+>>>>>>> 01dbc68d4 (chore: fix open application error when upgrade to 0.0.5.1)
     }
 
     pub fn get_groups_by_field_revs(&self, field_revs: &[Arc<FieldRevision>]) -> Option<GroupConfigurationsByFieldId> {

From 4c07ae26fc51c62dbe4b5be3453af9c1b52c8389 Mon Sep 17 00:00:00 2001
From: appflowy <annie@appflowy.io>
Date: Fri, 16 Sep 2022 15:43:11 +0800
Subject: [PATCH 2/6] chore: fix trailing characters parser error

---
 .../src/revision/folder_rev.rs                | 71 ++++++++++++++++++-
 .../src/client_folder/folder_pad.rs           |  6 +-
 2 files changed, 74 insertions(+), 3 deletions(-)

diff --git a/shared-lib/flowy-folder-data-model/src/revision/folder_rev.rs b/shared-lib/flowy-folder-data-model/src/revision/folder_rev.rs
index f7d48b93fd..e253ad56f5 100644
--- a/shared-lib/flowy-folder-data-model/src/revision/folder_rev.rs
+++ b/shared-lib/flowy-folder-data-model/src/revision/folder_rev.rs
@@ -1,9 +1,76 @@
 use crate::revision::{TrashRevision, WorkspaceRevision};
-use serde::{Deserialize, Serialize};
+use serde::de::{MapAccess, Visitor};
+use serde::{de, Deserialize, Deserializer, Serialize};
+use std::fmt;
 use std::sync::Arc;
 
-#[derive(Debug, Default, Deserialize, Serialize, Clone, Eq, PartialEq)]
+#[derive(Debug, Default, Serialize, Clone, Eq, PartialEq)]
 pub struct FolderRevision {
     pub workspaces: Vec<Arc<WorkspaceRevision>>,
     pub trash: Vec<Arc<TrashRevision>>,
 }
+
+impl<'de> Deserialize<'de> for FolderRevision {
+    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        struct FolderVisitor<'a>(&'a mut Option<FolderRevision>);
+        impl<'de, 'a> Visitor<'de> for FolderVisitor<'a> {
+            type Value = ();
+            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+                formatter.write_str("Expect struct FolderRevision")
+            }
+
+            fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
+            where
+                A: MapAccess<'de>,
+            {
+                let f = |map: &mut A,
+                         workspaces: &mut Option<Vec<WorkspaceRevision>>,
+                         trash: &mut Option<Vec<TrashRevision>>| match map.next_key::<String>()
+                {
+                    Ok(Some(key)) => {
+                        if key == "workspaces" && workspaces.is_none() {
+                            *workspaces = Some(map.next_value::<Vec<WorkspaceRevision>>().ok()?);
+                        }
+                        if key == "trash" && trash.is_none() {
+                            *trash = Some(map.next_value::<Vec<TrashRevision>>().ok()?);
+                        }
+                        Some(())
+                    }
+                    Ok(None) => None,
+                    Err(_e) => None,
+                };
+
+                let mut workspaces: Option<Vec<WorkspaceRevision>> = None;
+                let mut trash: Option<Vec<TrashRevision>> = None;
+                while f(&mut map, &mut workspaces, &mut trash).is_some() {
+                    if workspaces.is_some() && trash.is_some() {
+                        break;
+                    }
+                }
+
+                *self.0 = Some(FolderRevision {
+                    workspaces: workspaces.unwrap_or_default().into_iter().map(Arc::new).collect(),
+                    trash: trash.unwrap_or_default().into_iter().map(Arc::new).collect(),
+                });
+                Ok(())
+            }
+        }
+
+        let mut folder_rev: Option<FolderRevision> = None;
+        const FIELDS: &[&str] = &["workspaces", "trash"];
+        let _ = serde::Deserializer::deserialize_struct(
+            deserializer,
+            "FolderRevision",
+            FIELDS,
+            FolderVisitor(&mut folder_rev),
+        );
+
+        match folder_rev {
+            None => Err(de::Error::missing_field("workspaces or trash")),
+            Some(folder_rev) => Ok(folder_rev),
+        }
+    }
+}
diff --git a/shared-lib/flowy-sync/src/client_folder/folder_pad.rs b/shared-lib/flowy-sync/src/client_folder/folder_pad.rs
index 69ed94a69b..93bed69641 100644
--- a/shared-lib/flowy-sync/src/client_folder/folder_pad.rs
+++ b/shared-lib/flowy-sync/src/client_folder/folder_pad.rs
@@ -12,6 +12,7 @@ use flowy_folder_data_model::revision::{AppRevision, FolderRevision, TrashRevisi
 use lib_infra::util::move_vec_element;
 use lib_ot::core::*;
 
+use serde::Deserialize;
 use std::sync::Arc;
 
 #[derive(Debug, Clone, Eq, PartialEq)]
@@ -44,7 +45,9 @@ impl FolderPad {
     pub fn from_delta(delta: FolderDelta) -> CollaborateResult<Self> {
         // TODO: Reconvert from history if delta.to_str() failed.
         let content = delta.content()?;
-        let folder_rev: FolderRevision = serde_json::from_str(&content).map_err(|e| {
+        let mut deserializer = serde_json::Deserializer::from_reader(content.as_bytes());
+
+        let folder_rev = FolderRevision::deserialize(&mut deserializer).map_err(|e| {
             tracing::error!("Deserialize folder from {} failed", content);
             return CollaborateError::internal().context(format!("Deserialize delta to folder failed: {}", e));
         })?;
@@ -455,6 +458,7 @@ mod tests {
     #![allow(clippy::all)]
     use crate::{client_folder::folder_pad::FolderPad, entities::folder::FolderDelta};
     use chrono::Utc;
+    use serde::Deserialize;
 
     use flowy_folder_data_model::revision::{
         AppRevision, FolderRevision, TrashRevision, ViewRevision, WorkspaceRevision,

From 496123601295f2ee63952c7c6a91f9a981b2e928 Mon Sep 17 00:00:00 2001
From: appflowy <annie@appflowy.io>
Date: Fri, 16 Sep 2022 18:28:16 +0800
Subject: [PATCH 3/6] chore: update version to 0.0.5.2

---
 frontend/Makefile.toml                             |  2 +-
 .../src/revision/app_rev.rs                        |  3 +++
 .../src/revision/trash_rev.rs                      |  2 ++
 .../src/revision/view_rev.rs                       |  3 ++-
 .../src/revision/workspace_rev.rs                  |  2 ++
 .../flowy-sync/src/client_folder/folder_pad.rs     | 14 ++++++++++++++
 6 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/frontend/Makefile.toml b/frontend/Makefile.toml
index bdecb73712..05de6d7fad 100644
--- a/frontend/Makefile.toml
+++ b/frontend/Makefile.toml
@@ -22,7 +22,7 @@ CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true
 CARGO_MAKE_CRATE_FS_NAME = "dart_ffi"
 CARGO_MAKE_CRATE_NAME = "dart-ffi"
 LIB_NAME = "dart_ffi"
-CURRENT_APP_VERSION = "0.0.5.1"
+CURRENT_APP_VERSION = "0.0.5.2"
 FEATURES = "flutter"
 PRODUCT_NAME = "AppFlowy"
 # CRATE_TYPE: https://doc.rust-lang.org/reference/linkage.html
diff --git a/shared-lib/flowy-folder-data-model/src/revision/app_rev.rs b/shared-lib/flowy-folder-data-model/src/revision/app_rev.rs
index 015cb70427..a942acb16b 100644
--- a/shared-lib/flowy-folder-data-model/src/revision/app_rev.rs
+++ b/shared-lib/flowy-folder-data-model/src/revision/app_rev.rs
@@ -17,10 +17,13 @@ pub struct AppRevision {
 
     pub belongings: Vec<ViewRevision>,
 
+    #[serde(default)]
     pub version: i64,
 
+    #[serde(default)]
     pub modified_time: i64,
 
+    #[serde(default)]
     pub create_time: i64,
 }
 
diff --git a/shared-lib/flowy-folder-data-model/src/revision/trash_rev.rs b/shared-lib/flowy-folder-data-model/src/revision/trash_rev.rs
index 0855fb3d29..1e0b1a6e54 100644
--- a/shared-lib/flowy-folder-data-model/src/revision/trash_rev.rs
+++ b/shared-lib/flowy-folder-data-model/src/revision/trash_rev.rs
@@ -8,8 +8,10 @@ pub struct TrashRevision {
 
     pub name: String,
 
+    #[serde(default)]
     pub modified_time: i64,
 
+    #[serde(default)]
     pub create_time: i64,
 
     pub ty: TrashTypeRevision,
diff --git a/shared-lib/flowy-folder-data-model/src/revision/view_rev.rs b/shared-lib/flowy-folder-data-model/src/revision/view_rev.rs
index f5bf1d7ffc..e5ee15f7c9 100644
--- a/shared-lib/flowy-folder-data-model/src/revision/view_rev.rs
+++ b/shared-lib/flowy-folder-data-model/src/revision/view_rev.rs
@@ -9,7 +9,6 @@ pub fn gen_view_id() -> String {
 pub struct ViewRevision {
     pub id: String,
 
-    // Maybe app_id or vi
     #[serde(rename = "belong_to_id")]
     pub app_id: String,
 
@@ -24,8 +23,10 @@ pub struct ViewRevision {
 
     pub belongings: Vec<ViewRevision>,
 
+    #[serde(default)]
     pub modified_time: i64,
 
+    #[serde(default)]
     pub create_time: i64,
 
     #[serde(default)]
diff --git a/shared-lib/flowy-folder-data-model/src/revision/workspace_rev.rs b/shared-lib/flowy-folder-data-model/src/revision/workspace_rev.rs
index d975663931..823bb4233f 100644
--- a/shared-lib/flowy-folder-data-model/src/revision/workspace_rev.rs
+++ b/shared-lib/flowy-folder-data-model/src/revision/workspace_rev.rs
@@ -14,7 +14,9 @@ pub struct WorkspaceRevision {
 
     pub apps: Vec<AppRevision>,
 
+    #[serde(default)]
     pub modified_time: i64,
 
+    #[serde(default)]
     pub create_time: i64,
 }
diff --git a/shared-lib/flowy-sync/src/client_folder/folder_pad.rs b/shared-lib/flowy-sync/src/client_folder/folder_pad.rs
index 93bed69641..964df23fd7 100644
--- a/shared-lib/flowy-sync/src/client_folder/folder_pad.rs
+++ b/shared-lib/flowy-sync/src/client_folder/folder_pad.rs
@@ -482,6 +482,20 @@ mod tests {
         assert_eq!(folder, folder_from_delta);
     }
 
+    #[test]
+    fn folder_deserialize_invalid_json_test() {
+        for json in vec![
+            // No timestamp
+            r#"{"workspaces":[{"id":"1","name":"first workspace","desc":"","apps":[]}],"trash":[]}"#,
+            // Trailing characters
+            r#"{"workspaces":[{"id":"1","name":"first workspace","desc":"","apps":[]}],"trash":[]}123"#,
+        ] {
+            let mut deserializer = serde_json::Deserializer::from_reader(json.as_bytes());
+            let folder_rev = FolderRevision::deserialize(&mut deserializer).unwrap();
+            assert_eq!(folder_rev.workspaces.first().as_ref().unwrap().name, "first workspace");
+        }
+    }
+
     #[test]
     fn folder_update_workspace() {
         let (mut folder, initial_delta, workspace) = test_folder();

From a204af97839733948c468587434c904cbe2aef34 Mon Sep 17 00:00:00 2001
From: appflowy <annie@appflowy.io>
Date: Fri, 16 Sep 2022 18:55:54 +0800
Subject: [PATCH 4/6] chore: enable create card from no status column

---
 .../board/presentation/board_page.dart        | 50 +++++++++----------
 1 file changed, 23 insertions(+), 27 deletions(-)

diff --git a/frontend/app_flowy/lib/plugins/board/presentation/board_page.dart b/frontend/app_flowy/lib/plugins/board/presentation/board_page.dart
index 3a34469cd7..2a1762c3ed 100644
--- a/frontend/app_flowy/lib/plugins/board/presentation/board_page.dart
+++ b/frontend/app_flowy/lib/plugins/board/presentation/board_page.dart
@@ -187,35 +187,31 @@ class _BoardContentState extends State<BoardContent> {
   }
 
   Widget _buildFooter(BuildContext context, AppFlowyGroupData columnData) {
-    final boardCustomData = columnData.customData as BoardCustomData;
-    final group = boardCustomData.group;
+    // final boardCustomData = columnData.customData as BoardCustomData;
+    // final group = boardCustomData.group;
 
-    if (group.isDefault) {
-      return const SizedBox();
-    } else {
-      return AppFlowyGroupFooter(
-        icon: SizedBox(
-          height: 20,
-          width: 20,
-          child: svgWidget(
-            "home/add",
-            color: context.read<AppTheme>().iconColor,
-          ),
+    return AppFlowyGroupFooter(
+      icon: SizedBox(
+        height: 20,
+        width: 20,
+        child: svgWidget(
+          "home/add",
+          color: context.read<AppTheme>().iconColor,
         ),
-        title: FlowyText.medium(
-          LocaleKeys.board_column_create_new_card.tr(),
-          fontSize: 14,
-          color: context.read<AppTheme>().textColor,
-        ),
-        height: 50,
-        margin: config.footerPadding,
-        onAddButtonClick: () {
-          context.read<BoardBloc>().add(
-                BoardEvent.createBottomRow(columnData.id),
-              );
-        },
-      );
-    }
+      ),
+      title: FlowyText.medium(
+        LocaleKeys.board_column_create_new_card.tr(),
+        fontSize: 14,
+        color: context.read<AppTheme>().textColor,
+      ),
+      height: 50,
+      margin: config.footerPadding,
+      onAddButtonClick: () {
+        context.read<BoardBloc>().add(
+              BoardEvent.createBottomRow(columnData.id),
+            );
+      },
+    );
   }
 
   Widget _buildCard(

From 2b451fa06dd63d08ddbbbddc9cb6a640a9648582 Mon Sep 17 00:00:00 2001
From: appflowy <annie@appflowy.io>
Date: Fri, 16 Sep 2022 19:08:20 +0800
Subject: [PATCH 5/6] chore: fix delete card issue

---
 .../presentation/widgets/row/row_action_sheet.dart   | 12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/row_action_sheet.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/row_action_sheet.dart
index e67908f544..9f2c9e8ef5 100644
--- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/row_action_sheet.dart
+++ b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/row_action_sheet.dart
@@ -1,5 +1,4 @@
 import 'package:app_flowy/plugins/grid/application/row/row_action_sheet_bloc.dart';
-import 'package:app_flowy/workspace/presentation/widgets/dialogs.dart';
 import 'package:easy_localization/easy_localization.dart';
 import 'package:app_flowy/generated/locale_keys.g.dart';
 import 'package:flowy_infra/image.dart';
@@ -151,14 +150,9 @@ extension _RowActionExtension on _RowAction {
             .add(const RowActionSheetEvent.duplicateRow());
         break;
       case _RowAction.delete:
-        NavigatorAlertDialog(
-          title: LocaleKeys.grid_field_deleteFieldPromptMessage.tr(),
-          confirm: () {
-            context
-                .read<RowActionSheetBloc>()
-                .add(const RowActionSheetEvent.deleteRow());
-          },
-        ).show(context);
+        context
+            .read<RowActionSheetBloc>()
+            .add(const RowActionSheetEvent.deleteRow());
 
         break;
     }

From 589acd9e2bc24e1ccc908dc735d1554980f349be Mon Sep 17 00:00:00 2001
From: appflowy <annie@appflowy.io>
Date: Fri, 16 Sep 2022 20:00:51 +0800
Subject: [PATCH 6/6] fix: can not delete row from no status group

---
 .../flowy-grid/src/services/block_manager.rs  |  1 +
 .../flowy-grid/src/services/grid_editor.rs    |  1 +
 .../src/services/grid_view_editor.rs          |  2 +
 .../src/services/group/configuration.rs       | 46 +++++++++----------
 .../src/services/group/controller.rs          | 15 ++++--
 .../controller_impls/checkbox_controller.rs   |  6 +--
 .../multi_select_controller.rs                |  6 +--
 .../single_select_controller.rs               |  6 +--
 .../src/client_grid/view_revision_pad.rs      |  9 +---
 9 files changed, 47 insertions(+), 45 deletions(-)

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 800348fb97..ef5632b0c5 100644
--- a/frontend/rust-lib/flowy-grid/src/services/block_manager.rs
+++ b/frontend/rust-lib/flowy-grid/src/services/block_manager.rs
@@ -57,6 +57,7 @@ impl GridBlockManager {
         Ok(self.get_block_editor(&block_id).await?)
     }
 
+    #[tracing::instrument(level = "trace", skip(self, start_row_id), err)]
     pub(crate) async fn create_row(&self, row_rev: RowRevision, start_row_id: Option<String>) -> FlowyResult<i32> {
         let block_id = row_rev.block_id.clone();
         let _ = self.persistence.insert(&row_rev.block_id, &row_rev.id)?;
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 320d41cbff..aa913c2c4e 100644
--- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs
+++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs
@@ -420,6 +420,7 @@ impl GridRevisionEditor {
 
     pub async fn delete_row(&self, row_id: &str) -> FlowyResult<()> {
         let row_rev = self.block_manager.delete_row(row_id).await?;
+        tracing::trace!("Did delete row:{:?}", row_rev);
         if let Some(row_rev) = row_rev {
             self.view_manager.did_delete_row(row_rev).await;
         }
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 0a8600c891..c7fb7f0a7f 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
@@ -109,6 +109,7 @@ impl GridViewRevisionEditor {
         }
     }
 
+    #[tracing::instrument(level = "trace", skip_all)]
     pub(crate) async fn did_delete_row(&self, row_rev: &RowRevision) {
         // Send the group notification if the current view has groups;
         let changesets = self
@@ -116,6 +117,7 @@ impl GridViewRevisionEditor {
             .await;
 
         if let Some(changesets) = changesets {
+            tracing::trace!("{:?}", changesets);
             for changeset in changesets {
                 self.notify_did_update_group(changeset).await;
             }
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 1518240442..07e5ba45d4 100644
--- a/frontend/rust-lib/flowy-grid/src/services/group/configuration.rs
+++ b/frontend/rust-lib/flowy-grid/src/services/group/configuration.rs
@@ -92,17 +92,33 @@ where
         })
     }
 
-    /// Returns the groups without the default group
-    pub(crate) fn concrete_groups(&self) -> Vec<&Group> {
-        self.groups_map.values().collect()
-    }
-
-    pub(crate) fn default_group(&self) -> &Group {
+    pub(crate) fn get_default_group(&self) -> &Group {
         &self.default_group
     }
 
+    pub(crate) fn get_mut_default_group(&mut self) -> &mut Group {
+        &mut self.default_group
+    }
+
+    /// Returns the groups without the default group
+    pub(crate) fn groups(&self) -> Vec<&Group> {
+        self.groups_map.values().collect()
+    }
+
+    pub(crate) fn get_mut_group(&mut self, group_id: &str) -> Option<&mut Group> {
+        self.groups_map.get_mut(group_id)
+    }
+
+    // Returns the index and group specified by the group_id
+    pub(crate) fn get_group(&self, group_id: &str) -> Option<(usize, &Group)> {
+        match (self.groups_map.get_index_of(group_id), self.groups_map.get(group_id)) {
+            (Some(index), Some(group)) => Some((index, group)),
+            _ => None,
+        }
+    }
+
     /// Iterate mut the groups. The default group will be the last one that get mutated.
-    pub(crate) fn iter_mut_groups(&mut self, mut each: impl FnMut(&mut Group)) {
+    pub(crate) fn iter_mut_all_groups(&mut self, mut each: impl FnMut(&mut Group)) {
         self.groups_map.iter_mut().for_each(|(_, group)| {
             each(group);
         });
@@ -253,22 +269,6 @@ where
         Ok(())
     }
 
-    pub(crate) fn get_mut_default_group(&mut self) -> &mut Group {
-        &mut self.default_group
-    }
-
-    pub(crate) fn get_mut_group(&mut self, group_id: &str) -> Option<&mut Group> {
-        self.groups_map.get_mut(group_id)
-    }
-
-    // Returns the index and group specified by the group_id
-    pub(crate) fn get_group(&self, group_id: &str) -> Option<(usize, &Group)> {
-        match (self.groups_map.get_index_of(group_id), self.groups_map.get(group_id)) {
-            (Some(index), Some(group)) => Some((index, group)),
-            _ => None,
-        }
-    }
-
     pub fn save_configuration(&self) -> FlowyResult<()> {
         let configuration = (&*self.configuration).clone();
         let writer = self.writer.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 7bdbb57368..5ea8639c92 100644
--- a/frontend/rust-lib/flowy-grid/src/services/group/controller.rs
+++ b/frontend/rust-lib/flowy-grid/src/services/group/controller.rs
@@ -183,11 +183,11 @@ where
 
     fn groups(&self) -> Vec<Group> {
         if self.use_default_group() {
-            let mut groups: Vec<Group> = self.group_ctx.concrete_groups().into_iter().cloned().collect();
-            groups.push(self.group_ctx.default_group().clone());
+            let mut groups: Vec<Group> = self.group_ctx.groups().into_iter().cloned().collect();
+            groups.push(self.group_ctx.get_default_group().clone());
             groups
         } else {
-            self.group_ctx.concrete_groups().into_iter().cloned().collect()
+            self.group_ctx.groups().into_iter().cloned().collect()
         }
     }
 
@@ -208,7 +208,7 @@ where
                 let mut grouped_rows: Vec<GroupedRow> = vec![];
                 let cell_bytes = decode_any_cell_data(cell_rev.data, field_rev);
                 let cell_data = cell_bytes.parser::<P>()?;
-                for group in self.group_ctx.concrete_groups() {
+                for group in self.group_ctx.groups() {
                     if self.can_group(&group.filter_content, &cell_data) {
                         grouped_rows.push(GroupedRow {
                             row: row_rev.into(),
@@ -264,12 +264,17 @@ where
         row_rev: &RowRevision,
         field_rev: &FieldRevision,
     ) -> FlowyResult<Vec<GroupChangesetPB>> {
+        // if the cell_rev is none, then the row must be crated from 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);
             let cell_data = cell_bytes.parser::<P>()?;
             Ok(self.remove_row_if_match(row_rev, &cell_data))
         } else {
-            Ok(vec![])
+            let group = self.group_ctx.get_default_group();
+            Ok(vec![GroupChangesetPB::delete(
+                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 62f21d708b..a15b0cc62b 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
@@ -41,7 +41,7 @@ impl GroupAction for CheckboxGroupController {
 
     fn add_row_if_match(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType) -> Vec<GroupChangesetPB> {
         let mut changesets = vec![];
-        self.group_ctx.iter_mut_groups(|group| {
+        self.group_ctx.iter_mut_all_groups(|group| {
             let mut changeset = GroupChangesetPB::new(group.id.clone());
             let is_contained = group.contains_row(&row_rev.id);
             if group.id == CHECK && cell_data.is_check() {
@@ -63,7 +63,7 @@ impl GroupAction for CheckboxGroupController {
 
     fn remove_row_if_match(&mut self, row_rev: &RowRevision, _cell_data: &Self::CellDataType) -> Vec<GroupChangesetPB> {
         let mut changesets = vec![];
-        self.group_ctx.iter_mut_groups(|group| {
+        self.group_ctx.iter_mut_all_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());
@@ -79,7 +79,7 @@ impl GroupAction for CheckboxGroupController {
 
     fn move_row(&mut self, _cell_data: &Self::CellDataType, mut context: MoveGroupRowContext) -> Vec<GroupChangesetPB> {
         let mut group_changeset = vec![];
-        self.group_ctx.iter_mut_groups(|group| {
+        self.group_ctx.iter_mut_all_groups(|group| {
             if let Some(changeset) = move_group_row(group, &mut context) {
                 group_changeset.push(changeset);
             }
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 8d18fa2a83..4905c6eaa7 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
@@ -28,7 +28,7 @@ impl GroupAction for MultiSelectGroupController {
 
     fn add_row_if_match(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType) -> Vec<GroupChangesetPB> {
         let mut changesets = vec![];
-        self.group_ctx.iter_mut_groups(|group| {
+        self.group_ctx.iter_mut_all_groups(|group| {
             if let Some(changeset) = add_select_option_row(group, cell_data, row_rev) {
                 changesets.push(changeset);
             }
@@ -38,7 +38,7 @@ impl GroupAction for MultiSelectGroupController {
 
     fn remove_row_if_match(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType) -> Vec<GroupChangesetPB> {
         let mut changesets = vec![];
-        self.group_ctx.iter_mut_groups(|group| {
+        self.group_ctx.iter_mut_all_groups(|group| {
             if let Some(changeset) = remove_select_option_row(group, cell_data, row_rev) {
                 changesets.push(changeset);
             }
@@ -48,7 +48,7 @@ impl GroupAction for MultiSelectGroupController {
 
     fn move_row(&mut self, _cell_data: &Self::CellDataType, mut context: MoveGroupRowContext) -> Vec<GroupChangesetPB> {
         let mut group_changeset = vec![];
-        self.group_ctx.iter_mut_groups(|group| {
+        self.group_ctx.iter_mut_all_groups(|group| {
             if let Some(changeset) = move_group_row(group, &mut context) {
                 group_changeset.push(changeset);
             }
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 25da9eec17..0c86166520 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
@@ -28,7 +28,7 @@ impl GroupAction for SingleSelectGroupController {
 
     fn add_row_if_match(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType) -> Vec<GroupChangesetPB> {
         let mut changesets = vec![];
-        self.group_ctx.iter_mut_groups(|group| {
+        self.group_ctx.iter_mut_all_groups(|group| {
             if let Some(changeset) = add_select_option_row(group, cell_data, row_rev) {
                 changesets.push(changeset);
             }
@@ -38,7 +38,7 @@ impl GroupAction for SingleSelectGroupController {
 
     fn remove_row_if_match(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType) -> Vec<GroupChangesetPB> {
         let mut changesets = vec![];
-        self.group_ctx.iter_mut_groups(|group| {
+        self.group_ctx.iter_mut_all_groups(|group| {
             if let Some(changeset) = remove_select_option_row(group, cell_data, row_rev) {
                 changesets.push(changeset);
             }
@@ -48,7 +48,7 @@ impl GroupAction for SingleSelectGroupController {
 
     fn move_row(&mut self, _cell_data: &Self::CellDataType, mut context: MoveGroupRowContext) -> Vec<GroupChangesetPB> {
         let mut group_changeset = vec![];
-        self.group_ctx.iter_mut_groups(|group| {
+        self.group_ctx.iter_mut_all_groups(|group| {
             if let Some(changeset) = move_group_row(group, &mut context) {
                 group_changeset.push(changeset);
             }
diff --git a/shared-lib/flowy-sync/src/client_grid/view_revision_pad.rs b/shared-lib/flowy-sync/src/client_grid/view_revision_pad.rs
index 9c0d8b4d1b..652c6d6867 100644
--- a/shared-lib/flowy-sync/src/client_grid/view_revision_pad.rs
+++ b/shared-lib/flowy-sync/src/client_grid/view_revision_pad.rs
@@ -32,7 +32,6 @@ impl GridViewRevisionPad {
         Self { view, delta }
     }
 
-
     pub fn from_delta(view_id: &str, delta: Delta) -> CollaborateResult<Self> {
         if delta.is_empty() {
             return Ok(GridViewRevisionPad::new(view_id.to_owned(), view_id.to_owned()));
@@ -49,15 +48,9 @@ impl GridViewRevisionPad {
         })
     }
 
-<<<<<<< HEAD
-    pub fn from_revisions(_grid_id: &str, revisions: Vec<Revision>) -> CollaborateResult<Self> {
-        let delta: Delta = make_text_delta_from_revisions(revisions)?;
-        Self::from_delta(delta)
-=======
     pub fn from_revisions(view_id: &str, revisions: Vec<Revision>) -> CollaborateResult<Self> {
-        let delta: TextDelta = make_text_delta_from_revisions(revisions)?;
+        let delta: Delta = make_text_delta_from_revisions(revisions)?;
         Self::from_delta(view_id, delta)
->>>>>>> 01dbc68d4 (chore: fix open application error when upgrade to 0.0.5.1)
     }
 
     pub fn get_groups_by_field_revs(&self, field_revs: &[Arc<FieldRevision>]) -> Option<GroupConfigurationsByFieldId> {