Prechádzať zdrojové kódy

refactor: read cell data

appflowy 2 rokov pred
rodič
commit
b73c68c6f6
21 zmenil súbory, kde vykonal 108 pridanie a 132 odobranie
  1. 1 1
      frontend/app_flowy/lib/workspace/application/grid/block/block_listener.dart
  2. 1 1
      frontend/rust-lib/flowy-grid/src/dart_notification.rs
  3. 1 1
      frontend/rust-lib/flowy-grid/src/event_handler.rs
  4. 2 2
      frontend/rust-lib/flowy-grid/src/event_map.rs
  5. 11 17
      frontend/rust-lib/flowy-grid/src/manager.rs
  6. 8 7
      frontend/rust-lib/flowy-grid/src/services/block_manager.rs
  7. 5 5
      frontend/rust-lib/flowy-grid/src/services/block_revision_editor.rs
  8. 7 25
      frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs
  9. 2 2
      frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs
  10. 13 12
      frontend/rust-lib/flowy-grid/src/services/grid_editor.rs
  11. 6 15
      frontend/rust-lib/flowy-grid/src/services/row/cell_data_operation.rs
  12. 3 9
      frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs
  13. 1 4
      frontend/rust-lib/flowy-grid/tests/grid/field_util.rs
  14. 1 4
      frontend/rust-lib/flowy-grid/tests/grid/filter_test.rs
  15. 3 5
      frontend/rust-lib/flowy-grid/tests/grid/row_test.rs
  16. 3 2
      frontend/rust-lib/flowy-grid/tests/grid/row_util.rs
  17. 1 1
      shared-lib/flowy-grid-data-model/Cargo.toml
  18. 9 9
      shared-lib/flowy-grid-data-model/src/entities/grid_filter.rs
  19. 11 2
      shared-lib/flowy-grid-data-model/src/revision/grid_rev.rs
  20. 2 0
      shared-lib/flowy-grid-data-model/src/revision/grid_setting_rev.rs
  21. 17 8
      shared-lib/flowy-sync/src/client_grid/grid_revision_pad.rs

+ 1 - 1
frontend/app_flowy/lib/workspace/application/grid/block/block_listener.dart

