fix: number cell format (#1623)

Co-authored-by: nathan <nathan@appflowy.io>
This commit is contained in:
Nathan.fooo 2022-12-31 08:06:10 +08:00 committed by GitHub
parent 5c1b084789
commit a2b5d6fa99
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 132 additions and 1001 deletions

View File

@ -229,11 +229,14 @@ pub(crate) async fn move_field_handler(
/// The [FieldRevision] contains multiple data, each of them belongs to a specific FieldType. /// The [FieldRevision] 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>> { 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(|| { let s = field_rev
default_type_option_builder_from_type(field_type) .get_type_option_str(field_type)
.serializer() .map(|value| value.to_owned())
.json_str() .unwrap_or_else(|| {
}); default_type_option_builder_from_type(field_type)
.serializer()
.json_str()
});
let field_type: FieldType = field_rev.ty.into(); let field_type: FieldType = field_rev.ty.into();
let builder = type_option_builder_from_json_str(&s, &field_type); let builder = type_option_builder_from_json_str(&s, &field_type);
let type_option_data = builder.serializer().protobuf_bytes().to_vec(); let type_option_data = builder.serializer().protobuf_bytes().to_vec();

View File

@ -41,7 +41,7 @@ pub trait CellDataChangeset: TypeOption {
&self, &self,
changeset: <Self as TypeOption>::CellChangeset, changeset: <Self as TypeOption>::CellChangeset,
type_cell_data: Option<TypeCellData>, type_cell_data: Option<TypeCellData>,
) -> FlowyResult<<Self as TypeOption>::CellData>; ) -> FlowyResult<(String, <Self as TypeOption>::CellData)>;
} }
/// changeset: It will be deserialized into specific data base on the FieldType. /// changeset: It will be deserialized into specific data base on the FieldType.
@ -65,13 +65,13 @@ pub fn apply_cell_data_changeset<C: ToCellChangesetString, T: AsRef<FieldRevisio
Err(_) => None, Err(_) => None,
}); });
let cell_data = match TypeOptionCellExt::new_with_cell_data_cache(field_rev, cell_data_cache) let cell_str = match TypeOptionCellExt::new_with_cell_data_cache(field_rev, cell_data_cache)
.get_type_option_cell_data_handler(&field_type) .get_type_option_cell_data_handler(&field_type)
{ {
None => "".to_string(), None => "".to_string(),
Some(handler) => handler.handle_cell_changeset(changeset, type_cell_data, field_rev)?, Some(handler) => handler.handle_cell_changeset(changeset, type_cell_data, field_rev)?,
}; };
Ok(TypeCellData::new(cell_data, field_type).to_json()) Ok(TypeCellData::new(cell_str, field_type).to_json())
} }
pub fn decode_type_cell_data<T: TryInto<TypeCellData, Error = FlowyError> + Debug>( pub fn decode_type_cell_data<T: TryInto<TypeCellData, Error = FlowyError> + Debug>(

View File

@ -82,11 +82,8 @@ impl std::convert::TryFrom<CellRevision> for TypeCellData {
} }
impl TypeCellData { impl TypeCellData {
pub fn new(content: String, field_type: FieldType) -> Self { pub fn new(cell_str: String, field_type: FieldType) -> Self {
TypeCellData { TypeCellData { cell_str, field_type }
cell_str: content,
field_type,
}
} }
pub fn to_json(&self) -> String { pub fn to_json(&self) -> String {

View File

@ -87,9 +87,9 @@ impl CellDataChangeset for CheckboxTypeOptionPB {
&self, &self,
changeset: <Self as TypeOption>::CellChangeset, changeset: <Self as TypeOption>::CellChangeset,
_type_cell_data: Option<TypeCellData>, _type_cell_data: Option<TypeCellData>,
) -> FlowyResult<<Self as TypeOption>::CellData> { ) -> FlowyResult<(String, <Self as TypeOption>::CellData)> {
let checkbox_cell_data = CheckboxCellData::from_str(&changeset)?; let checkbox_cell_data = CheckboxCellData::from_str(&changeset)?;
Ok(checkbox_cell_data) Ok((checkbox_cell_data.to_string(), checkbox_cell_data))
} }
} }

View File

@ -152,17 +152,17 @@ mod tests {
time: include_time_str, time: include_time_str,
is_utc: false, is_utc: false,
}; };
let encoded_data = type_option.apply_changeset(changeset, None).unwrap(); let (cell_str, _) = type_option.apply_changeset(changeset, None).unwrap();
assert_eq!( assert_eq!(
decode_cell_data(encoded_data.to_string(), type_option, field_rev), decode_cell_data(cell_str, type_option, field_rev),
expected_str.to_owned(), expected_str.to_owned(),
); );
} }
fn decode_cell_data(encoded_data: String, type_option: &DateTypeOptionPB, field_rev: &FieldRevision) -> String { fn decode_cell_data(cell_str: String, type_option: &DateTypeOptionPB, field_rev: &FieldRevision) -> String {
let decoded_data = type_option let decoded_data = type_option
.decode_cell_str(encoded_data, &FieldType::DateTime, field_rev) .decode_cell_str(cell_str, &FieldType::DateTime, field_rev)
.unwrap(); .unwrap();
let decoded_data = type_option.convert_to_protobuf(decoded_data); let decoded_data = type_option.convert_to_protobuf(decoded_data);
if type_option.include_time { if type_option.include_time {

View File

@ -157,7 +157,7 @@ impl CellDataChangeset for DateTypeOptionPB {
&self, &self,
changeset: <Self as TypeOption>::CellChangeset, changeset: <Self as TypeOption>::CellChangeset,
_type_cell_data: Option<TypeCellData>, _type_cell_data: Option<TypeCellData>,
) -> FlowyResult<<Self as TypeOption>::CellData> { ) -> FlowyResult<(String, <Self as TypeOption>::CellData)> {
let cell_data = match changeset.date_timestamp() { let cell_data = match changeset.date_timestamp() {
None => 0, None => 0,
Some(date_timestamp) => match (self.include_time, changeset.time) { Some(date_timestamp) => match (self.include_time, changeset.time) {
@ -171,8 +171,8 @@ impl CellDataChangeset for DateTypeOptionPB {
_ => date_timestamp, _ => date_timestamp,
}, },
}; };
let date_cell_data = DateCellData(Some(cell_data));
Ok(DateCellData(Some(cell_data))) Ok((date_cell_data.to_string(), date_cell_data))
} }
} }

View File

@ -70,7 +70,7 @@ impl ToCellChangesetString for DateCellChangeset {
} }
} }
#[derive(Default, Clone)] #[derive(Default, Clone, Debug)]
pub struct DateCellData(pub Option<i64>); pub struct DateCellData(pub Option<i64>);
impl std::convert::From<DateCellData> for i64 { impl std::convert::From<DateCellData> for i64 {

View File

@ -155,10 +155,10 @@ impl CellDataChangeset for NumberTypeOptionPB {
&self, &self,
changeset: <Self as TypeOption>::CellChangeset, changeset: <Self as TypeOption>::CellChangeset,
_type_cell_data: Option<TypeCellData>, _type_cell_data: Option<TypeCellData>,
) -> FlowyResult<<Self as TypeOption>::CellData> { ) -> FlowyResult<(String, <Self as TypeOption>::CellData)> {
let data = changeset.trim().to_string(); let data = changeset.trim().to_string();
let _ = self.format_cell_data(&data)?; let number_cell_data = self.format_cell_data(&data)?;
Ok(StrCellData(data)) Ok((data, number_cell_data.to_string().into()))
} }
} }

