chore: add grid filter test

This commit is contained in:
appflowy
2022-06-21 16:56:50 +08:00
parent 706893f6fa
commit 60675afd1d
13 changed files with 581 additions and 184 deletions

View File

@ -11,7 +11,7 @@ pub fn create(grid_manager: Arc<GridManager>) -> Module {
.event(GridEvent::GetGridData, get_grid_data_handler) .event(GridEvent::GetGridData, get_grid_data_handler)
.event(GridEvent::GetGridBlocks, get_grid_blocks_handler) .event(GridEvent::GetGridBlocks, get_grid_blocks_handler)
.event(GridEvent::GetGridSetting, get_grid_setting_handler) .event(GridEvent::GetGridSetting, get_grid_setting_handler)
.event(GridEvent::UpdateGridSetting, get_grid_setting_handler) .event(GridEvent::UpdateGridSetting, update_grid_setting_handler)
// Field // Field
.event(GridEvent::GetFields, get_fields_handler) .event(GridEvent::GetFields, get_fields_handler)
.event(GridEvent::UpdateField, update_field_handler) .event(GridEvent::UpdateField, update_field_handler)

View File

@ -261,6 +261,10 @@ impl GridEditorTest {
.unwrap() .unwrap()
.row_revs .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) { pub fn create_text_field(grid_id: &str) -> (InsertFieldParams, FieldRevision) {

View File

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

View File

@ -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<GridFilterRevision> 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<String>,
#[pb(index = 2, one_of)]
pub content: Option<String>,
}
impl std::convert::From<FilterInfoRevision> 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<GridFilter>,
}
impl std::convert::From<Vec<GridFilterRevision>> for RepeatedGridFilter {
fn from(revs: Vec<GridFilterRevision>) -> Self {
RepeatedGridFilter {
items: revs.into_iter().map(|rev| rev.into()).collect(),
}
}
}
impl std::convert::From<Vec<GridFilter>> for RepeatedGridFilter {
fn from(items: Vec<GridFilter>) -> 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<CreateGridFilterParams> for CreateGridFilterPayload {
type Error = ErrorCode;
fn try_into(self) -> Result<CreateGridFilterParams, Self::Error> {
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<TextFilterConditionRevision> 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<NumberFilterConditionRevision> 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,
}
}
}

View File

@ -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<String>,
#[pb(index = 3, one_of)]
pub sub_group_field_id: Option<String>,
}
impl std::convert::From<GridGroupRevision> 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<GridGroup>,
}
impl std::convert::From<Vec<GridGroup>> for RepeatedGridGroup {
fn from(items: Vec<GridGroup>) -> Self {
Self { items }
}
}
impl std::convert::From<Vec<GridGroupRevision>> for RepeatedGridGroup {
fn from(revs: Vec<GridGroupRevision>) -> 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<String>,
#[pb(index = 2, one_of)]
pub sub_field_id: Option<String>,
}
pub struct CreateGridGroupParams {
pub field_id: Option<String>,
pub sub_field_id: Option<String>,
}
impl TryInto<CreateGridGroupParams> for CreateGridGroupPayload {
type Error = ErrorCode;
fn try_into(self) -> Result<CreateGridGroupParams, Self::Error> {
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 })
}
}

View File

