Procházet zdrojové kódy

chore: save multi type option data

appflowy před 3 roky
rodič
revize
915d71991a

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

@@ -1,5 +1,5 @@
 use crate::manager::GridManager;
-use crate::services::field::{type_option_builder_from_json_str, SelectOption};
+use crate::services::field::{default_type_option_builder_from_type, type_option_builder_from_json_str, SelectOption};
 use crate::services::grid_editor::ClientGridEditor;
 use flowy_error::{FlowyError, FlowyResult};
 use flowy_grid_data_model::entities::*;
@@ -85,7 +85,19 @@ pub(crate) async fn switch_to_field_handler(
 ) -> DataResult<EditFieldContext, FlowyError> {
     let params: EditFieldParams = data.into_inner().try_into()?;
     let editor = manager.get_grid_editor(&params.grid_id)?;
-    let edit_context = editor.switch_to_field_type(&params.field_id, params.field_type).await?;
+    editor
+        .switch_to_field_type(&params.field_id, &params.field_type)
+        .await?;
+
+    let field_meta = editor.get_field(&params.field_id).await?;
+    let edit_context = make_field_edit_context(
+        &params.grid_id,
+        Some(params.field_id),
+        params.field_type,
+        editor,
+        field_meta,
+    )
+    .await?;
     data_result(edit_context)
 }
 