View File

@ -60,15 +60,15 @@ impl CellDataChangeset for ChecklistTypeOptionPB {
&self, &self,
changeset: <Self as TypeOption>::CellChangeset, changeset: <Self as TypeOption>::CellChangeset,
type_cell_data: Option<TypeCellData>, type_cell_data: Option<TypeCellData>,
) -> FlowyResult<<Self as TypeOption>::CellData> { ) -> FlowyResult<(String, <Self as TypeOption>::CellData)> {
let insert_option_ids = changeset let insert_option_ids = changeset
.insert_option_ids .insert_option_ids
.into_iter() .into_iter()
.filter(|insert_option_id| self.options.iter().any(|option| &option.id == insert_option_id)) .filter(|insert_option_id| self.options.iter().any(|option| &option.id == insert_option_id))
.collect::<Vec<String>>(); .collect::<Vec<String>>();
match type_cell_data { let select_option_ids = match type_cell_data {
None => Ok(SelectOptionIds::from(insert_option_ids)), None => SelectOptionIds::from(insert_option_ids),
Some(type_cell_data) => { Some(type_cell_data) => {
let mut select_ids: SelectOptionIds = type_cell_data.cell_str.into(); let mut select_ids: SelectOptionIds = type_cell_data.cell_str.into();
for insert_option_id in insert_option_ids { for insert_option_id in insert_option_ids {
@ -81,9 +81,10 @@ impl CellDataChangeset for ChecklistTypeOptionPB {
select_ids.retain(|id| id != &delete_option_id); select_ids.retain(|id| id != &delete_option_id);
} }
Ok(select_ids) select_ids
} }
} };
Ok((select_option_ids.to_string(), select_option_ids))
} }
} }
impl TypeOptionCellDataFilter for ChecklistTypeOptionPB { impl TypeOptionCellDataFilter for ChecklistTypeOptionPB {

View File

@ -61,15 +61,15 @@ impl CellDataChangeset for MultiSelectTypeOptionPB {
&self, &self,
changeset: <Self as TypeOption>::CellChangeset, changeset: <Self as TypeOption>::CellChangeset,
type_cell_data: Option<TypeCellData>, type_cell_data: Option<TypeCellData>,
) -> FlowyResult<<Self as TypeOption>::CellData> { ) -> FlowyResult<(String, <Self as TypeOption>::CellData)> {
let insert_option_ids = changeset let insert_option_ids = changeset
.insert_option_ids .insert_option_ids
.into_iter() .into_iter()
.filter(|insert_option_id| self.options.iter().any(|option| &option.id == insert_option_id)) .filter(|insert_option_id| self.options.iter().any(|option| &option.id == insert_option_id))
.collect::<Vec<String>>(); .collect::<Vec<String>>();
match type_cell_data { let select_option_ids = match type_cell_data {
None => Ok(SelectOptionIds::from(insert_option_ids)), None => SelectOptionIds::from(insert_option_ids),
Some(type_cell_data) => { Some(type_cell_data) => {
let mut select_ids: SelectOptionIds = type_cell_data.cell_str.into(); let mut select_ids: SelectOptionIds = type_cell_data.cell_str.into();
for insert_option_id in insert_option_ids { for insert_option_id in insert_option_ids {
@ -83,9 +83,10 @@ impl CellDataChangeset for MultiSelectTypeOptionPB {
} }
tracing::trace!("Multi-select cell data: {}", select_ids.to_string()); tracing::trace!("Multi-select cell data: {}", select_ids.to_string());
Ok(select_ids) select_ids
} }
} };
Ok((select_option_ids.to_string(), select_option_ids))
} }
} }
@ -210,7 +211,7 @@ mod tests {
let type_option = MultiSelectTypeOptionPB::from(&field_rev); let type_option = MultiSelectTypeOptionPB::from(&field_rev);
let option_ids = vec![google.id, facebook.id]; let option_ids = vec![google.id, facebook.id];
let changeset = SelectOptionCellChangeset::from_insert_options(option_ids.clone()); let changeset = SelectOptionCellChangeset::from_insert_options(option_ids.clone());
let select_option_ids: SelectOptionIds = type_option.apply_changeset(changeset, None).unwrap(); let select_option_ids: SelectOptionIds = type_option.apply_changeset(changeset, None).unwrap().1;
assert_eq!(&*select_option_ids, &option_ids); assert_eq!(&*select_option_ids, &option_ids);
} }
@ -229,12 +230,12 @@ mod tests {
// insert // insert
let changeset = SelectOptionCellChangeset::from_insert_options(option_ids.clone()); let changeset = SelectOptionCellChangeset::from_insert_options(option_ids.clone());
let select_option_ids = type_option.apply_changeset(changeset, None).unwrap(); let select_option_ids = type_option.apply_changeset(changeset, None).unwrap().1;
assert_eq!(&*select_option_ids, &option_ids); assert_eq!(&*select_option_ids, &option_ids);
// delete // delete
let changeset = SelectOptionCellChangeset::from_delete_options(option_ids); let changeset = SelectOptionCellChangeset::from_delete_options(option_ids);
let select_option_ids = type_option.apply_changeset(changeset, None).unwrap(); let select_option_ids = type_option.apply_changeset(changeset, None).unwrap().1;
assert!(select_option_ids.is_empty()); assert!(select_option_ids.is_empty());
} }
@ -250,7 +251,7 @@ mod tests {
let type_option = MultiSelectTypeOptionPB::from(&field_rev); let type_option = MultiSelectTypeOptionPB::from(&field_rev);
let changeset = SelectOptionCellChangeset::from_insert_option_id(&google.id); let changeset = SelectOptionCellChangeset::from_insert_option_id(&google.id);
let select_option_ids = type_option.apply_changeset(changeset, None).unwrap(); let select_option_ids = type_option.apply_changeset(changeset, None).unwrap().1;
assert_eq!(select_option_ids.to_string(), google.id); assert_eq!(select_option_ids.to_string(), google.id);
} }
@ -265,7 +266,7 @@ mod tests {
let type_option = MultiSelectTypeOptionPB::from(&field_rev); let type_option = MultiSelectTypeOptionPB::from(&field_rev);
let changeset = SelectOptionCellChangeset::from_insert_option_id(&google.id); let changeset = SelectOptionCellChangeset::from_insert_option_id(&google.id);
let select_option_ids = type_option.apply_changeset(changeset, None).unwrap(); let (_, select_option_ids) = type_option.apply_changeset(changeset, None).unwrap();
assert!(select_option_ids.is_empty()); assert!(select_option_ids.is_empty());
} }
@ -283,11 +284,11 @@ mod tests {
// empty option id string // empty option id string
let changeset = SelectOptionCellChangeset::from_insert_option_id(""); let changeset = SelectOptionCellChangeset::from_insert_option_id("");
let select_option_ids = type_option.apply_changeset(changeset, None).unwrap(); let (cell_str, _) = type_option.apply_changeset(changeset, None).unwrap();
assert_eq!(select_option_ids.to_string(), ""); assert_eq!(cell_str, "");
let changeset = SelectOptionCellChangeset::from_insert_option_id("123,456"); let changeset = SelectOptionCellChangeset::from_insert_option_id("123,456");
let select_option_ids = type_option.apply_changeset(changeset, None).unwrap(); let select_option_ids = type_option.apply_changeset(changeset, None).unwrap().1;
assert!(select_option_ids.is_empty()); assert!(select_option_ids.is_empty());
} }
} }