@ -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_derive::{ProtoBuf, ProtoBuf_Enum};
use flowy_error_code::ErrorCode; use flowy_error_code::ErrorCode;
use std::collections::HashMap; use std::collections::HashMap;
@ -7,13 +12,41 @@ use std::convert::TryInto;
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] #[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
pub struct GridSetting { pub struct GridSetting {
#[pb(index = 1)] #[pb(index = 1)]
pub filter: HashMap<String, GridFilter>, pub filters_by_layout_ty: HashMap<String, RepeatedGridFilter>,
#[pb(index = 2)] #[pb(index = 2)]
pub group: HashMap<String, GridGroup>, pub groups_by_layout_ty: HashMap<String, RepeatedGridGroup>,
#[pb(index = 3)] #[pb(index = 3)]
pub sort: HashMap<String, GridSort>, pub sorts_by_layout_ty: HashMap<String, RepeatedGridSort>,
}
impl std::convert::From<GridSettingRevision> for GridSetting {
fn from(rev: GridSettingRevision) -> Self {
let filters_by_layout_ty: HashMap<String, RepeatedGridFilter> = rev
.filter
.into_iter()
.map(|(layout_rev, filter_revs)| (layout_rev.to_string(), filter_revs.into()))
.collect();
let groups_by_layout_ty: HashMap<String, RepeatedGridGroup> = rev
.group
.into_iter()
.map(|(layout_rev, group_revs)| (layout_rev.to_string(), group_revs.into()))
.collect();
let sorts_by_layout_ty: HashMap<String, RepeatedGridSort> = 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)] #[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum)]
@ -29,25 +62,22 @@ impl std::default::Default for GridLayoutType {
} }
} }
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] impl std::convert::From<GridLayoutRevision> for GridLayoutType {
pub struct GridFilter { fn from(rev: GridLayoutRevision) -> Self {
#[pb(index = 1, one_of)] match rev {
pub field_id: Option<String>, GridLayoutRevision::Table => GridLayoutType::Table,
GridLayoutRevision::Board => GridLayoutType::Board,
}
}
} }
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] impl std::convert::From<GridLayoutType> for GridLayoutRevision {
pub struct GridGroup { fn from(layout: GridLayoutType) -> Self {
#[pb(index = 1, one_of)] match layout {
pub group_field_id: Option<String>, GridLayoutType::Table => GridLayoutRevision::Table,
GridLayoutType::Board => GridLayoutRevision::Board,
#[pb(index = 2, one_of)] }
pub sub_group_field_id: Option<String>,
} }
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
pub struct GridSort {
#[pb(index = 1, one_of)]
pub field_id: Option<String>,
} }
#[derive(Default, ProtoBuf)] #[derive(Default, ProtoBuf)]
@ -59,21 +89,61 @@ pub struct GridSettingChangesetPayload {
pub layout_type: GridLayoutType, pub layout_type: GridLayoutType,
#[pb(index = 3, one_of)] #[pb(index = 3, one_of)]
pub filter: Option<GridFilter>, pub insert_filter: Option<CreateGridFilterPayload>,
#[pb(index = 4, one_of)] #[pb(index = 4, one_of)]
pub group: Option<GridGroup>, pub delete_filter: Option<String>,
#[pb(index = 5, one_of)] #[pb(index = 5, one_of)]
pub sort: Option<GridSort>, pub insert_group: Option<CreateGridGroupPayload>,
#[pb(index = 6, one_of)]
pub delete_group: Option<String>,
#[pb(index = 7, one_of)]
pub insert_sort: Option<CreateGridSortPayload>,
#[pb(index = 8, one_of)]
pub delete_sort: Option<String>,
} }
pub struct GridSettingChangesetParams { pub struct GridSettingChangesetParams {
pub grid_id: String, pub grid_id: String,
pub layout_type: GridLayoutType, pub layout_type: GridLayoutType,
pub filter: Option<GridFilter>, pub insert_filter: Option<CreateGridFilterParams>,
pub group: Option<GridGroup>, pub delete_filter: Option<String>,
pub sort: Option<GridSort>, pub insert_group: Option<CreateGridGroupParams>,
pub delete_group: Option<String>,
pub insert_sort: Option<CreateGridSortParams>,
pub delete_sort: Option<String>,
}
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<GridSettingChangesetParams> for GridSettingChangesetPayload { impl TryInto<GridSettingChangesetParams> for GridSettingChangesetPayload {
@ -84,27 +154,45 @@ impl TryInto<GridSettingChangesetParams> for GridSettingChangesetPayload {
.map_err(|_| ErrorCode::FieldIdIsEmpty)? .map_err(|_| ErrorCode::FieldIdIsEmpty)?
.0; .0;
let filter = match self.filter { let insert_filter = match self.insert_filter {
None => None, 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, 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, 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 { Ok(GridSettingChangesetParams {
grid_id: view_id, grid_id: view_id,
layout_type: self.layout_type, layout_type: self.layout_type,
filter, insert_filter,
group, delete_filter,
sort, insert_group,
delete_group,
insert_sort,
delete_sort,
}) })
} }
} }

View File

@ -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<String>,
}
impl std::convert::From<GridSortRevision> 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<GridSort>,
}
impl std::convert::From<Vec<GridSortRevision>> for RepeatedGridSort {
fn from(revs: Vec<GridSortRevision>) -> Self {
RepeatedGridSort {
items: revs.into_iter().map(|rev| rev.into()).collect(),
}
}
}
impl std::convert::From<Vec<GridSort>> for RepeatedGridSort {
fn from(items: Vec<GridSort>) -> Self {
Self { items }
}
}
#[derive(ProtoBuf, Debug, Default, Clone)]
pub struct CreateGridSortPayload {
#[pb(index = 1, one_of)]
pub field_id: Option<String>,
}
pub struct CreateGridSortParams {
pub field_id: Option<String>,
}
impl TryInto<CreateGridSortParams> for CreateGridSortPayload {
type Error = ErrorCode;
fn try_into(self) -> Result<CreateGridSortParams, Self::Error> {
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 })
}
}