@@ -115,31 +127,46 @@ pub(crate) async fn get_field_context_handler(
 ) -> DataResult<EditFieldContext, FlowyError> {
     let params = data.into_inner();
     let editor = manager.get_grid_editor(&params.grid_id)?;
-    let mut field_meta = get_or_create_field_meta(&params, editor).await?;
-    let s = field_meta.get_type_option_str().unwrap();
+    let edit_context =
+        make_field_edit_context(&params.grid_id, params.field_id, params.field_type, editor, None).await?;
+
+    data_result(edit_context)
+}
+
+async fn make_field_edit_context(
+    grid_id: &str,
+    field_id: Option<String>,
+    field_type: FieldType,
+    editor: Arc<ClientGridEditor>,
+    field_meta: Option<FieldMeta>,
+) -> FlowyResult<EditFieldContext> {
+    let field_meta = field_meta.unwrap_or(get_or_create_field_meta(field_id, &field_type, editor).await?);
+    let s = field_meta
+        .get_type_option_str()
+        .unwrap_or_else(|| default_type_option_builder_from_type(&field_type).entry().json_str());
+
     let builder = type_option_builder_from_json_str(&s, &field_meta.field_type);
     let type_option_data = builder.entry().protobuf_bytes().to_vec();
-
     let field: Field = field_meta.into();
-    let edit_context = EditFieldContext {
-        grid_id: params.grid_id,
+    Ok(EditFieldContext {
+        grid_id: grid_id.to_string(),
         grid_field: field,
         type_option_data,
-    };
-    data_result(edit_context)
+    })
 }
 
 async fn get_or_create_field_meta(
-    params: &GetEditFieldContextPayload,
+    field_id: Option<String>,
+    field_type: &FieldType,
     editor: Arc<ClientGridEditor>,
 ) -> FlowyResult<FieldMeta> {
-    if params.field_id.is_some() {
-        if let Some(field_meta) = editor.get_field(params.field_id.as_ref().unwrap()).await? {
+    if field_id.is_some() {
+        if let Some(field_meta) = editor.get_field(field_id.as_ref().unwrap()).await? {
             return Ok(field_meta);
         }
     }
 
-    editor.default_field_meta(&params.field_type).await
+    editor.create_next_field_meta(field_type).await
 }
 
 #[tracing::instrument(level = "debug", skip(data, manager), err)]

+ 14 - 6
frontend/rust-lib/flowy-grid/src/services/grid_editor.rs

@@ -1,7 +1,10 @@
 use crate::dart_notification::{send_dart_notification, GridNotification};
 use crate::manager::GridUser;
 use crate::services::block_meta_editor::GridBlockMetaEditorManager;
-use crate::services::field::{type_option_builder_from_bytes, FieldBuilder};
+use crate::services::field::{
+    default_type_option_builder_from_type, type_option_builder_from_bytes, type_option_builder_from_json_str,
+    FieldBuilder,
+};
 use crate::services::row::*;
 use bytes::Bytes;
 use flowy_error::{ErrorCode, FlowyError, FlowyResult};
@@ -85,7 +88,7 @@ impl ClientGridEditor {
         Ok(())
     }
 
-    pub async fn default_field_meta(&self, field_type: &FieldType) -> FlowyResult<FieldMeta> {
+    pub async fn create_next_field_meta(&self, field_type: &FieldType) -> FlowyResult<FieldMeta> {
         let name = format!("Property {}", self.pad.read().await.fields().len() + 1);
         let field_meta = FieldBuilder::from_field_type(field_type).name(&name).build();
         Ok(field_meta)
@@ -95,7 +98,7 @@ impl ClientGridEditor {
         self.pad.read().await.contain_field(field_id)
     }
 
-    pub async fn update_field(&self, mut params: FieldChangesetParams) -> FlowyResult<()> {
+    pub async fn update_field(&self, params: FieldChangesetParams) -> FlowyResult<()> {
         let deserializer = match self.pad.read().await.get_field(&params.field_id) {
             None => return Err(ErrorCode::FieldDoesNotExist.into()),
             Some(field_meta) => TypeOptionChangesetDeserializer(field_meta.field_type.clone()),
@@ -112,10 +115,15 @@ impl ClientGridEditor {
         Ok(())
     }
 
-    pub async fn switch_to_field_type(&self, field_id: &str, field_type: FieldType) -> FlowyResult<EditFieldContext> {
-        let _ = self.modify(|grid| Ok(grid.delete_field(field_id)?)).await?;
+    pub async fn switch_to_field_type(&self, field_id: &str, field_type: &FieldType) -> FlowyResult<()> {
+        let type_option_json_builder =
+            |field_type: &FieldType| -> String { default_type_option_builder_from_type(field_type).entry().json_str() };
+
+        let _ = self
+            .modify(|grid| Ok(grid.switch_to_field(field_id, field_type.clone(), type_option_json_builder)?))
+            .await?;
         let _ = self.notify_did_update_fields().await?;
-        todo!()
+        Ok(())
     }
 
     pub async fn duplicate_field(&self, field_id: &str) -> FlowyResult<()> {

+ 33 - 1
shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs

@@ -3,7 +3,8 @@ use crate::errors::{internal_error, CollaborateError, CollaborateResult};
 use crate::util::{cal_diff, make_delta_from_revisions};
 use bytes::Bytes;
 use flowy_grid_data_model::entities::{
-    FieldChangesetParams, FieldMeta, FieldOrder, GridBlockMeta, GridBlockMetaChangeset, GridMeta, RepeatedFieldOrder,
+    FieldChangesetParams, FieldMeta, FieldOrder, FieldType, GridBlockMeta, GridBlockMetaChangeset, GridMeta,
+    RepeatedFieldOrder, TypeOptionDataEntry,
 };
 
 use lib_infra::uuid;
@@ -89,6 +90,37 @@ impl GridMetaPad {
         })
     }
 
+    pub fn switch_to_field<B>(
+        &mut self,
+        field_id: &str,
+        field_type: FieldType,
+        type_option_json_builder: B,
+    ) -> CollaborateResult<Option<GridChangeset>>
+    where
+        B: FnOnce(&FieldType) -> String,
+    {
+        self.modify_grid(|grid| {
+            //
+            match grid.fields.iter_mut().find(|field_meta| field_meta.id == field_id) {
+                None => {
+                    tracing::warn!("Can not find the field with id: {}", field_id);
+                    Ok(None)
+                }
+                Some(field_meta) => {
+                    if field_meta.get_type_option_str().is_none() {
+                        let type_option_json = type_option_json_builder(&field_type);
+                        field_meta
+                            .type_option_by_field_type_id
+                            .insert(&field_type, type_option_json);
+                    }
+
+                    field_meta.field_type = field_type;
+                    Ok(Some(()))
+                }
+            }
+        })
+    }
+
     pub fn update_field<T: TypeOptionDataDeserializer>(
         &mut self,
         changeset: FieldChangesetParams,