View File

@ -254,7 +254,7 @@ pub fn new_select_option_color(options: &Vec<SelectOptionPB>) -> SelectOptionCol
/// Calls [to_string] will return a string consists list of ids, /// Calls [to_string] will return a string consists list of ids,
/// placing a commas separator between each /// placing a commas separator between each
/// ///
#[derive(Default, Clone)] #[derive(Default, Clone, Debug)]
pub struct SelectOptionIds(Vec<String>); pub struct SelectOptionIds(Vec<String>);
impl SelectOptionIds { impl SelectOptionIds {

View File

@ -63,7 +63,7 @@ impl CellDataChangeset for SingleSelectTypeOptionPB {
&self, &self,
changeset: <Self as TypeOption>::CellChangeset, changeset: <Self as TypeOption>::CellChangeset,
_type_cell_data: Option<TypeCellData>, _type_cell_data: Option<TypeCellData>,
) -> FlowyResult<<Self as TypeOption>::CellData> { ) -> FlowyResult<(String, <Self as TypeOption>::CellData)> {
let mut insert_option_ids = changeset let mut insert_option_ids = changeset
.insert_option_ids .insert_option_ids
.into_iter() .into_iter()
@ -73,13 +73,14 @@ impl CellDataChangeset for SingleSelectTypeOptionPB {
// In single select, the insert_option_ids should only contain one select option id. // In single select, the insert_option_ids should only contain one select option id.
// Sometimes, the insert_option_ids may contain list of option ids. For example, // Sometimes, the insert_option_ids may contain list of option ids. For example,
// copy/paste a ids string. // copy/paste a ids string.
if insert_option_ids.is_empty() { let select_option_ids = if insert_option_ids.is_empty() {
Ok(SelectOptionIds::from(insert_option_ids)) SelectOptionIds::from(insert_option_ids)
} else { } else {
// Just take the first select option // Just take the first select option
let _ = insert_option_ids.drain(1..); let _ = insert_option_ids.drain(1..);
Ok(SelectOptionIds::from(insert_option_ids)) SelectOptionIds::from(insert_option_ids)
} };
Ok((select_option_ids.to_string(), select_option_ids))
} }
} }
@ -195,7 +196,7 @@ mod tests {
let type_option = SingleSelectTypeOptionPB::from(&field_rev); let type_option = SingleSelectTypeOptionPB::from(&field_rev);
let option_ids = vec![google.id.clone(), facebook.id]; let option_ids = vec![google.id.clone(), facebook.id];
let changeset = SelectOptionCellChangeset::from_insert_options(option_ids); let changeset = SelectOptionCellChangeset::from_insert_options(option_ids);
let select_option_ids = type_option.apply_changeset(changeset, None).unwrap(); let select_option_ids = type_option.apply_changeset(changeset, None).unwrap().1;
assert_eq!(&*select_option_ids, &vec![google.id]); assert_eq!(&*select_option_ids, &vec![google.id]);
} }
@ -213,12 +214,12 @@ mod tests {
// insert // insert
let changeset = SelectOptionCellChangeset::from_insert_options(option_ids.clone()); let changeset = SelectOptionCellChangeset::from_insert_options(option_ids.clone());
let select_option_ids = type_option.apply_changeset(changeset, None).unwrap(); let select_option_ids = type_option.apply_changeset(changeset, None).unwrap().1;
assert_eq!(&*select_option_ids, &vec![google.id]); assert_eq!(&*select_option_ids, &vec![google.id]);
// delete // delete
let changeset = SelectOptionCellChangeset::from_delete_options(option_ids); let changeset = SelectOptionCellChangeset::from_delete_options(option_ids);
let select_option_ids = type_option.apply_changeset(changeset, None).unwrap(); let select_option_ids = type_option.apply_changeset(changeset, None).unwrap().1;
assert!(select_option_ids.is_empty()); assert!(select_option_ids.is_empty());
} }
@ -231,7 +232,7 @@ mod tests {
let option_ids = vec![google.id]; let option_ids = vec![google.id];
let changeset = SelectOptionCellChangeset::from_insert_options(option_ids); let changeset = SelectOptionCellChangeset::from_insert_options(option_ids);
let select_option_ids = type_option.apply_changeset(changeset, None).unwrap(); let select_option_ids = type_option.apply_changeset(changeset, None).unwrap().1;
assert!(select_option_ids.is_empty()); assert!(select_option_ids.is_empty());
} }
@ -243,7 +244,7 @@ mod tests {
let type_option = SingleSelectTypeOptionPB::from(&field_rev); let type_option = SingleSelectTypeOptionPB::from(&field_rev);
let changeset = SelectOptionCellChangeset::from_insert_option_id(""); let changeset = SelectOptionCellChangeset::from_insert_option_id("");
let select_option_ids = type_option.apply_changeset(changeset, None).unwrap(); let select_option_ids = type_option.apply_changeset(changeset, None).unwrap().1;
assert!(select_option_ids.is_empty()); assert!(select_option_ids.is_empty());
} }
} }