@@ -70,7 +70,7 @@ class _GridBlockListener {
 
   void _handler(GridNotification ty, Either<Uint8List, FlowyError> result) {
     switch (ty) {
-      case GridNotification.DidUpdateGridRow:
+      case GridNotification.DidUpdateGridBlock:
         result.fold(
           (payload) => _rowsUpdateNotifier?.value = left([GridRowsChangeset.fromBuffer(payload)]),
           (error) => _rowsUpdateNotifier?.value = right(error),

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

@@ -6,7 +6,7 @@ const OBSERVABLE_CATEGORY: &str = "Grid";
 pub enum GridNotification {
     Unknown = 0,
     DidCreateBlock = 11,
-    DidUpdateGridRow = 20,
+    DidUpdateGridBlock = 20,
     DidUpdateGridField = 21,
     DidUpdateRow = 30,
     DidUpdateCell = 40,

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

@@ -9,7 +9,7 @@ use lib_dispatch::prelude::{data_result, AppData, Data, DataResult};
 use std::sync::Arc;
 
 #[tracing::instrument(level = "trace", skip(data, manager), err)]
-pub(crate) async fn get_grid_data_handler(
+pub(crate) async fn get_grid_handler(
     data: Data<GridId>,
     manager: AppData<Arc<GridManager>>,
 ) -> DataResult<Grid, FlowyError> {

+ 2 - 2
frontend/rust-lib/flowy-grid/src/event_map.rs

@@ -8,7 +8,7 @@ use strum_macros::Display;
 pub fn create(grid_manager: Arc<GridManager>) -> Module {
     let mut module = Module::new().name(env!("CARGO_PKG_NAME")).data(grid_manager);
     module = module
-        .event(GridEvent::GetGridData, get_grid_data_handler)
+        .event(GridEvent::GetGrid, get_grid_handler)
         .event(GridEvent::GetGridBlocks, get_grid_blocks_handler)
         .event(GridEvent::GetGridSetting, get_grid_setting_handler)
         .event(GridEvent::UpdateGridSetting, update_grid_setting_handler)
@@ -46,7 +46,7 @@ pub fn create(grid_manager: Arc<GridManager>) -> Module {
 #[event_err = "FlowyError"]
 pub enum GridEvent {
     #[event(input = "GridId", output = "Grid")]
-    GetGridData = 0,
+    GetGrid = 0,
 
     #[event(input = "QueryGridBlocksPayload", output = "RepeatedGridBlock")]
     GetGridBlocks = 1,

+ 11 - 17
frontend/rust-lib/flowy-grid/src/manager.rs

@@ -156,23 +156,8 @@ pub async fn make_grid_view_data(
     grid_manager: Arc<GridManager>,
     build_context: BuildGridContext,
 ) -> FlowyResult<Bytes> {
-    let grid_rev = GridRevision {
-        grid_id: view_id.to_string(),
-        fields: build_context.field_revs,
-        blocks: build_context.blocks,
-        setting: GridSettingRevision::default(),
-    };
-
-    // Create grid
-    let grid_meta_delta = make_grid_delta(&grid_rev);
-    let grid_delta_data = grid_meta_delta.to_delta_bytes();
-    let repeated_revision: RepeatedRevision =
-        Revision::initial_revision(user_id, view_id, grid_delta_data.clone()).into();
-    let _ = grid_manager.create_grid(view_id, repeated_revision).await?;
-
-    for block_meta_data in build_context.blocks_meta_data {
-        let block_id = block_meta_data.block_id.clone();
-
+    for block_meta_data in &build_context.blocks_meta_data {
+        let block_id = &block_meta_data.block_id;
         // Indexing the block's rows
         block_meta_data.rows.iter().for_each(|row| {
             let _ = grid_manager.block_index_cache.insert(&row.block_id, &row.id);
@@ -188,5 +173,14 @@ pub async fn make_grid_view_data(
             .await?;
     }
 
+    let grid_rev = GridRevision::from_build_context(view_id, build_context);
+
+    // Create grid
+    let grid_meta_delta = make_grid_delta(&grid_rev);
+    let grid_delta_data = grid_meta_delta.to_delta_bytes();
+    let repeated_revision: RepeatedRevision =
+        Revision::initial_revision(user_id, view_id, grid_delta_data.clone()).into();
+    let _ = grid_manager.create_grid(view_id, repeated_revision).await?;
+
     Ok(grid_delta_data)
 }

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

@@ -19,6 +19,7 @@ use std::sync::Arc;
 
 type BlockId = String;
 pub(crate) struct GridBlockManager {
+    #[allow(dead_code)]
     grid_id: String,
     user: Arc<dyn GridUser>,
     persistence: Arc<BlockIndexCache>,
@@ -29,10 +30,10 @@ impl GridBlockManager {
     pub(crate) async fn new(
         grid_id: &str,
         user: &Arc<dyn GridUser>,
-        blocks: Vec<GridBlockRevision>,
+        block_revs: Vec<Arc<GridBlockRevision>>,
         persistence: Arc<BlockIndexCache>,
     ) -> FlowyResult<Self> {
-        let editor_map = make_block_meta_editor_map(user, blocks).await?;
+        let editor_map = make_block_meta_editor_map(user, block_revs).await?;
         let user = user.clone();
         let grid_id = grid_id.to_owned();
         let manager = Self {
@@ -246,7 +247,7 @@ impl GridBlockManager {
     }
 
     async fn notify_did_update_block(&self, block_id: &str, changeset: GridRowsChangeset) -> FlowyResult<()> {
-        send_dart_notification(block_id, GridNotification::DidUpdateGridRow)
+        send_dart_notification(block_id, GridNotification::DidUpdateGridBlock)
             .payload(changeset)
             .send();
         Ok(())
@@ -261,12 +262,12 @@ impl GridBlockManager {
 
 async fn make_block_meta_editor_map(
     user: &Arc<dyn GridUser>,
-    blocks: Vec<GridBlockRevision>,
+    block_revs: Vec<Arc<GridBlockRevision>>,
 ) -> FlowyResult<DashMap<String, Arc<GridBlockRevisionEditor>>> {
     let editor_map = DashMap::new();
-    for block in blocks {
-        let editor = make_block_meta_editor(user, &block.block_id).await?;
-        editor_map.insert(block.block_id, Arc::new(editor));
+    for block_rev in block_revs {
+        let editor = make_block_meta_editor(user, &block_rev.block_id).await?;
+        editor_map.insert(block_rev.block_id.clone(), Arc::new(editor));
     }
 
     Ok(editor_map)

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

@@ -42,28 +42,28 @@ impl GridBlockRevisionEditor {
         })
     }
 
-    pub async fn duplicate_block_meta_data(&self, duplicated_block_id: &str) -> GridBlockRevisionData {
+    pub async fn duplicate_block(&self, duplicated_block_id: &str) -> GridBlockRevisionData {
         self.pad.read().await.duplicate_data(duplicated_block_id).await
     }
 
-    /// return current number of rows and the inserted index. The inserted index will be None if the start_row_id is None
+    /// Create a row after the the with prev_row_id. If prev_row_id is None, the row will be appended to the list
     pub(crate) async fn create_row(
         &self,
         row: RowRevision,
-        start_row_id: Option<String>,
+        prev_row_id: Option<String>,
     ) -> FlowyResult<(i32, Option<i32>)> {
         let mut row_count = 0;
         let mut row_index = None;
         let _ = self
             .modify(|block_pad| {
-                if let Some(start_row_id) = start_row_id.as_ref() {
+                if let Some(start_row_id) = prev_row_id.as_ref() {
                     match block_pad.index_of_row(start_row_id) {
                         None => {}
                         Some(index) => row_index = Some(index + 1),
                     }
                 }
 
-                let change = block_pad.add_row_rev(row, start_row_id)?;
+                let change = block_pad.add_row_rev(row, prev_row_id)?;
                 row_count = block_pad.number_of_rows();
 
                 if row_index.is_none() {

+ 7 - 25
frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs

@@ -93,7 +93,7 @@ mod tests {
     use crate::services::field::type_options::checkbox_type_option::{NO, YES};
 
     use crate::services::field::FieldBuilder;
-    use crate::services::row::{apply_cell_data_changeset, decode_cell_data_from_type_option_cell_data};
+    use crate::services::row::{apply_cell_data_changeset, decode_cell_data};
 
     use flowy_grid_data_model::entities::FieldType;
 
@@ -101,39 +101,21 @@ mod tests {
     fn checkout_box_description_test() {
         let field_rev = FieldBuilder::from_field_type(&FieldType::Checkbox).build();
         let data = apply_cell_data_changeset("true", None, &field_rev).unwrap();
-        assert_eq!(
-            decode_cell_data_from_type_option_cell_data(data, &field_rev, &field_rev.field_type).to_string(),
-            YES
-        );
+        assert_eq!(decode_cell_data(data, &field_rev).to_string(), YES);
 
         let data = apply_cell_data_changeset("1", None, &field_rev).unwrap();
-        assert_eq!(
-            decode_cell_data_from_type_option_cell_data(data, &field_rev, &field_rev.field_type).to_string(),
-            YES
-        );
+        assert_eq!(decode_cell_data(data, &field_rev,).to_string(), YES);
 
         let data = apply_cell_data_changeset("yes", None, &field_rev).unwrap();
-        assert_eq!(
-            decode_cell_data_from_type_option_cell_data(data, &field_rev, &field_rev.field_type).to_string(),
-            YES
-        );
+        assert_eq!(decode_cell_data(data, &field_rev,).to_string(), YES);
 
         let data = apply_cell_data_changeset("false", None, &field_rev).unwrap();
-        assert_eq!(
-            decode_cell_data_from_type_option_cell_data(data, &field_rev, &field_rev.field_type).to_string(),
-            NO
-        );
+        assert_eq!(decode_cell_data(data, &field_rev,).to_string(), NO);
 
         let data = apply_cell_data_changeset("no", None, &field_rev).unwrap();
-        assert_eq!(
-            decode_cell_data_from_type_option_cell_data(data, &field_rev, &field_rev.field_type).to_string(),
-            NO
-        );
+        assert_eq!(decode_cell_data(data, &field_rev,).to_string(), NO);
 
         let data = apply_cell_data_changeset("12", None, &field_rev).unwrap();
-        assert_eq!(
-            decode_cell_data_from_type_option_cell_data(data, &field_rev, &field_rev.field_type).to_string(),
-            NO
-        );
+        assert_eq!(decode_cell_data(data, &field_rev,).to_string(), NO);
     }
 }

+ 2 - 2
frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs

@@ -1,6 +1,6 @@
 use crate::impl_type_option;
 use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
-use crate::services::row::{decode_cell_data, CellContentChangeset, CellDataOperation, DecodedCellData};
+use crate::services::row::{try_decode_cell_data, CellContentChangeset, CellDataOperation, DecodedCellData};
 use bytes::Bytes;
 use flowy_derive::ProtoBuf;
 use flowy_error::{FlowyError, FlowyResult};
@@ -45,7 +45,7 @@ impl CellDataOperation<String> for RichTextTypeOption {
             || decoded_field_type.is_multi_select()
             || decoded_field_type.is_number()
         {
-            decode_cell_data(encoded_data, decoded_field_type, decoded_field_type, field_rev)
+            try_decode_cell_data(encoded_data, field_rev, decoded_field_type, decoded_field_type)
         } else {
             let cell_data = encoded_data.into();
             Ok(DecodedCellData::new(cell_data))

+ 13 - 12
frontend/rust-lib/flowy-grid/src/services/grid_editor.rs

@@ -46,9 +46,9 @@ impl GridRevisionEditor {
         let grid_pad = rev_manager.load::<GridPadBuilder>(Some(cloud)).await?;
         let rev_manager = Arc::new(rev_manager);
         let grid_pad = Arc::new(RwLock::new(grid_pad));
-        let blocks = grid_pad.read().await.get_block_revs();
+        let block_revs = grid_pad.read().await.get_block_revs();
 
-        let block_meta_manager = Arc::new(GridBlockManager::new(grid_id, &user, blocks, persistence).await?);
+        let block_meta_manager = Arc::new(GridBlockManager::new(grid_id, &user, block_revs, persistence).await?);
         Ok(Arc::new(Self {
             grid_id: grid_id.to_owned(),
             user,
@@ -342,7 +342,10 @@ impl GridRevisionEditor {
     pub async fn get_cell(&self, params: &CellIdentifier) -> Option<Cell> {
         let field_rev = self.get_field_rev(&params.field_id).await?;
         let row_rev = self.block_manager.get_row_rev(&params.row_id).await.ok()??;
-        make_cell(&params.field_id, &field_rev, &row_rev)
+
+        let cell_rev = row_rev.cells.get(&params.field_id)?.clone();
+        let data = decode_cell_data(cell_rev.data, &field_rev).data;
+        Some(Cell::new(&params.field_id, data))
     }
 
     pub async fn get_cell_rev(&self, row_id: &str, field_id: &str) -> FlowyResult<Option<CellRevision>> {
@@ -405,7 +408,7 @@ impl GridRevisionEditor {
         make_grid_blocks(block_ids, block_snapshots)
     }
 
-    pub async fn get_block_metas(&self) -> FlowyResult<Vec<GridBlockRevision>> {
+    pub async fn get_block_metas(&self) -> FlowyResult<Vec<Arc<GridBlockRevision>>> {
         let grid_blocks = self.grid_pad.read().await.get_block_revs();
         Ok(grid_blocks)
     }
@@ -422,10 +425,10 @@ impl GridRevisionEditor {
         let pad_read_guard = self.grid_pad.read().await;
         let field_orders = pad_read_guard.get_field_orders();
         let mut block_orders = vec![];
-        for block_order in pad_read_guard.get_block_revs() {
-            let row_orders = self.block_manager.get_row_orders(&block_order.block_id).await?;
+        for block_rev in pad_read_guard.get_block_revs() {
+            let row_orders = self.block_manager.get_row_orders(&block_rev.block_id).await?;
             let block_order = GridBlock {
-                id: block_order.block_id,
+                id: block_rev.block_id.clone(),
                 row_orders,
             };
             block_orders.push(block_order);
@@ -467,8 +470,8 @@ impl GridRevisionEditor {
                 .read()
                 .await
                 .get_block_revs()
-                .into_iter()
-                .map(|block_meta| block_meta.block_id)
+                .iter()
+                .map(|block_rev| block_rev.block_id.clone())
                 .collect::<Vec<String>>(),
             Some(block_ids) => block_ids,
         };
@@ -526,9 +529,7 @@ impl GridRevisionEditor {
                 let duplicated_block_id = &duplicated_blocks[index].block_id;
 
                 tracing::trace!("Duplicate block:{} meta data", duplicated_block_id);
-                let duplicated_block_meta_data = grid_block_meta_editor
-                    .duplicate_block_meta_data(duplicated_block_id)
-                    .await;
+                let duplicated_block_meta_data = grid_block_meta_editor.duplicate_block(duplicated_block_id).await;
                 blocks_meta_data.push(duplicated_block_meta_data);
             }
         } else {

+ 6 - 15
frontend/rust-lib/flowy-grid/src/services/row/cell_data_operation.rs

@@ -55,12 +55,6 @@ pub struct TypeOptionCellData {
     pub field_type: FieldType,
 }
 
-impl TypeOptionCellData {
-    pub fn split(self) -> (String, FieldType) {
-        (self.data, self.field_type)
-    }
-}
-
 impl std::str::FromStr for TypeOptionCellData {
     type Err = FlowyError;
 
@@ -139,14 +133,11 @@ pub fn apply_cell_data_changeset<T: Into<CellContentChangeset>>(
     Ok(TypeOptionCellData::new(s, field_rev.field_type.clone()).json())
 }
 
-pub fn decode_cell_data_from_type_option_cell_data<T: TryInto<TypeOptionCellData>>(
-    data: T,
-    field_rev: &FieldRevision,
-    field_type: &FieldType,
-) -> DecodedCellData {
+pub fn decode_cell_data<T: TryInto<TypeOptionCellData>>(data: T, field_rev: &FieldRevision) -> DecodedCellData {
     if let Ok(type_option_cell_data) = data.try_into() {
-        let (encoded_data, s_field_type) = type_option_cell_data.split();
-        match decode_cell_data(encoded_data, &s_field_type, field_type, field_rev) {
+        let TypeOptionCellData { data, field_type } = type_option_cell_data;
+        let to_field_type = &field_rev.field_type;
+        match try_decode_cell_data(data, &field_rev, &field_type, to_field_type) {
             Ok(cell_data) => cell_data,
             Err(e) => {
                 tracing::error!("Decode cell data failed, {:?}", e);
@@ -159,11 +150,11 @@ pub fn decode_cell_data_from_type_option_cell_data<T: TryInto<TypeOptionCellData
     }
 }
 
-pub fn decode_cell_data<T: Into<String>>(
+pub fn try_decode_cell_data<T: Into<String>>(
     encoded_data: T,
+    field_rev: &FieldRevision,
     s_field_type: &FieldType,
     t_field_type: &FieldType,
-    field_rev: &FieldRevision,
 ) -> FlowyResult<DecodedCellData> {
     let encoded_data = encoded_data.into();
     let get_cell_data = || {

+ 3 - 9
frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs

@@ -1,4 +1,4 @@
-use crate::services::row::decode_cell_data_from_type_option_cell_data;
+use crate::services::row::decode_cell_data;
 use flowy_error::FlowyResult;
 use flowy_grid_data_model::entities::{Cell, GridBlock, RepeatedGridBlock, Row, RowOrder};
 use flowy_grid_data_model::revision::{CellRevision, FieldRevision, RowRevision};
@@ -24,23 +24,17 @@ pub(crate) fn block_from_row_orders(row_orders: Vec<RowOrder>) -> Vec<GridBlock>
 }
 
 #[inline(always)]
-pub fn make_cell_by_field_id(
+fn make_cell_by_field_id(
     field_map: &HashMap<&String, &FieldRevision>,
     field_id: String,
     cell_rev: CellRevision,
 ) -> Option<(String, Cell)> {
     let field_rev = field_map.get(&field_id)?;
-    let data = decode_cell_data_from_type_option_cell_data(cell_rev.data, field_rev, &field_rev.field_type).data;
+    let data = decode_cell_data(cell_rev.data, field_rev).data;
     let cell = Cell::new(&field_id, data);
     Some((field_id, cell))
 }
 
-pub fn make_cell(field_id: &str, field_rev: &FieldRevision, row_rev: &RowRevision) -> Option<Cell> {
-    let cell_rev = row_rev.cells.get(field_id)?.clone();
-    let data = decode_cell_data_from_type_option_cell_data(cell_rev.data, field_rev, &field_rev.field_type).data;
-    Some(Cell::new(field_id, data))
-}
-
 pub(crate) fn make_row_orders_from_row_revs(row_revs: &[Arc<RowRevision>]) -> Vec<RowOrder> {
     row_revs.iter().map(RowOrder::from).collect::<Vec<_>>()
 }

+ 1 - 4
frontend/rust-lib/flowy-grid/tests/grid/field_util.rs

@@ -1,10 +1,7 @@
 use flowy_grid::services::field::*;
-use flowy_grid::services::grid_editor::{GridPadBuilder, GridRevisionEditor};
-use flowy_grid::services::row::CreateRowRevisionPayload;
-use flowy_grid::services::setting::GridSettingChangesetBuilder;
+
 use flowy_grid_data_model::entities::*;
 use flowy_grid_data_model::revision::*;
-use flowy_sync::client_grid::GridBuilder;
 
 pub fn create_text_field(grid_id: &str) -> (InsertFieldParams, FieldRevision) {
     let field_rev = FieldBuilder::new(RichTextTypeOptionBuilder::default())

+ 1 - 4
frontend/rust-lib/flowy-grid/tests/grid/filter_test.rs

@@ -1,9 +1,6 @@
 use crate::grid::script::EditorScript::*;
 use crate::grid::script::*;
-
-use flowy_grid_data_model::entities::{
-    CreateGridFilterParams, CreateGridFilterPayload, GridLayoutType, GridSettingChangesetParams, TextFilterCondition,
-};
+use flowy_grid_data_model::entities::{CreateGridFilterPayload, TextFilterCondition};
 
 #[tokio::test]
 async fn grid_filter_create_test() {

+ 3 - 5
frontend/rust-lib/flowy-grid/tests/grid/row_test.rs

@@ -6,11 +6,9 @@ use chrono::NaiveDateTime;
 use flowy_grid::services::field::{
     DateCellData, MultiSelectTypeOption, SingleSelectTypeOption, SELECTION_IDS_SEPARATOR,
 };
-use flowy_grid::services::row::{
-    decode_cell_data_from_type_option_cell_data, CreateRowRevisionBuilder, CreateRowRevisionPayload,
-};
+use flowy_grid::services::row::{decode_cell_data, CreateRowRevisionBuilder};
 use flowy_grid_data_model::entities::FieldType;
-use flowy_grid_data_model::revision::{FieldRevision, RowMetaChangeset};
+use flowy_grid_data_model::revision::RowMetaChangeset;
 
 #[tokio::test]
 async fn grid_create_row_count_test() {
@@ -139,7 +137,7 @@ async fn grid_row_add_date_cell_test() {
     let date_field = date_field.unwrap();
     let cell_data = context.cell_by_field_id.get(&date_field.id).unwrap().clone();
     assert_eq!(
-        decode_cell_data_from_type_option_cell_data(cell_data.data.clone(), &date_field, &date_field.field_type)
+        decode_cell_data(cell_data.data.clone(), &date_field)
             .parse::<DateCellData>()
             .unwrap()
             .date,

+ 3 - 2
frontend/rust-lib/flowy-grid/tests/grid/row_util.rs

@@ -53,12 +53,13 @@ impl<'a> GridRowTestBuilder<'a> {
         self
     }
 
-    pub fn field_rev_with_type(&self, field_type: &FieldType) -> &FieldRevision {
+    pub fn field_rev_with_type(&self, field_type: &FieldType) -> FieldRevision {
         self.test
             .field_revs
             .iter()
-            .find(|field_rev| field_rev.field_type == &field_type)
+            .find(|field_rev| &field_rev.field_type == field_type)
             .unwrap()
+            .clone()
     }
 
     pub fn build(self) -> CreateRowRevisionPayload {

+ 1 - 1
shared-lib/flowy-grid-data-model/Cargo.toml

@@ -11,7 +11,7 @@ protobuf = {version = "2.18.0"}
 bytes = "1.0"
 strum = "0.21"
 strum_macros = "0.21"
-serde = { version = "1.0", features = ["derive"] }
+serde = { version = "1.0", features = ["derive", "rc"] }
 serde_json = {version = "1.0"}
 serde_repr = "0.1"
 nanoid = "0.4.0"

+ 9 - 9
shared-lib/flowy-grid-data-model/src/entities/grid_filter.rs

@@ -125,9 +125,9 @@ pub enum TextFilterCondition {
     TextIsEmpty = 6,
     TextIsNotEmpty = 7,
 }
-impl std::convert::Into<i32> for TextFilterCondition {
-    fn into(self) -> i32 {
-        self as i32
+impl std::convert::From<TextFilterCondition> for i32 {
+    fn from(value: TextFilterCondition) -> Self {
+        value as i32
     }
 }
 
@@ -190,9 +190,9 @@ impl std::default::Default for NumberFilterCondition {
     }
 }
 
-impl std::convert::Into<i32> for NumberFilterCondition {
-    fn into(self) -> i32 {
-        self as i32
+impl std::convert::From<NumberFilterCondition> for i32 {
+    fn from(value: NumberFilterCondition) -> Self {
+        value as i32
     }
 }
 impl std::convert::TryFrom<u8> for NumberFilterCondition {
@@ -240,9 +240,9 @@ pub enum SelectOptionCondition {
     OptionIsNotEmpty = 3,
 }
 
-impl std::convert::Into<i32> for SelectOptionCondition {
-    fn into(self) -> i32 {
-        self as i32
+impl std::convert::From<SelectOptionCondition> for i32 {
+    fn from(value: SelectOptionCondition) -> Self {
+        value as i32
     }
 }
 

+ 11 - 2
shared-lib/flowy-grid-data-model/src/revision/grid_rev.rs

@@ -30,9 +30,9 @@ pub fn gen_field_id() -> String {
 pub struct GridRevision {
     pub grid_id: String,
     pub fields: Vec<FieldRevision>,
-    pub blocks: Vec<GridBlockRevision>,
+    pub blocks: Vec<Arc<GridBlockRevision>>,
 
-    #[serde(default, skip)]
+    #[serde(default)]
     pub setting: GridSettingRevision,
 }
 
@@ -45,6 +45,15 @@ impl GridRevision {
             setting: GridSettingRevision::default(),
         }
     }
+
+    pub fn from_build_context(grid_id: &str, context: BuildGridContext) -> Self {
+        Self {
+            grid_id: grid_id.to_owned(),
+            fields: context.field_revs,
+            blocks: context.blocks.into_iter().map(Arc::new).collect(),
+            setting: Default::default(),
+        }
+    }
 }
 
 #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]

+ 2 - 0
shared-lib/flowy-grid-data-model/src/revision/grid_setting_rev.rs

@@ -17,6 +17,8 @@ pub fn gen_grid_sort_id() -> String {
 
 #[derive(Debug, Clone, Serialize, Deserialize, Default, Eq, PartialEq)]
 pub struct GridSettingRevision {
+    pub layout: GridLayoutRevision,
+
     #[serde(with = "indexmap::serde_seq")]
     pub filter: IndexMap<GridLayoutRevision, Vec<GridFilterRevision>>,
 

+ 17 - 8
shared-lib/flowy-sync/src/client_grid/grid_revision_pad.rs

@@ -35,7 +35,7 @@ impl GridRevisionPad {
             .blocks
             .iter()
             .map(|block| {
-                let mut duplicated_block = block.clone();
+                let mut duplicated_block = (&*block.clone()).clone();
                 duplicated_block.block_id = gen_block_id();
                 duplicated_block
             })
@@ -288,7 +288,7 @@ impl GridRevisionPad {
                 Ok(None)
             } else {
                 match grid_meta.blocks.last() {
-                    None => grid_meta.blocks.push(block),
+                    None => grid_meta.blocks.push(Arc::new(block)),
                     Some(last_block) => {
                         if last_block.start_row_index > block.start_row_index
                             && last_block.len() > block.start_row_index
@@ -296,7 +296,7 @@ impl GridRevisionPad {
                             let msg = "GridBlock's start_row_index should be greater than the last_block's start_row_index and its len".to_string();
                             return Err(CollaborateError::internal().context(msg))
                         }
-                        grid_meta.blocks.push(block);
+                        grid_meta.blocks.push(Arc::new(block));
                     }
                 }
                 Ok(Some(()))
@@ -304,7 +304,7 @@ impl GridRevisionPad {
         })
     }
 
-    pub fn get_block_revs(&self) -> Vec<GridBlockRevision> {
+    pub fn get_block_revs(&self) -> Vec<Arc<GridBlockRevision>> {
         self.grid_rev.blocks.clone()
     }
 
@@ -362,7 +362,9 @@ impl GridRevisionPad {
             if let Some(delete_filter_id) = changeset.delete_filter {
                 match grid_rev.setting.filter.get_mut(&layout_rev) {
                     Some(filters) => filters.retain(|filter| filter.id != delete_filter_id),
-                    None => {}
+                    None => {
+                        tracing::warn!("Can't find the filter with {:?}", layout_rev);
+                    }
                 }
             }
             if let Some(params) = changeset.insert_group {
@@ -384,7 +386,9 @@ impl GridRevisionPad {
             if let Some(delete_group_id) = changeset.delete_group {
                 match grid_rev.setting.group.get_mut(&layout_rev) {
                     Some(groups) => groups.retain(|group| group.id != delete_group_id),
-                    None => {}
+                    None => {
+                        tracing::warn!("Can't find the group with {:?}", layout_rev);
+                    }
                 }
             }
             if let Some(sort) = changeset.insert_sort {
@@ -405,7 +409,9 @@ impl GridRevisionPad {
             if let Some(delete_sort_id) = changeset.delete_sort {
                 match grid_rev.setting.sort.get_mut(&layout_rev) {
                     Some(sorts) => sorts.retain(|sort| sort.id != delete_sort_id),
-                    None => {}
+                    None => {
+                        tracing::warn!("Can't find the sort with {:?}", layout_rev);
+                    }
                 }
             }
             Ok(is_changed)
@@ -459,7 +465,10 @@ impl GridRevisionPad {
                     tracing::warn!("[GridMetaPad]: Can't find any block with id: {}", block_id);
                     Ok(None)
                 }
-                Some(index) => f(&mut grid_rev.blocks[index]),
+                Some(index) => {
+                    let block_rev = Arc::make_mut(&mut grid_rev.blocks[index]);
+                    f(block_rev)
+                }
             },
         )
     }