mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: add edit field type option helper
This commit is contained in:
parent
f192f89ebb
commit
e75d8f22c8
@ -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>,
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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> {
|
||||
|
@ -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(())
|
||||
}
|
@ -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::*;
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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(),
|
||||
)
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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![],
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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 },
|
||||
|
@ -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();
|
||||
|
@ -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]
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)]
|
||||
|
Loading…
Reference in New Issue
Block a user