View File

@ -104,11 +104,12 @@ impl CellDataChangeset for RichTextTypeOptionPB {
&self, &self,
changeset: <Self as TypeOption>::CellChangeset, changeset: <Self as TypeOption>::CellChangeset,
_type_cell_data: Option<TypeCellData>, _type_cell_data: Option<TypeCellData>,
) -> FlowyResult<<Self as TypeOption>::CellData> { ) -> FlowyResult<(String, <Self as TypeOption>::CellData)> {
if changeset.len() > 10000 { if changeset.len() > 10000 {
Err(FlowyError::text_too_long().context("The len of the text should not be more than 10000")) Err(FlowyError::text_too_long().context("The len of the text should not be more than 10000"))
} else { } else {
Ok(StrCellData(changeset)) let text_cell_data = StrCellData(changeset);
Ok((text_cell_data.to_string(), text_cell_data))
} }
} }
} }

View File

@ -20,7 +20,7 @@ pub trait TypeOption {
/// ///
/// Uses `StrCellData` for any `TypeOption` if their cell data is pure `String`. /// Uses `StrCellData` for any `TypeOption` if their cell data is pure `String`.
/// ///
type CellData: FromCellString + ToString + Default + Send + Sync + Clone + 'static; type CellData: FromCellString + ToString + Default + Send + Sync + Clone + Debug + 'static;
/// Represents as the corresponding field type cell changeset. /// Represents as the corresponding field type cell changeset.
/// The changeset must implements the `FromCellChangesetString` and the `ToCellChangesetString` trait. /// The changeset must implements the `FromCellChangesetString` and the `ToCellChangesetString` trait.

View File

@ -13,7 +13,7 @@ use flowy_error::FlowyResult;
use grid_rev_model::{FieldRevision, TypeOptionDataDeserializer, TypeOptionDataSerializer}; use grid_rev_model::{FieldRevision, TypeOptionDataDeserializer, TypeOptionDataSerializer};
use std::cmp::Ordering; use std::cmp::Ordering;
use std::collections::hash_map::DefaultHasher; use std::collections::hash_map::DefaultHasher;
use std::hash::Hasher; use std::hash::{Hash, Hasher};
/// A helper trait that used to erase the `Self` of `TypeOption` trait to make it become a Object-safe trait /// A helper trait that used to erase the `Self` of `TypeOption` trait to make it become a Object-safe trait
/// Only object-safe traits can be made into trait objects. /// Only object-safe traits can be made into trait objects.
@ -55,6 +55,9 @@ struct CellDataCacheKey(u64);
impl CellDataCacheKey { impl CellDataCacheKey {
pub fn new(field_rev: &FieldRevision, decoded_field_type: FieldType, cell_str: &str) -> Self { pub fn new(field_rev: &FieldRevision, decoded_field_type: FieldType, cell_str: &str) -> Self {
let mut hasher = DefaultHasher::new(); let mut hasher = DefaultHasher::new();
if let Some(type_option_str) = field_rev.get_type_option_str(&decoded_field_type) {
type_option_str.hash(&mut hasher);
}
hasher.write(field_rev.id.as_bytes()); hasher.write(field_rev.id.as_bytes());
hasher.write_u8(decoded_field_type as u8); hasher.write_u8(decoded_field_type as u8);
hasher.write(cell_str.as_bytes()); hasher.write(cell_str.as_bytes());
@ -112,7 +115,12 @@ where
if let Some(cell_data_cache) = self.cell_data_cache.as_ref() { if let Some(cell_data_cache) = self.cell_data_cache.as_ref() {
let read_guard = cell_data_cache.read(); let read_guard = cell_data_cache.read();
if let Some(cell_data) = read_guard.get(key.as_ref()).cloned() { if let Some(cell_data) = read_guard.get(key.as_ref()).cloned() {
tracing::trace!("Cell cache hit: {}:{}", decoded_field_type, cell_str); tracing::trace!(
"Cell cache hit: field_type:{}, cell_str: {}, cell_data: {:?}",
decoded_field_type,
cell_str,
cell_data
);
return Ok(cell_data); return Ok(cell_data);
} }
} }
@ -124,12 +132,20 @@ where
Ok(cell_data) Ok(cell_data)
} }
fn set_decoded_cell_data(&self, cell_data: <Self as TypeOption>::CellData, field_rev: &FieldRevision) { fn set_decoded_cell_data(
&self,
cell_str: &str,
cell_data: <Self as TypeOption>::CellData,
field_rev: &FieldRevision,
) {
if let Some(cell_data_cache) = self.cell_data_cache.as_ref() { if let Some(cell_data_cache) = self.cell_data_cache.as_ref() {
let field_type: FieldType = field_rev.ty.into(); let field_type: FieldType = field_rev.ty.into();
let cell_str = cell_data.to_string(); tracing::trace!(
tracing::trace!("Update cell cache {}:{}", field_type, cell_str); "Update cell cache field_type: {}, cell_data: {:?}",
let key = CellDataCacheKey::new(field_rev, field_type, &cell_str); field_type,
cell_data
);
let key = CellDataCacheKey::new(field_rev, field_type, cell_str);
cell_data_cache.write().insert(key.as_ref(), cell_data); cell_data_cache.write().insert(key.as_ref(), cell_data);
} }
} }
@ -187,9 +203,9 @@ where
field_rev: &FieldRevision, field_rev: &FieldRevision,
) -> FlowyResult<String> { ) -> FlowyResult<String> {
let changeset = <Self as TypeOption>::CellChangeset::from_changeset(cell_changeset)?; let changeset = <Self as TypeOption>::CellChangeset::from_changeset(cell_changeset)?;
let cell_data = self.apply_changeset(changeset, old_type_cell_data)?; let (cell_str, cell_data) = self.apply_changeset(changeset, old_type_cell_data)?;
self.set_decoded_cell_data(cell_data.clone(), field_rev); self.set_decoded_cell_data(&cell_str, cell_data, field_rev);
Ok(cell_data.to_string()) Ok(cell_str)
} }
fn handle_cell_compare(&self, left_cell_data: &str, right_cell_data: &str, field_rev: &FieldRevision) -> Ordering { fn handle_cell_compare(&self, left_cell_data: &str, right_cell_data: &str, field_rev: &FieldRevision) -> Ordering {

View File

@ -157,7 +157,7 @@ mod tests {
expected_url: &str, expected_url: &str,
_field_rev: &FieldRevision, _field_rev: &FieldRevision,
) { ) {
let decode_cell_data = type_option.apply_changeset(input_str.to_owned(), None).unwrap(); let decode_cell_data = type_option.apply_changeset(input_str.to_owned(), None).unwrap().1;
assert_eq!(expected_str.to_owned(), decode_cell_data.content); assert_eq!(expected_str.to_owned(), decode_cell_data.content);
assert_eq!(expected_url.to_owned(), decode_cell_data.url); assert_eq!(expected_url.to_owned(), decode_cell_data.url);
} }

View File

@ -81,15 +81,16 @@ impl CellDataChangeset for URLTypeOptionPB {
&self, &self,
changeset: <Self as TypeOption>::CellChangeset, changeset: <Self as TypeOption>::CellChangeset,
_type_cell_data: Option<TypeCellData>, _type_cell_data: Option<TypeCellData>,
) -> FlowyResult<<Self as TypeOption>::CellData> { ) -> FlowyResult<(String, <Self as TypeOption>::CellData)> {
let mut url = "".to_string(); let mut url = "".to_string();
if let Ok(Some(m)) = URL_REGEX.find(&changeset) { if let Ok(Some(m)) = URL_REGEX.find(&changeset) {
url = auto_append_scheme(m.as_str()); url = auto_append_scheme(m.as_str());
} }
Ok(URLCellData { let url_cell_data = URLCellData {
url, url,
content: changeset, content: changeset,
}) };
Ok((url_cell_data.to_string(), url_cell_data))
} }
} }