View File

@ -1,7 +1,13 @@
mod field; mod field;
mod grid; mod grid;
mod grid_filter;
mod grid_group;
mod grid_setting; mod grid_setting;
mod grid_sort;
pub use field::*; pub use field::*;
pub use grid::*; pub use grid::*;
pub use grid_filter::*;
pub use grid_group::*;
pub use grid_setting::*; pub use grid_setting::*;
pub use grid_sort::*;

View File

@ -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<GridFilter, ErrorCode> {
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<GridGroup, ErrorCode> {
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<GridSort, ErrorCode> {
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 })
}
}

View File

@ -1,5 +1,2 @@
mod grid_info_parser;
mod str_parser; mod str_parser;
pub use grid_info_parser::*;
pub use str_parser::*; pub use str_parser::*;

View File

@ -31,8 +31,6 @@ pub struct GridRevision {
pub grid_id: String, pub grid_id: String,
pub fields: Vec<FieldRevision>, pub fields: Vec<FieldRevision>,
pub blocks: Vec<GridBlockRevision>, pub blocks: Vec<GridBlockRevision>,
#[serde(skip)]
pub setting: GridSettingRevision, pub setting: GridSettingRevision,
} }

View File

@ -1,19 +1,31 @@
use crate::entities::{GridFilter, GridGroup, GridLayoutType, GridSetting, GridSort};
use indexmap::IndexMap; use indexmap::IndexMap;
use nanoid::nanoid;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_repr::*; 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)] #[derive(Debug, Clone, Serialize, Deserialize, Default, Eq, PartialEq)]
pub struct GridSettingRevision { pub struct GridSettingRevision {
#[serde(with = "indexmap::serde_seq")] #[serde(with = "indexmap::serde_seq")]
pub filter: IndexMap<GridLayoutRevision, GridFilterRevision>, pub filter: IndexMap<GridLayoutRevision, Vec<GridFilterRevision>>,
#[serde(with = "indexmap::serde_seq")] #[serde(skip, with = "indexmap::serde_seq")]
pub group: IndexMap<GridLayoutRevision, GridGroupRevision>, pub group: IndexMap<GridLayoutRevision, Vec<GridGroupRevision>>,
#[serde(with = "indexmap::serde_seq")] #[serde(skip, with = "indexmap::serde_seq")]
pub sort: IndexMap<GridLayoutRevision, GridSortRevision>, pub sort: IndexMap<GridLayoutRevision, Vec<GridSortRevision>>,
} }
#[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize_repr, Deserialize_repr)] #[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize_repr, Deserialize_repr)]
@ -36,81 +48,84 @@ impl std::default::Default for GridLayoutRevision {
} }
} }
impl std::convert::From<GridLayoutRevision> for GridLayoutType {
fn from(rev: GridLayoutRevision) -> Self {
match rev {
GridLayoutRevision::Table => GridLayoutType::Table,
GridLayoutRevision::Board => GridLayoutType::Board,
}
}
}
impl std::convert::From<GridLayoutType> 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)] #[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
pub struct GridFilterRevision { pub struct GridFilterRevision {
pub field_id: Option<String>, pub id: String,
pub field_id: String,
pub info: FilterInfoRevision,
} }
#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)] #[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
pub struct GridGroupRevision { pub struct GridGroupRevision {
pub group_field_id: Option<String>, pub id: String,
pub sub_group_field_id: Option<String>, pub field_id: Option<String>,
pub sub_field_id: Option<String>,
} }
#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)] #[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
pub struct GridSortRevision { pub struct GridSortRevision {
pub id: String,
pub field_id: Option<String>, pub field_id: Option<String>,
} }
impl std::convert::From<GridFilterRevision> for GridFilter { #[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
fn from(rev: GridFilterRevision) -> Self { pub struct FilterInfoRevision {
GridFilter { field_id: rev.field_id } pub condition: Option<String>,
pub content: Option<String>,
}
#[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<GridGroupRevision> for GridGroup { impl FromStr for TextFilterConditionRevision {
fn from(rev: GridGroupRevision) -> Self { type Err = serde_json::Error;
GridGroup {
group_field_id: rev.group_field_id, fn from_str(s: &str) -> Result<Self, Self::Err> {
sub_group_field_id: rev.sub_group_field_id, let rev = serde_json::from_str(s)?;
} Ok(rev)
} }
} }
impl std::convert::From<GridSortRevision> for GridSort { #[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize_repr, Deserialize_repr)]
fn from(rev: GridSortRevision) -> Self { #[repr(u8)]
GridSort { field_id: rev.field_id } 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<GridSettingRevision> for GridSetting { impl FromStr for NumberFilterConditionRevision {
fn from(rev: GridSettingRevision) -> Self { type Err = serde_json::Error;
let filter: HashMap<String, GridFilter> = rev
.filter
.into_iter()
.map(|(layout_rev, filter_rev)| (layout_rev.to_string(), filter_rev.into()))
.collect();
let group: HashMap<String, GridGroup> = rev fn from_str(s: &str) -> Result<Self, Self::Err> {
.group let rev = serde_json::from_str(s)?;
.into_iter() Ok(rev)
.map(|(layout_rev, group_rev)| (layout_rev.to_string(), group_rev.into()))
.collect();
let sort: HashMap<String, GridSort> = rev
.sort
.into_iter()
.map(|(layout_rev, sort_rev)| (layout_rev.to_string(), sort_rev.into()))
.collect();
GridSetting { filter, group, sort }
} }
} }

View File

@ -5,8 +5,9 @@ use bytes::Bytes;
use flowy_grid_data_model::entities::{FieldChangesetParams, FieldOrder}; use flowy_grid_data_model::entities::{FieldChangesetParams, FieldOrder};
use flowy_grid_data_model::entities::{FieldType, GridSettingChangesetParams}; use flowy_grid_data_model::entities::{FieldType, GridSettingChangesetParams};
use flowy_grid_data_model::revision::{ use flowy_grid_data_model::revision::{
gen_block_id, gen_grid_id, FieldRevision, GridBlockRevision, GridBlockRevisionChangeset, GridFilterRevision, gen_block_id, gen_grid_filter_id, gen_grid_group_id, gen_grid_id, gen_grid_sort_id, FieldRevision,
GridGroupRevision, GridLayoutRevision, GridRevision, GridSettingRevision, GridSortRevision, GridBlockRevision, GridBlockRevisionChangeset, GridFilterRevision, GridGroupRevision, GridLayoutRevision,
GridRevision, GridSettingRevision, GridSortRevision,
}; };
use lib_infra::util::move_vec_element; use lib_infra::util::move_vec_element;
use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder};
@ -341,34 +342,51 @@ impl GridRevisionPad {
let mut is_changed = None; let mut is_changed = None;
let layout_rev: GridLayoutRevision = changeset.layout_type.into(); let layout_rev: GridLayoutRevision = changeset.layout_type.into();
if let Some(filter) = changeset.filter { if let Some(params) = changeset.insert_filter {
grid_rev.setting.filter.insert( let rev = GridFilterRevision {
layout_rev.clone(), id: gen_grid_filter_id(),
GridFilterRevision { field_id: params.field_id,
field_id: filter.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(()) is_changed = Some(())
} }
if let Some(group) = changeset.group { if let Some(params) = changeset.insert_group {
grid_rev.setting.group.insert( let rev = GridGroupRevision {
layout_rev.clone(), id: gen_grid_group_id(),
GridGroupRevision { field_id: params.field_id,
group_field_id: group.group_field_id, sub_field_id: params.sub_field_id,
sub_group_field_id: group.sub_group_field_id, };
},
); grid_rev
.setting
.group
.entry(layout_rev.clone())
.or_insert_with(std::vec::Vec::new)
.push(rev);
is_changed = Some(()) is_changed = Some(())
} }
if let Some(sort) = changeset.sort { if let Some(sort) = changeset.insert_sort {
grid_rev.setting.sort.insert( let rev = GridSortRevision {
layout_rev, id: gen_grid_sort_id(),
GridSortRevision {
field_id: sort.field_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(()) is_changed = Some(())
} }