chore: save multi type option data

This commit is contained in:
appflowy 2022-04-01 22:46:01 +08:00
parent e0b969595c
commit 915d71991a
3 changed files with 90 additions and 23 deletions

View File

@ -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 builder = type_option_builder_from_json_str(&s, &field_meta.field_type);
let type_option_data = builder.entry().protobuf_bytes().to_vec();
let edit_context =
make_field_edit_context(&params.grid_id, params.field_id, params.field_type, editor, None).await?;
let field: Field = field_meta.into();
let edit_context = EditFieldContext {
grid_id: params.grid_id,
grid_field: field,
type_option_data,
};
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();
Ok(EditFieldContext {
grid_id: grid_id.to_string(),
grid_field: field,
type_option_data,
})
}
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)]

View File

@ -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<()> {

View File

@ -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,