View File

@ -30,7 +30,7 @@ impl DecodedCellData for URLCellDataPB {
} }
} }
#[derive(Clone, Default, Serialize, Deserialize)] #[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct URLCellData { pub struct URLCellData {
pub url: String, pub url: String,
pub content: String, pub content: String,

View File

@ -142,6 +142,10 @@ impl SortController {
}); });
} }
pub async fn did_update_view_field_type_option(&self, _field_rev: &FieldRevision) {
//
}
#[tracing::instrument(level = "trace", skip(self))] #[tracing::instrument(level = "trace", skip(self))]
pub async fn did_receive_changes(&mut self, changeset: SortChangeset) -> SortChangesetNotificationPB { pub async fn did_receive_changes(&mut self, changeset: SortChangeset) -> SortChangesetNotificationPB {
let mut notification = SortChangesetNotificationPB::default(); let mut notification = SortChangesetNotificationPB::default();

View File

@ -537,6 +537,13 @@ impl GridViewRevisionEditor {
let new = FilterType::from(&field_rev); let new = FilterType::from(&field_rev);
let filter_type = UpdatedFilterType::new(old, new); let filter_type = UpdatedFilterType::new(old, new);
let filter_changeset = FilterChangeset::from_update(filter_type); let filter_changeset = FilterChangeset::from_update(filter_type);
self.sort_controller
.read()
.await
.did_update_view_field_type_option(&field_rev)
.await;
if let Some(changeset) = self if let Some(changeset) = self
.filter_controller .filter_controller
.write() .write()

View File

@ -15,7 +15,7 @@ async fn grid_create_field() {
CreateField { params }, CreateField { params },
AssertFieldTypeOptionEqual { AssertFieldTypeOptionEqual {
field_index: test.field_count(), field_index: test.field_count(),
expected_type_option_data: field_rev.get_type_option_str(field_rev.ty).unwrap(), expected_type_option_data: field_rev.get_type_option_str(field_rev.ty).unwrap().to_owned(),
}, },
]; ];
test.run_scripts(scripts).await; test.run_scripts(scripts).await;
@ -25,7 +25,7 @@ async fn grid_create_field() {
CreateField { params }, CreateField { params },
AssertFieldTypeOptionEqual { AssertFieldTypeOptionEqual {
field_index: test.field_count(), field_index: test.field_count(),
expected_type_option_data: field_rev.get_type_option_str(field_rev.ty).unwrap(), expected_type_option_data: field_rev.get_type_option_str(field_rev.ty).unwrap().to_owned(),
}, },
]; ];
test.run_scripts(scripts).await; test.run_scripts(scripts).await;
@ -63,7 +63,7 @@ async fn grid_update_field_with_empty_change() {
UpdateField { changeset }, UpdateField { changeset },
AssertFieldTypeOptionEqual { AssertFieldTypeOptionEqual {
field_index: create_field_index, field_index: create_field_index,
expected_type_option_data: field_rev.get_type_option_str(field_rev.ty).unwrap(), expected_type_option_data: field_rev.get_type_option_str(field_rev.ty).unwrap().to_owned(),
}, },
]; ];
test.run_scripts(scripts).await; test.run_scripts(scripts).await;

