diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs index 166ac9eea3..cb8f2c1e76 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -11,7 +11,7 @@ pub fn create(grid_manager: Arc) -> Module { .event(GridEvent::GetGridData, get_grid_data_handler) .event(GridEvent::GetGridBlocks, get_grid_blocks_handler) .event(GridEvent::GetGridSetting, get_grid_setting_handler) - .event(GridEvent::UpdateGridSetting, get_grid_setting_handler) + .event(GridEvent::UpdateGridSetting, update_grid_setting_handler) // Field .event(GridEvent::GetFields, get_fields_handler) .event(GridEvent::UpdateField, update_field_handler) diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index eb00e88e2b..92cbaf921f 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -261,6 +261,10 @@ impl GridEditorTest { .unwrap() .row_revs } + + pub(crate) async fn get_grid_setting(&self) -> GridSettingRevision { + self.editor.get_grid_setting().await.unwrap() + } } pub fn create_text_field(grid_id: &str) -> (InsertFieldParams, FieldRevision) { diff --git a/frontend/rust-lib/flowy-grid/tests/grid/setting_test.rs b/frontend/rust-lib/flowy-grid/tests/grid/setting_test.rs index 8b13789179..dd75014515 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/setting_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/setting_test.rs @@ -1 +1,29 @@ +use crate::grid::script::EditorScript::*; +use crate::grid::script::*; +use flowy_grid_data_model::entities::{ + CreateGridFilterParams, CreateGridFilterPayload, GridLayoutType, GridSettingChangesetParams, +}; +use flowy_grid_data_model::revision::GridSettingRevision; +#[tokio::test] +async fn grid_setting_create_filter_test() { + let test = GridEditorTest::new().await; + + let layout_type = GridLayoutType::Table; + let field_rev = test.field_revs.last().unwrap(); + let create_params: CreateGridFilterParams = CreateGridFilterPayload { + field_id: field_rev.id.clone(), + field_type: field_rev.field_type.clone(), + } + .try_into() + .unwrap(); + let params = GridSettingChangesetParams::from_insert_filter(&test.grid_id, layout_type, create_params); + + let scripts = vec![UpdateGridSetting { params }]; + GridEditorTest::new().await.run_scripts(scripts).await; + + // let mut expected_grid_setting = test.get_grid_setting().await; +} + +#[tokio::test] +async fn grid_setting_sort_test() {} diff --git a/shared-lib/flowy-grid-data-model/src/entities/grid_filter.rs b/shared-lib/flowy-grid-data-model/src/entities/grid_filter.rs new file mode 100644 index 0000000000..1bd3fd3641 --- /dev/null +++ b/shared-lib/flowy-grid-data-model/src/entities/grid_filter.rs @@ -0,0 +1,154 @@ +use crate::parser::NotEmptyStr; +use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; +use flowy_error_code::ErrorCode; + +use crate::entities::FieldType; +use crate::revision::{ + FilterInfoRevision, GridFilterRevision, NumberFilterConditionRevision, TextFilterConditionRevision, +}; +use std::convert::TryInto; + +#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] +pub struct GridFilter { + #[pb(index = 1)] + pub id: String, + + #[pb(index = 2)] + pub field_id: String, + + #[pb(index = 3)] + pub info: FilterInfo, +} + +impl std::convert::From for GridFilter { + fn from(rev: GridFilterRevision) -> Self { + GridFilter { + id: rev.id, + field_id: rev.field_id, + info: rev.info.into(), + } + } +} + +#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] +pub struct FilterInfo { + #[pb(index = 1, one_of)] + pub condition: Option, + + #[pb(index = 2, one_of)] + pub content: Option, +} + +impl std::convert::From for FilterInfo { + fn from(rev: FilterInfoRevision) -> Self { + FilterInfo { + condition: rev.condition, + content: rev.content, + } + } +} + +#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] +pub struct RepeatedGridFilter { + #[pb(index = 1)] + pub items: Vec, +} + +impl std::convert::From> for RepeatedGridFilter { + fn from(revs: Vec) -> Self { + RepeatedGridFilter { + items: revs.into_iter().map(|rev| rev.into()).collect(), + } + } +} + +impl std::convert::From> for RepeatedGridFilter { + fn from(items: Vec) -> Self { + Self { items } + } +} + +#[derive(ProtoBuf, Debug, Default, Clone)] +pub struct CreateGridFilterPayload { + #[pb(index = 1)] + pub field_id: String, + + #[pb(index = 2)] + pub field_type: FieldType, +} + +pub struct CreateGridFilterParams { + pub field_id: String, + pub field_type: FieldType, +} + +impl TryInto for CreateGridFilterPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let field_id = NotEmptyStr::parse(self.field_id) + .map_err(|_| ErrorCode::FieldIdIsEmpty)? + .0; + + Ok(CreateGridFilterParams { + field_id, + field_type: self.field_type, + }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum)] +#[repr(u8)] +pub enum TextFilterCondition { + Is = 0, + IsNot = 1, + Contains = 2, + DoesNotContain = 3, + StartsWith = 4, + EndsWith = 5, + TextIsEmpty = 6, + TextIsNotEmpty = 7, +} + +impl std::convert::From for TextFilterCondition { + fn from(rev: TextFilterConditionRevision) -> Self { + match rev { + TextFilterConditionRevision::Is => TextFilterCondition::Is, + TextFilterConditionRevision::IsNot => TextFilterCondition::IsNot, + TextFilterConditionRevision::Contains => TextFilterCondition::Contains, + TextFilterConditionRevision::DoesNotContain => TextFilterCondition::DoesNotContain, + TextFilterConditionRevision::StartsWith => TextFilterCondition::StartsWith, + TextFilterConditionRevision::EndsWith => TextFilterCondition::EndsWith, + TextFilterConditionRevision::IsEmpty => TextFilterCondition::TextIsEmpty, + TextFilterConditionRevision::IsNotEmpty => TextFilterCondition::TextIsNotEmpty, + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum)] +#[repr(u8)] +pub enum NumberFilterCondition { + Equal = 0, + NotEqual = 1, + GreaterThan = 2, + LessThan = 3, + GreaterThanOrEqualTo = 4, + LessThanOrEqualTo = 5, + NumberIsEmpty = 6, + NumberIsNotEmpty = 7, +} + +impl std::convert::From for NumberFilterCondition { + fn from(rev: NumberFilterConditionRevision) -> Self { + match rev { + NumberFilterConditionRevision::Equal => NumberFilterCondition::Equal, + NumberFilterConditionRevision::NotEqual => NumberFilterCondition::NotEqual, + NumberFilterConditionRevision::GreaterThan => NumberFilterCondition::GreaterThan, + NumberFilterConditionRevision::LessThan => NumberFilterCondition::LessThan, + NumberFilterConditionRevision::GreaterThanOrEqualTo => NumberFilterCondition::GreaterThan, + NumberFilterConditionRevision::LessThanOrEqualTo => NumberFilterCondition::LessThanOrEqualTo, + NumberFilterConditionRevision::IsEmpty => NumberFilterCondition::NumberIsEmpty, + NumberFilterConditionRevision::IsNotEmpty => NumberFilterCondition::NumberIsNotEmpty, + } + } +} diff --git a/shared-lib/flowy-grid-data-model/src/entities/grid_group.rs b/shared-lib/flowy-grid-data-model/src/entities/grid_group.rs new file mode 100644 index 0000000000..a6ae2364e2 --- /dev/null +++ b/shared-lib/flowy-grid-data-model/src/entities/grid_group.rs @@ -0,0 +1,80 @@ +use crate::parser::NotEmptyStr; +use flowy_derive::ProtoBuf; +use flowy_error_code::ErrorCode; + +use crate::revision::GridGroupRevision; +use std::convert::TryInto; + +#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] +pub struct GridGroup { + #[pb(index = 1)] + pub id: String, + + #[pb(index = 2, one_of)] + pub group_field_id: Option, + + #[pb(index = 3, one_of)] + pub sub_group_field_id: Option, +} + +impl std::convert::From for GridGroup { + fn from(rev: GridGroupRevision) -> Self { + GridGroup { + id: rev.id, + group_field_id: rev.field_id, + sub_group_field_id: rev.sub_field_id, + } + } +} + +#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] +pub struct RepeatedGridGroup { + #[pb(index = 1)] + pub items: Vec, +} + +impl std::convert::From> for RepeatedGridGroup { + fn from(items: Vec) -> Self { + Self { items } + } +} + +impl std::convert::From> for RepeatedGridGroup { + fn from(revs: Vec) -> Self { + RepeatedGridGroup { + items: revs.into_iter().map(|rev| rev.into()).collect(), + } + } +} + +#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] +pub struct CreateGridGroupPayload { + #[pb(index = 1, one_of)] + pub field_id: Option, + + #[pb(index = 2, one_of)] + pub sub_field_id: Option, +} + +pub struct CreateGridGroupParams { + pub field_id: Option, + pub sub_field_id: Option, +} + +impl TryInto for CreateGridGroupPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let field_id = match self.field_id { + None => None, + Some(field_id) => Some(NotEmptyStr::parse(field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?.0), + }; + + let sub_field_id = match self.sub_field_id { + None => None, + Some(field_id) => Some(NotEmptyStr::parse(field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?.0), + }; + + Ok(CreateGridGroupParams { field_id, sub_field_id }) + } +} diff --git a/shared-lib/flowy-grid-data-model/src/entities/grid_setting.rs b/shared-lib/flowy-grid-data-model/src/entities/grid_setting.rs index ef96bf0714..3d2512fcff 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid_setting.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid_setting.rs @@ -1,4 +1,9 @@ -use crate::parser::{NotEmptyStr, ViewFilterParser, ViewGroupParser, ViewSortParser}; +use crate::entities::{ + CreateGridFilterParams, CreateGridFilterPayload, CreateGridGroupParams, CreateGridGroupPayload, + CreateGridSortParams, CreateGridSortPayload, RepeatedGridFilter, RepeatedGridGroup, RepeatedGridSort, +}; +use crate::parser::NotEmptyStr; +use crate::revision::{GridLayoutRevision, GridSettingRevision}; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error_code::ErrorCode; use std::collections::HashMap; @@ -7,13 +12,41 @@ use std::convert::TryInto; #[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] pub struct GridSetting { #[pb(index = 1)] - pub filter: HashMap, + pub filters_by_layout_ty: HashMap, #[pb(index = 2)] - pub group: HashMap, + pub groups_by_layout_ty: HashMap, #[pb(index = 3)] - pub sort: HashMap, + pub sorts_by_layout_ty: HashMap, +} + +impl std::convert::From for GridSetting { + fn from(rev: GridSettingRevision) -> Self { + let filters_by_layout_ty: HashMap = rev + .filter + .into_iter() + .map(|(layout_rev, filter_revs)| (layout_rev.to_string(), filter_revs.into())) + .collect(); + + let groups_by_layout_ty: HashMap = rev + .group + .into_iter() + .map(|(layout_rev, group_revs)| (layout_rev.to_string(), group_revs.into())) + .collect(); + + let sorts_by_layout_ty: HashMap = rev + .sort + .into_iter() + .map(|(layout_rev, sort_revs)| (layout_rev.to_string(), sort_revs.into())) + .collect(); + + GridSetting { + filters_by_layout_ty, + groups_by_layout_ty, + sorts_by_layout_ty, + } + } } #[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum)] @@ -29,25 +62,22 @@ impl std::default::Default for GridLayoutType { } } -#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] -pub struct GridFilter { - #[pb(index = 1, one_of)] - pub field_id: Option, +impl std::convert::From for GridLayoutType { + fn from(rev: GridLayoutRevision) -> Self { + match rev { + GridLayoutRevision::Table => GridLayoutType::Table, + GridLayoutRevision::Board => GridLayoutType::Board, + } + } } -#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] -pub struct GridGroup { - #[pb(index = 1, one_of)] - pub group_field_id: Option, - - #[pb(index = 2, one_of)] - pub sub_group_field_id: Option, -} - -#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] -pub struct GridSort { - #[pb(index = 1, one_of)] - pub field_id: Option, +impl std::convert::From for GridLayoutRevision { + fn from(layout: GridLayoutType) -> Self { + match layout { + GridLayoutType::Table => GridLayoutRevision::Table, + GridLayoutType::Board => GridLayoutRevision::Board, + } + } } #[derive(Default, ProtoBuf)] @@ -59,21 +89,61 @@ pub struct GridSettingChangesetPayload { pub layout_type: GridLayoutType, #[pb(index = 3, one_of)] - pub filter: Option, + pub insert_filter: Option, #[pb(index = 4, one_of)] - pub group: Option, + pub delete_filter: Option, #[pb(index = 5, one_of)] - pub sort: Option, + pub insert_group: Option, + + #[pb(index = 6, one_of)] + pub delete_group: Option, + + #[pb(index = 7, one_of)] + pub insert_sort: Option, + + #[pb(index = 8, one_of)] + pub delete_sort: Option, } pub struct GridSettingChangesetParams { pub grid_id: String, pub layout_type: GridLayoutType, - pub filter: Option, - pub group: Option, - pub sort: Option, + pub insert_filter: Option, + pub delete_filter: Option, + pub insert_group: Option, + pub delete_group: Option, + pub insert_sort: Option, + pub delete_sort: Option, +} + +impl GridSettingChangesetParams { + pub fn from_insert_filter(grid_id: &str, layout_type: GridLayoutType, params: CreateGridFilterParams) -> Self { + Self { + grid_id: grid_id.to_owned(), + layout_type, + insert_filter: Some(params), + delete_filter: None, + insert_group: None, + delete_group: None, + insert_sort: None, + delete_sort: None, + } + } + + pub fn from_delete_filter(grid_id: &str, layout_type: GridLayoutType, filter_id: &str) -> Self { + Self { + grid_id: grid_id.to_owned(), + layout_type, + insert_filter: None, + delete_filter: Some(filter_id.to_string()), + insert_group: None, + delete_group: None, + insert_sort: None, + delete_sort: None, + } + } } impl TryInto for GridSettingChangesetPayload { @@ -84,27 +154,45 @@ impl TryInto for GridSettingChangesetPayload { .map_err(|_| ErrorCode::FieldIdIsEmpty)? .0; - let filter = match self.filter { + let insert_filter = match self.insert_filter { None => None, - Some(filter) => Some(ViewFilterParser::parse(filter)?), + Some(payload) => Some(payload.try_into()?), }; - let group = match self.group { + let delete_filter = match self.delete_filter { None => None, - Some(group) => Some(ViewGroupParser::parse(group)?), + Some(filter_id) => Some(NotEmptyStr::parse(filter_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?.0), }; - let sort = match self.sort { + let insert_group = match self.insert_group { + Some(payload) => Some(payload.try_into()?), None => None, - Some(sort) => Some(ViewSortParser::parse(sort)?), + }; + + let delete_group = match self.delete_group { + None => None, + Some(filter_id) => Some(NotEmptyStr::parse(filter_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?.0), + }; + + let insert_sort = match self.insert_sort { + None => None, + Some(payload) => Some(payload.try_into()?), + }; + + let delete_sort = match self.delete_sort { + None => None, + Some(filter_id) => Some(NotEmptyStr::parse(filter_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?.0), }; Ok(GridSettingChangesetParams { grid_id: view_id, layout_type: self.layout_type, - filter, - group, - sort, + insert_filter, + delete_filter, + insert_group, + delete_group, + insert_sort, + delete_sort, }) } } diff --git a/shared-lib/flowy-grid-data-model/src/entities/grid_sort.rs b/shared-lib/flowy-grid-data-model/src/entities/grid_sort.rs new file mode 100644 index 0000000000..8b833f41ba --- /dev/null +++ b/shared-lib/flowy-grid-data-model/src/entities/grid_sort.rs @@ -0,0 +1,67 @@ +use crate::parser::NotEmptyStr; +use flowy_derive::ProtoBuf; +use flowy_error_code::ErrorCode; + +use crate::revision::GridSortRevision; +use std::convert::TryInto; + +#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] +pub struct GridSort { + #[pb(index = 1)] + pub id: String, + + #[pb(index = 2, one_of)] + pub field_id: Option, +} + +impl std::convert::From for GridSort { + fn from(rev: GridSortRevision) -> Self { + GridSort { + id: rev.id, + field_id: rev.field_id, + } + } +} + +#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] +pub struct RepeatedGridSort { + #[pb(index = 1)] + pub items: Vec, +} + +impl std::convert::From> for RepeatedGridSort { + fn from(revs: Vec) -> Self { + RepeatedGridSort { + items: revs.into_iter().map(|rev| rev.into()).collect(), + } + } +} + +impl std::convert::From> for RepeatedGridSort { + fn from(items: Vec) -> Self { + Self { items } + } +} + +#[derive(ProtoBuf, Debug, Default, Clone)] +pub struct CreateGridSortPayload { + #[pb(index = 1, one_of)] + pub field_id: Option, +} + +pub struct CreateGridSortParams { + pub field_id: Option, +} + +impl TryInto for CreateGridSortPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let field_id = match self.field_id { + None => None, + Some(field_id) => Some(NotEmptyStr::parse(field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?.0), + }; + + Ok(CreateGridSortParams { field_id }) + } +} diff --git a/shared-lib/flowy-grid-data-model/src/entities/mod.rs b/shared-lib/flowy-grid-data-model/src/entities/mod.rs index 535e2142d8..e6a16d8026 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/mod.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/mod.rs @@ -1,7 +1,13 @@ mod field; mod grid; +mod grid_filter; +mod grid_group; mod grid_setting; +mod grid_sort; pub use field::*; pub use grid::*; +pub use grid_filter::*; +pub use grid_group::*; pub use grid_setting::*; +pub use grid_sort::*; diff --git a/shared-lib/flowy-grid-data-model/src/parser/grid_info_parser.rs b/shared-lib/flowy-grid-data-model/src/parser/grid_info_parser.rs deleted file mode 100644 index 1d14582ac0..0000000000 --- a/shared-lib/flowy-grid-data-model/src/parser/grid_info_parser.rs +++ /dev/null @@ -1,58 +0,0 @@ -use crate::entities::{GridFilter, GridGroup, GridSort}; -use crate::parser::NotEmptyStr; -use flowy_error_code::ErrorCode; - -pub struct ViewFilterParser(pub GridFilter); - -impl ViewFilterParser { - pub fn parse(value: GridFilter) -> Result { - let field_id = match value.field_id { - None => None, - Some(field_id) => Some(NotEmptyStr::parse(field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?.0), - }; - - Ok(GridFilter { field_id }) - } -} - -pub struct ViewGroupParser(pub GridGroup); - -impl ViewGroupParser { - pub fn parse(value: GridGroup) -> Result { - let group_field_id = match value.group_field_id { - None => None, - Some(group_field_id) => Some( - NotEmptyStr::parse(group_field_id) - .map_err(|_| ErrorCode::FieldIdIsEmpty)? - .0, - ), - }; - - let sub_group_field_id = match value.sub_group_field_id { - None => None, - Some(sub_group_field_id) => Some( - NotEmptyStr::parse(sub_group_field_id) - .map_err(|_| ErrorCode::FieldIdIsEmpty)? - .0, - ), - }; - - Ok(GridGroup { - group_field_id, - sub_group_field_id, - }) - } -} - -pub struct ViewSortParser(pub GridSort); - -impl ViewSortParser { - pub fn parse(value: GridSort) -> Result { - let field_id = match value.field_id { - None => None, - Some(field_id) => Some(NotEmptyStr::parse(field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?.0), - }; - - Ok(GridSort { field_id }) - } -} diff --git a/shared-lib/flowy-grid-data-model/src/parser/mod.rs b/shared-lib/flowy-grid-data-model/src/parser/mod.rs index 270d4ca043..8a9739e5b3 100644 --- a/shared-lib/flowy-grid-data-model/src/parser/mod.rs +++ b/shared-lib/flowy-grid-data-model/src/parser/mod.rs @@ -1,5 +1,2 @@ -mod grid_info_parser; mod str_parser; - -pub use grid_info_parser::*; pub use str_parser::*; diff --git a/shared-lib/flowy-grid-data-model/src/revision/grid_rev.rs b/shared-lib/flowy-grid-data-model/src/revision/grid_rev.rs index 310a28b843..669dcc48ec 100644 --- a/shared-lib/flowy-grid-data-model/src/revision/grid_rev.rs +++ b/shared-lib/flowy-grid-data-model/src/revision/grid_rev.rs @@ -31,8 +31,6 @@ pub struct GridRevision { pub grid_id: String, pub fields: Vec, pub blocks: Vec, - - #[serde(skip)] pub setting: GridSettingRevision, } diff --git a/shared-lib/flowy-grid-data-model/src/revision/grid_setting_rev.rs b/shared-lib/flowy-grid-data-model/src/revision/grid_setting_rev.rs index fd251f3c04..3598aaac90 100644 --- a/shared-lib/flowy-grid-data-model/src/revision/grid_setting_rev.rs +++ b/shared-lib/flowy-grid-data-model/src/revision/grid_setting_rev.rs @@ -1,19 +1,31 @@ -use crate::entities::{GridFilter, GridGroup, GridLayoutType, GridSetting, GridSort}; use indexmap::IndexMap; +use nanoid::nanoid; use serde::{Deserialize, Serialize}; use serde_repr::*; -use std::collections::HashMap; +use std::str::FromStr; + +pub fn gen_grid_filter_id() -> String { + nanoid!(6) +} + +pub fn gen_grid_group_id() -> String { + nanoid!(6) +} + +pub fn gen_grid_sort_id() -> String { + nanoid!(6) +} #[derive(Debug, Clone, Serialize, Deserialize, Default, Eq, PartialEq)] pub struct GridSettingRevision { #[serde(with = "indexmap::serde_seq")] - pub filter: IndexMap, + pub filter: IndexMap>, - #[serde(with = "indexmap::serde_seq")] - pub group: IndexMap, + #[serde(skip, with = "indexmap::serde_seq")] + pub group: IndexMap>, - #[serde(with = "indexmap::serde_seq")] - pub sort: IndexMap, + #[serde(skip, with = "indexmap::serde_seq")] + pub sort: IndexMap>, } #[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize_repr, Deserialize_repr)] @@ -36,81 +48,84 @@ impl std::default::Default for GridLayoutRevision { } } -impl std::convert::From for GridLayoutType { - fn from(rev: GridLayoutRevision) -> Self { - match rev { - GridLayoutRevision::Table => GridLayoutType::Table, - GridLayoutRevision::Board => GridLayoutType::Board, - } - } -} - -impl std::convert::From for GridLayoutRevision { - fn from(layout: GridLayoutType) -> Self { - match layout { - GridLayoutType::Table => GridLayoutRevision::Table, - GridLayoutType::Board => GridLayoutRevision::Board, - } - } -} - #[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)] pub struct GridFilterRevision { - pub field_id: Option, + pub id: String, + pub field_id: String, + pub info: FilterInfoRevision, } #[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)] pub struct GridGroupRevision { - pub group_field_id: Option, - pub sub_group_field_id: Option, + pub id: String, + pub field_id: Option, + pub sub_field_id: Option, } #[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)] pub struct GridSortRevision { + pub id: String, pub field_id: Option, } -impl std::convert::From for GridFilter { - fn from(rev: GridFilterRevision) -> Self { - GridFilter { field_id: rev.field_id } +#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)] +pub struct FilterInfoRevision { + pub condition: Option, + pub content: Option, +} + +#[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize_repr, Deserialize_repr)] +#[repr(u8)] +pub enum TextFilterConditionRevision { + Is = 0, + IsNot = 1, + Contains = 2, + DoesNotContain = 3, + StartsWith = 4, + EndsWith = 5, + IsEmpty = 6, + IsNotEmpty = 7, +} + +impl ToString for TextFilterConditionRevision { + fn to_string(&self) -> String { + (self.clone() as u8).to_string() } } -impl std::convert::From for GridGroup { - fn from(rev: GridGroupRevision) -> Self { - GridGroup { - group_field_id: rev.group_field_id, - sub_group_field_id: rev.sub_group_field_id, - } +impl FromStr for TextFilterConditionRevision { + type Err = serde_json::Error; + + fn from_str(s: &str) -> Result { + let rev = serde_json::from_str(s)?; + Ok(rev) } } -impl std::convert::From for GridSort { - fn from(rev: GridSortRevision) -> Self { - GridSort { field_id: rev.field_id } +#[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize_repr, Deserialize_repr)] +#[repr(u8)] +pub enum NumberFilterConditionRevision { + Equal = 0, + NotEqual = 1, + GreaterThan = 2, + LessThan = 3, + GreaterThanOrEqualTo = 4, + LessThanOrEqualTo = 5, + IsEmpty = 6, + IsNotEmpty = 7, +} + +impl ToString for NumberFilterConditionRevision { + fn to_string(&self) -> String { + (self.clone() as u8).to_string() } } -impl std::convert::From for GridSetting { - fn from(rev: GridSettingRevision) -> Self { - let filter: HashMap = rev - .filter - .into_iter() - .map(|(layout_rev, filter_rev)| (layout_rev.to_string(), filter_rev.into())) - .collect(); +impl FromStr for NumberFilterConditionRevision { + type Err = serde_json::Error; - let group: HashMap = rev - .group - .into_iter() - .map(|(layout_rev, group_rev)| (layout_rev.to_string(), group_rev.into())) - .collect(); - - let sort: HashMap = rev - .sort - .into_iter() - .map(|(layout_rev, sort_rev)| (layout_rev.to_string(), sort_rev.into())) - .collect(); - - GridSetting { filter, group, sort } + fn from_str(s: &str) -> Result { + let rev = serde_json::from_str(s)?; + Ok(rev) } } diff --git a/shared-lib/flowy-sync/src/client_grid/grid_revision_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_revision_pad.rs index 986ce35045..d27e779fd9 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_revision_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_revision_pad.rs @@ -5,8 +5,9 @@ use bytes::Bytes; use flowy_grid_data_model::entities::{FieldChangesetParams, FieldOrder}; use flowy_grid_data_model::entities::{FieldType, GridSettingChangesetParams}; use flowy_grid_data_model::revision::{ - gen_block_id, gen_grid_id, FieldRevision, GridBlockRevision, GridBlockRevisionChangeset, GridFilterRevision, - GridGroupRevision, GridLayoutRevision, GridRevision, GridSettingRevision, GridSortRevision, + gen_block_id, gen_grid_filter_id, gen_grid_group_id, gen_grid_id, gen_grid_sort_id, FieldRevision, + GridBlockRevision, GridBlockRevisionChangeset, GridFilterRevision, GridGroupRevision, GridLayoutRevision, + GridRevision, GridSettingRevision, GridSortRevision, }; use lib_infra::util::move_vec_element; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; @@ -341,34 +342,51 @@ impl GridRevisionPad { let mut is_changed = None; let layout_rev: GridLayoutRevision = changeset.layout_type.into(); - if let Some(filter) = changeset.filter { - grid_rev.setting.filter.insert( - layout_rev.clone(), - GridFilterRevision { - field_id: filter.field_id, - }, - ); + if let Some(params) = changeset.insert_filter { + let rev = GridFilterRevision { + id: gen_grid_filter_id(), + field_id: params.field_id, + info: Default::default(), + }; + grid_rev + .setting + .filter + .entry(layout_rev.clone()) + .or_insert_with(std::vec::Vec::new) + .push(rev); + is_changed = Some(()) } - if let Some(group) = changeset.group { - grid_rev.setting.group.insert( - layout_rev.clone(), - GridGroupRevision { - group_field_id: group.group_field_id, - sub_group_field_id: group.sub_group_field_id, - }, - ); + if let Some(params) = changeset.insert_group { + let rev = GridGroupRevision { + id: gen_grid_group_id(), + field_id: params.field_id, + sub_field_id: params.sub_field_id, + }; + + grid_rev + .setting + .group + .entry(layout_rev.clone()) + .or_insert_with(std::vec::Vec::new) + .push(rev); + is_changed = Some(()) } - if let Some(sort) = changeset.sort { - grid_rev.setting.sort.insert( - layout_rev, - GridSortRevision { - field_id: sort.field_id, - }, - ); + if let Some(sort) = changeset.insert_sort { + let rev = GridSortRevision { + id: gen_grid_sort_id(), + field_id: sort.field_id, + }; + + grid_rev + .setting + .sort + .entry(layout_rev) + .or_insert_with(std::vec::Vec::new) + .push(rev); is_changed = Some(()) }