chore: add edit field type option helper

This commit is contained in:
appflowy 2022-09-02 09:49:26 +08:00
parent f192f89ebb
commit e75d8f22c8
27 changed files with 158 additions and 75 deletions

View File

@ -133,13 +133,13 @@ pub struct GroupViewChangesetPB {
#[pb(index = 2)]
pub inserted_groups: Vec<InsertedGroupPB>,
#[pb(index = 2)]
#[pb(index = 3)]
pub new_groups: Vec<GroupPB>,
#[pb(index = 3)]
#[pb(index = 4)]
pub deleted_groups: Vec<String>,
#[pb(index = 4)]
#[pb(index = 5)]
pub update_groups: Vec<GroupPB>,
}

View File

@ -203,12 +203,14 @@ pub(crate) async fn move_field_handler(
/// The FieldMeta contains multiple data, each of them belongs to a specific FieldType.
async fn get_type_option_data(field_rev: &FieldRevision, field_type: &FieldType) -> FlowyResult<Vec<u8>> {
let s = field_rev
.get_type_option_str(field_type)
.unwrap_or_else(|| default_type_option_builder_from_type(field_type).entry().json_str());
let s = field_rev.get_type_option_str(field_type).unwrap_or_else(|| {
default_type_option_builder_from_type(field_type)
.data_format()
.json_str()
});
let field_type: FieldType = field_rev.ty.into();
let builder = type_option_builder_from_json_str(&s, &field_type);
let type_option_data = builder.entry().protobuf_bytes().to_vec();
let type_option_data = builder.data_format().protobuf_bytes().to_vec();
Ok(type_option_data)
}
@ -337,7 +339,7 @@ pub(crate) async fn update_select_option_handler(
type_option.delete_option(option);
}
mut_field_rev.insert_type_option_entry(&*type_option);
mut_field_rev.insert_type_option(&*type_option);
let _ = editor.replace_field(field_rev).await?;
if let Some(cell_content_changeset) = cell_content_changeset {

View File

@ -30,7 +30,7 @@ macro_rules! impl_type_option {
($target: ident, $field_type:expr) => {
impl std::convert::From<&FieldRevision> for $target {
fn from(field_rev: &FieldRevision) -> $target {
match field_rev.get_type_option_entry::<$target>($field_type.into()) {
match field_rev.get_type_option::<$target>($field_type.into()) {
None => $target::default(),
Some(target) => target,
}
@ -39,7 +39,7 @@ macro_rules! impl_type_option {
impl std::convert::From<&std::sync::Arc<FieldRevision>> for $target {
fn from(field_rev: &std::sync::Arc<FieldRevision>) -> $target {
match field_rev.get_type_option_entry::<$target>($field_type.into()) {
match field_rev.get_type_option::<$target>($field_type.into()) {
None => $target::default(),
Some(target) => target,
}
@ -52,7 +52,7 @@ macro_rules! impl_type_option {
}
}
impl TypeOptionDataEntry for $target {
impl TypeOptionDataFormat for $target {
fn json_str(&self) -> String {
match serde_json::to_string(&self) {
Ok(s) => s,

View File

@ -101,25 +101,25 @@ pub fn try_decode_cell_data(
let field_type: FieldTypeRevision = t_field_type.into();
let data = match t_field_type {
FieldType::RichText => field_rev
.get_type_option_entry::<RichTextTypeOptionPB>(field_type)?
.get_type_option::<RichTextTypeOptionPB>(field_type)?
.decode_cell_data(cell_data.into(), s_field_type, field_rev),
FieldType::Number => field_rev
.get_type_option_entry::<NumberTypeOptionPB>(field_type)?
.get_type_option::<NumberTypeOptionPB>(field_type)?
.decode_cell_data(cell_data.into(), s_field_type, field_rev),
FieldType::DateTime => field_rev
.get_type_option_entry::<DateTypeOptionPB>(field_type)?
.get_type_option::<DateTypeOptionPB>(field_type)?
.decode_cell_data(cell_data.into(), s_field_type, field_rev),
FieldType::SingleSelect => field_rev
.get_type_option_entry::<SingleSelectTypeOptionPB>(field_type)?
.get_type_option::<SingleSelectTypeOptionPB>(field_type)?
.decode_cell_data(cell_data.into(), s_field_type, field_rev),
FieldType::MultiSelect => field_rev
.get_type_option_entry::<MultiSelectTypeOptionPB>(field_type)?
.get_type_option::<MultiSelectTypeOptionPB>(field_type)?
.decode_cell_data(cell_data.into(), s_field_type, field_rev),
FieldType::Checkbox => field_rev
.get_type_option_entry::<CheckboxTypeOptionPB>(field_type)?
.get_type_option::<CheckboxTypeOptionPB>(field_type)?
.decode_cell_data(cell_data.into(), s_field_type, field_rev),
FieldType::URL => field_rev
.get_type_option_entry::<URLTypeOptionPB>(field_type)?
.get_type_option::<URLTypeOptionPB>(field_type)?
.decode_cell_data(cell_data.into(), s_field_type, field_rev),
};
Some(data)

View File

@ -1,7 +1,7 @@
use crate::entities::{FieldPB, FieldType};
use crate::services::field::type_options::*;
use bytes::Bytes;
use flowy_grid_data_model::revision::{FieldRevision, TypeOptionDataEntry};
use flowy_grid_data_model::revision::{FieldRevision, TypeOptionDataFormat};
use indexmap::IndexMap;
pub struct FieldBuilder {
@ -78,14 +78,14 @@ impl FieldBuilder {
pub fn build(self) -> FieldRevision {
let mut field_rev = self.field_rev;
field_rev.insert_type_option_entry(self.type_option_builder.entry());
field_rev.insert_type_option(self.type_option_builder.data_format());
field_rev
}
}
pub trait TypeOptionBuilder {
fn field_type(&self) -> FieldType;
fn entry(&self) -> &dyn TypeOptionDataEntry;
fn data_format(&self) -> &dyn TypeOptionDataFormat;
}
pub fn default_type_option_builder_from_type(field_type: &FieldType) -> Box<dyn TypeOptionBuilder> {

View File

@ -0,0 +1,47 @@
use crate::entities::{FieldChangesetParams, FieldType};
use crate::services::field::{select_option_operation, SelectOptionPB};
use crate::services::grid_editor::GridRevisionEditor;
use flowy_error::FlowyResult;
use flowy_grid_data_model::revision::{FieldRevision, TypeOptionDataDeserializer, TypeOptionDataFormat};
use std::sync::Arc;
pub async fn edit_field<T>(
field_id: &str,
editor: Arc<GridRevisionEditor>,
action: impl FnOnce(&mut T) -> bool,
) -> FlowyResult<()>
where
T: TypeOptionDataDeserializer + TypeOptionDataFormat,
{
let get_type_option = async {
let field_rev = editor.get_field_rev(field_id).await?;
field_rev.get_type_option::<T>(field_rev.ty)
};
if let Some(mut type_option) = get_type_option.await {
if action(&mut type_option) {
let changeset = FieldChangesetParams { ..Default::default() };
let _ = editor.update_field(changeset).await?;
}
}
Ok(())
}
pub fn insert_single_select_option(field_rev: &mut FieldRevision, options: Vec<SelectOptionPB>) -> FlowyResult<()> {
if options.is_empty() {
return Ok(());
}
let mut type_option = select_option_operation(field_rev)?;
options.into_iter().for_each(|option| type_option.insert_option(option));
Ok(())
}
pub fn insert_multi_select_option(field_rev: &mut FieldRevision, options: Vec<SelectOptionPB>) -> FlowyResult<()> {
if options.is_empty() {
return Ok(());
}
let mut type_option = select_option_operation(field_rev)?;
options.into_iter().for_each(|option| type_option.insert_option(option));
Ok(())
}

View File

@ -1,5 +1,7 @@
mod field_builder;
mod field_operation;
pub(crate) mod type_options;
pub use field_builder::*;
pub use field_operation::*;
pub use type_options::*;

View File

@ -5,7 +5,7 @@ use crate::services::field::{BoxTypeOptionBuilder, CheckboxCellData, TypeOptionB
use bytes::Bytes;
use flowy_derive::ProtoBuf;
use flowy_error::{FlowyError, FlowyResult};
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry};
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataFormat};
use serde::{Deserialize, Serialize};
use std::str::FromStr;
@ -26,7 +26,7 @@ impl TypeOptionBuilder for CheckboxTypeOptionBuilder {
FieldType::Checkbox
}
fn entry(&self) -> &dyn TypeOptionDataEntry {
fn data_format(&self) -> &dyn TypeOptionDataFormat {
&self.0
}
}

View File

@ -9,7 +9,7 @@ use chrono::format::strftime::StrftimeItems;
use chrono::{NaiveDateTime, Timelike};
use flowy_derive::ProtoBuf;
use flowy_error::{ErrorCode, FlowyError, FlowyResult};
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry};
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataFormat};
use serde::{Deserialize, Serialize};
// Date
@ -189,7 +189,7 @@ impl TypeOptionBuilder for DateTypeOptionBuilder {
FieldType::DateTime
}
fn entry(&self) -> &dyn TypeOptionDataEntry {
fn data_format(&self) -> &dyn TypeOptionDataFormat {
&self.0
}
}

View File

@ -6,7 +6,7 @@ use crate::services::field::{BoxTypeOptionBuilder, NumberCellData, TypeOptionBui
use bytes::Bytes;
use flowy_derive::ProtoBuf;
use flowy_error::{FlowyError, FlowyResult};
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry};
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataFormat};
use rust_decimal::Decimal;
@ -45,7 +45,7 @@ impl TypeOptionBuilder for NumberTypeOptionBuilder {
FieldType::Number
}
fn entry(&self) -> &dyn TypeOptionDataEntry {
fn data_format(&self) -> &dyn TypeOptionDataFormat {
&self.0
}
}

View File

@ -9,7 +9,7 @@ use crate::services::field::{
use bytes::Bytes;
use flowy_derive::ProtoBuf;
use flowy_error::{FlowyError, FlowyResult};
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry};
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataFormat};
use serde::{Deserialize, Serialize};
// Multiple select
@ -108,7 +108,7 @@ impl TypeOptionBuilder for MultiSelectTypeOptionBuilder {
FieldType::MultiSelect
}
fn entry(&self) -> &dyn TypeOptionDataEntry {
fn data_format(&self) -> &dyn TypeOptionDataFormat {
&self.0
}
}

View File

@ -5,7 +5,7 @@ use bytes::Bytes;
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use flowy_error::{internal_error, ErrorCode, FlowyResult};
use flowy_grid_data_model::parser::NotEmptyStr;
use flowy_grid_data_model::revision::{FieldRevision, TypeOptionDataEntry};
use flowy_grid_data_model::revision::{FieldRevision, TypeOptionDataFormat};
use nanoid::nanoid;
use serde::{Deserialize, Serialize};
@ -75,7 +75,7 @@ pub fn make_selected_select_options(
}
}
pub trait SelectOptionOperation: TypeOptionDataEntry + Send + Sync {
pub trait SelectOptionOperation: TypeOptionDataFormat + Send + Sync {
fn insert_option(&mut self, new_option: SelectOptionPB) {
let options = self.mut_options();
if let Some(index) = options

View File

@ -9,7 +9,7 @@ use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
use bytes::Bytes;
use flowy_derive::ProtoBuf;
use flowy_error::{FlowyError, FlowyResult};
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry};
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataFormat};
use serde::{Deserialize, Serialize};
// Single select
@ -91,7 +91,7 @@ impl TypeOptionBuilder for SingleSelectTypeOptionBuilder {
FieldType::SingleSelect
}
fn entry(&self) -> &dyn TypeOptionDataEntry {
fn data_format(&self) -> &dyn TypeOptionDataFormat {
&self.0
}
}

View File

@ -8,7 +8,7 @@ use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
use bytes::Bytes;
use flowy_derive::ProtoBuf;
use flowy_error::{FlowyError, FlowyResult};
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry};
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataFormat};
use serde::{Deserialize, Serialize};
#[derive(Default)]
@ -21,7 +21,7 @@ impl TypeOptionBuilder for RichTextTypeOptionBuilder {
FieldType::RichText
}
fn entry(&self) -> &dyn TypeOptionDataEntry {
fn data_format(&self) -> &dyn TypeOptionDataFormat {
&self.0
}
}

View File

@ -6,7 +6,7 @@ use bytes::Bytes;
use fancy_regex::Regex;
use flowy_derive::ProtoBuf;
use flowy_error::{FlowyError, FlowyResult};
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry};
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataFormat};
use lazy_static::lazy_static;
use serde::{Deserialize, Serialize};
@ -20,7 +20,7 @@ impl TypeOptionBuilder for URLTypeOptionBuilder {
FieldType::URL
}
fn entry(&self) -> &dyn TypeOptionDataEntry {
fn data_format(&self) -> &dyn TypeOptionDataFormat {
&self.0
}
}

View File

@ -188,7 +188,7 @@ fn filter_cell(
FieldType::RichText => filter_cache.text_filter.get(&filter_id).and_then(|filter| {
Some(
field_rev
.get_type_option_entry::<RichTextTypeOptionPB>(field_type_rev)?
.get_type_option::<RichTextTypeOptionPB>(field_type_rev)?
.apply_filter(any_cell_data, filter.value())
.ok(),
)
@ -196,7 +196,7 @@ fn filter_cell(
FieldType::Number => filter_cache.number_filter.get(&filter_id).and_then(|filter| {
Some(
field_rev
.get_type_option_entry::<NumberTypeOptionPB>(field_type_rev)?
.get_type_option::<NumberTypeOptionPB>(field_type_rev)?
.apply_filter(any_cell_data, filter.value())
.ok(),
)
@ -204,7 +204,7 @@ fn filter_cell(
FieldType::DateTime => filter_cache.date_filter.get(&filter_id).and_then(|filter| {
Some(
field_rev
.get_type_option_entry::<DateTypeOptionPB>(field_type_rev)?
.get_type_option::<DateTypeOptionPB>(field_type_rev)?
.apply_filter(any_cell_data, filter.value())
.ok(),
)
@ -212,7 +212,7 @@ fn filter_cell(
FieldType::SingleSelect => filter_cache.select_option_filter.get(&filter_id).and_then(|filter| {
Some(
field_rev
.get_type_option_entry::<SingleSelectTypeOptionPB>(field_type_rev)?
.get_type_option::<SingleSelectTypeOptionPB>(field_type_rev)?
.apply_filter(any_cell_data, filter.value())
.ok(),
)
@ -220,7 +220,7 @@ fn filter_cell(
FieldType::MultiSelect => filter_cache.select_option_filter.get(&filter_id).and_then(|filter| {
Some(
field_rev
.get_type_option_entry::<MultiSelectTypeOptionPB>(field_type_rev)?
.get_type_option::<MultiSelectTypeOptionPB>(field_type_rev)?
.apply_filter(any_cell_data, filter.value())
.ok(),
)
@ -228,7 +228,7 @@ fn filter_cell(
FieldType::Checkbox => filter_cache.checkbox_filter.get(&filter_id).and_then(|filter| {
Some(
field_rev
.get_type_option_entry::<CheckboxTypeOptionPB>(field_type_rev)?
.get_type_option::<CheckboxTypeOptionPB>(field_type_rev)?
.apply_filter(any_cell_data, filter.value())
.ok(),
)
@ -236,7 +236,7 @@ fn filter_cell(
FieldType::URL => filter_cache.url_filter.get(&filter_id).and_then(|filter| {
Some(
field_rev
.get_type_option_entry::<URLTypeOptionPB>(field_type_rev)?
.get_type_option::<URLTypeOptionPB>(field_type_rev)?
.apply_filter(any_cell_data, filter.value())
.ok(),
)

View File

@ -179,6 +179,10 @@ impl GridRevisionEditor {
None => Err(ErrorCode::FieldDoesNotExist.into()),
Some(field_type) => {
let _ = self.update_field_rev(params, field_type).await?;
match self.view_manager.did_update_field(&field_id).await {
Ok(_) => {}
Err(e) => tracing::error!("View manager update field failed: {:?}", e),
}
let _ = self.notify_did_update_grid_field(&field_id).await?;
Ok(())
}
@ -225,7 +229,9 @@ impl GridRevisionEditor {
let type_option_json_builder = |field_type: &FieldTypeRevision| -> String {
let field_type: FieldType = field_type.into();
return default_type_option_builder_from_type(&field_type).entry().json_str();
return default_type_option_builder_from_type(&field_type)
.data_format()
.json_str();
};
let _ = self
@ -828,7 +834,7 @@ impl JsonDeserializer for TypeOptionJsonDeserializer {
fn deserialize(&self, type_option_data: Vec<u8>) -> CollaborateResult<String> {
// The type_option_data sent from Dart is serialized by protobuf.
let builder = type_option_builder_from_bytes(type_option_data, &self.0);
let json = builder.entry().json_str();
let json = builder.data_format().json_str();
tracing::trace!("Deserialize type option data to: {}", json);
Ok(json)
}

View File

@ -152,7 +152,7 @@ where
} = merge_groups(&self.configuration.groups, new_groups);
let deleted_group_ids = deleted_group_revs
.iter()
.into_iter()
.map(|group_rev| group_rev.id)
.collect::<Vec<String>>();
@ -165,7 +165,7 @@ where
is_changed = true;
}
for mut group_rev in &mut all_group_revs {
for group_rev in &mut all_group_revs {
match configuration
.groups
.iter()
@ -177,8 +177,7 @@ where
}
Some(pos) => {
let mut old_group = configuration.groups.remove(pos);
// Update the group configuration base on the GroupRevision
group_rev.visible = old_group.visible;
group_rev.update_with_other(&old_group);
// Take the GroupRevision if the name has changed
if is_group_changed(&group_rev, &old_group) {
@ -192,6 +191,7 @@ where
is_changed
})?;
// The len of the filter_content_map should equal to the len of the all_group_revs
debug_assert_eq!(filter_content_map.len(), all_group_revs.len());
all_group_revs.into_iter().for_each(|group_rev| {
if let Some(filter_content) = filter_content_map.get(&group_rev.id) {
@ -207,21 +207,20 @@ where
let new_groups = new_group_revs
.into_iter()
.map(|group_rev| {
if let Some(filter_content) = filter_content_map.get(&group_rev.id) {
let group = Group::new(
group_rev.id,
self.field_rev.id.clone(),
group_rev.name,
filter_content.clone(),
);
GroupPB::from(group)
}
.flat_map(|group_rev| {
let filter_content = filter_content_map.get(&group_rev.id)?;
let group = Group::new(
group_rev.id,
self.field_rev.id.clone(),
group_rev.name,
filter_content.clone(),
);
Some(GroupPB::from(group))
})
.collect();
let changeset = GroupViewChangesetPB {
view_id,
view_id: self.view_id.clone(),
new_groups,
deleted_groups: deleted_group_ids,
update_groups: vec![],

View File

@ -87,7 +87,7 @@ where
{
pub async fn new(field_rev: &Arc<FieldRevision>, mut configuration: GroupContext<C>) -> FlowyResult<Self> {
let field_type_rev = field_rev.ty;
let type_option = field_rev.get_type_option_entry::<T>(field_type_rev);
let type_option = field_rev.get_type_option::<T>(field_type_rev);
let groups = G::generate_groups(&field_rev.id, &configuration, &type_option);
let _ = configuration.init_group_revs(groups)?;
@ -274,7 +274,7 @@ where
fn did_update_field(&mut self, field_rev: &FieldRevision) -> FlowyResult<Option<GroupViewChangesetPB>> {
let field_type_rev = field_rev.ty;
let type_option = field_rev.get_type_option_entry::<T>(field_type_rev);
let type_option = field_rev.get_type_option::<T>(field_type_rev);
let groups = G::generate_groups(&field_rev.id, &self.configuration, &type_option);
let changeset = self.configuration.init_group_revs(groups)?;
Ok(changeset)

View File

@ -176,7 +176,7 @@ impl GridRowTest {
FieldType::Number => {
let field_rev = self.editor.get_field_rev(&cell_id.field_id).await.unwrap();
let number_type_option = field_rev
.get_type_option_entry::<NumberTypeOptionPB>(FieldType::Number.into())
.get_type_option::<NumberTypeOptionPB>(FieldType::Number.into())
.unwrap();
let cell_data = self
.editor

View File

@ -4,7 +4,7 @@ use crate::grid::field_test::util::*;
use flowy_grid::entities::FieldChangesetParams;
use flowy_grid::services::field::selection_type_option::SelectOptionPB;
use flowy_grid::services::field::SingleSelectTypeOptionPB;
use flowy_grid_data_model::revision::TypeOptionDataEntry;
use flowy_grid_data_model::revision::TypeOptionDataFormat;
#[tokio::test]
async fn grid_create_field() {
@ -86,7 +86,7 @@ async fn grid_update_field() {
let mut expected_field_rev = single_select_field.clone();
expected_field_rev.frozen = true;
expected_field_rev.width = 1000;
expected_field_rev.insert_type_option_entry(&single_select_type_option);
expected_field_rev.insert_type_option(&single_select_type_option);
let scripts = vec![
CreateField { params },

View File

@ -12,7 +12,7 @@ pub fn create_text_field(grid_id: &str) -> (InsertFieldParams, FieldRevision) {
let cloned_field_rev = field_rev.clone();
let type_option_data = field_rev
.get_type_option_entry::<RichTextTypeOptionPB>(field_rev.ty)
.get_type_option::<RichTextTypeOptionPB>(field_rev.ty)
.unwrap()
.protobuf_bytes()
.to_vec();
@ -45,7 +45,7 @@ pub fn create_single_select_field(grid_id: &str) -> (InsertFieldParams, FieldRev
let field_rev = FieldBuilder::new(single_select).name("Name").visibility(true).build();
let cloned_field_rev = field_rev.clone();
let type_option_data = field_rev
.get_type_option_entry::<SingleSelectTypeOptionPB>(field_rev.ty)
.get_type_option::<SingleSelectTypeOptionPB>(field_rev.ty)
.unwrap()
.protobuf_bytes()
.to_vec();

View File

@ -8,7 +8,7 @@ use flowy_grid::services::field::{
use flowy_grid::services::row::{decode_cell_data_from_type_option_cell_data, CreateRowMetaBuilder};
use flowy_grid_data_model::entities::{
CellChangeset, FieldChangesetParams, FieldType, GridBlockInfoChangeset, GridBlockMetaSnapshot, RowMetaChangeset,
TypeOptionDataEntry,
TypeOptionDataFormat,
};
#[tokio::test]

View File

@ -3,6 +3,7 @@ use flowy_grid::entities::{
CreateRowParams, FieldChangesetParams, FieldType, GridLayout, GroupPB, MoveGroupParams, MoveGroupRowParams, RowPB,
};
use flowy_grid::services::cell::{delete_select_option_cell, insert_select_option_cell};
use flowy_grid::services::field::{select_option_operation, SelectOptionOperation};
use flowy_grid_data_model::revision::{FieldRevision, RowChangeset};
use std::sync::Arc;
use std::time::Duration;
@ -212,6 +213,28 @@ impl GridGroupTest {
.clone();
return field;
}
pub async fn get_single_select_field(&self) -> Arc<FieldRevision> {
self.inner
.field_revs
.iter()
.find(|field_rev| {
let field_type: FieldType = field_rev.ty.into();
field_type.is_single_select()
})
.unwrap()
.clone()
}
pub async fn edit_single_select_type_option(&self, f: impl FnOnce(Box<dyn SelectOptionOperation>)) {
let single_select = self.get_single_select_field().await;
let mut field_rev = self.editor.get_field_rev(&single_select.id).await.unwrap();
let mut_field_rev = Arc::make_mut(&mut field_rev);
let mut type_option = select_option_operation(mut_field_rev)?;
f(type_option);
mut_field_rev.insert_type_option(&*type_option);
let _ = self.editor.replace_field(field_rev).await?;
}
}
impl std::ops::Deref for GridGroupTest {

View File

@ -5,7 +5,7 @@ use flowy_grid::services::row::CreateRowMetaPayload;
use flowy_grid_data_model::entities::{
BuildGridContext, CellChangeset, Field, FieldChangesetParams, FieldMeta, FieldOrder, FieldType,
GridBlockInfoChangeset, GridBlockMetaSnapshot, InsertFieldParams, RowMeta, RowMetaChangeset, RowOrder,
TypeOptionDataEntry,
TypeOptionDataFormat,
};
use flowy_revision::REVISION_WRITE_INTERVAL_IN_MILLIS;
use flowy_sync::client_grid::GridBuilder;

View File

@ -143,15 +143,15 @@ impl FieldRevision {
}
}
pub fn insert_type_option_entry<T>(&mut self, entry: &T)
pub fn insert_type_option<T>(&mut self, type_option: &T)
where
T: TypeOptionDataEntry + ?Sized,
T: TypeOptionDataFormat + ?Sized,
{
let id = self.ty.to_string();
self.type_options.insert(id, entry.json_str());
self.type_options.insert(id, type_option.json_str());
}
pub fn get_type_option_entry<T: TypeOptionDataDeserializer>(&self, field_type_rev: FieldTypeRevision) -> Option<T> {
pub fn get_type_option<T: TypeOptionDataDeserializer>(&self, field_type_rev: FieldTypeRevision) -> Option<T> {
let id = field_type_rev.to_string();
// TODO: cache the deserialized type option
self.type_options.get(&id).map(|s| T::from_json_str(s))
@ -171,7 +171,7 @@ impl FieldRevision {
/// The macro [impl_type_option] will implement the [TypeOptionDataEntry] for the type that
/// supports the serde trait and the TryInto<Bytes> trait.
pub trait TypeOptionDataEntry {
pub trait TypeOptionDataFormat {
fn json_str(&self) -> String;
fn protobuf_bytes(&self) -> Bytes;
}

View File

@ -135,6 +135,10 @@ impl GroupRevision {
visible: true,
}
}
pub fn update_with_other(&mut self, other: &GroupRevision) {
self.visible = other.visible
}
}
#[derive(Default, Serialize, Deserialize)]