View File

@ -166,11 +166,16 @@ impl GridRevisionPad {
Some(field_rev) => { Some(field_rev) => {
let mut_field_rev = Arc::make_mut(field_rev); let mut_field_rev = Arc::make_mut(field_rev);
let old_field_type_rev = mut_field_rev.ty; let old_field_type_rev = mut_field_rev.ty;
let old_field_type_option = mut_field_rev.get_type_option_str(mut_field_rev.ty); let old_field_type_option = mut_field_rev
.get_type_option_str(mut_field_rev.ty)
.map(|value| value.to_owned());
match mut_field_rev.get_type_option_str(new_field_type) { match mut_field_rev.get_type_option_str(new_field_type) {
Some(new_field_type_option) => { Some(new_field_type_option) => {
let transformed_type_option = let transformed_type_option = type_option_transform(
type_option_transform(old_field_type_rev, old_field_type_option, new_field_type_option); old_field_type_rev,
old_field_type_option,
new_field_type_option.to_owned(),
);
mut_field_rev.insert_type_option_str(&new_field_type, transformed_type_option); mut_field_rev.insert_type_option_str(&new_field_type, transformed_type_option);
} }
None => { None => {

936
shared-lib/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -165,10 +165,10 @@ impl FieldRevision {
self.type_options.insert(id, json_str); self.type_options.insert(id, json_str);
} }
pub fn get_type_option_str<T: Into<FieldTypeRevision>>(&self, field_type: T) -> Option<String> { pub fn get_type_option_str<T: Into<FieldTypeRevision>>(&self, field_type: T) -> Option<&str> {
let field_type_rev = field_type.into(); let field_type_rev = field_type.into();
let id = field_type_rev.to_string(); let id = field_type_rev.to_string();
self.type_options.get(&id).map(|s| s.to_owned()) self.type_options.get(&id).map(|s| s.as_str())
} }
} }