chore: delete/create filter

This commit is contained in:
appflowy 2022-06-22 17:11:56 +08:00
parent 60675afd1d
commit ead305ddda
16 changed files with 488 additions and 201 deletions

View File

@ -27,7 +27,7 @@ pub(crate) async fn get_grid_setting_handler(
let grid_id: GridId = data.into_inner(); let grid_id: GridId = data.into_inner();
let editor = manager.open_grid(grid_id).await?; let editor = manager.open_grid(grid_id).await?;
let grid_setting = editor.get_grid_setting().await?; let grid_setting = editor.get_grid_setting().await?;
data_result(grid_setting.into()) data_result(grid_setting)
} }
#[tracing::instrument(level = "trace", skip(data, manager), err)] #[tracing::instrument(level = "trace", skip(data, manager), err)]

View File

@ -438,10 +438,19 @@ impl GridRevisionEditor {
}) })
} }
pub async fn get_grid_setting(&self) -> FlowyResult<GridSettingRevision> { pub async fn get_grid_setting(&self) -> FlowyResult<GridSetting> {
let pad_read_guard = self.grid_pad.read().await; let read_guard = self.grid_pad.read().await;
let grid_setting_rev = pad_read_guard.get_grid_setting_rev(); let grid_setting_rev = read_guard.get_grid_setting_rev();
Ok(grid_setting_rev) Ok(grid_setting_rev.into())
}
pub async fn get_grid_filter(&self, layout_type: &GridLayoutType) -> FlowyResult<Vec<GridFilter>> {
let layout_type: GridLayoutRevision = layout_type.clone().into();
let read_guard = self.grid_pad.read().await;
match read_guard.get_grid_setting_rev().filter.get(&layout_type) {
Some(filter_revs) => Ok(filter_revs.iter().map(GridFilter::from).collect::<Vec<GridFilter>>()),
None => Ok(vec![]),
}
} }
pub async fn update_grid_setting(&self, params: GridSettingChangesetParams) -> FlowyResult<()> { pub async fn update_grid_setting(&self, params: GridSettingChangesetParams) -> FlowyResult<()> {

View File

@ -6,3 +6,4 @@ pub mod field;
pub mod grid_editor; pub mod grid_editor;
pub mod persistence; pub mod persistence;
pub mod row; pub mod row;
pub mod setting;

View File

@ -0,0 +1,3 @@
mod setting_builder;
pub use setting_builder::*;

View File

@ -0,0 +1,35 @@
use flowy_grid_data_model::entities::{CreateGridFilterParams, GridLayoutType, GridSettingChangesetParams};
pub struct GridSettingChangesetBuilder {
params: GridSettingChangesetParams,
}
impl GridSettingChangesetBuilder {
pub fn new(grid_id: &str, layout_type: &GridLayoutType) -> Self {
let params = GridSettingChangesetParams {
grid_id: grid_id.to_string(),
layout_type: layout_type.clone(),
insert_filter: None,
delete_filter: None,
insert_group: None,
delete_group: None,
insert_sort: None,
delete_sort: None,
};
Self { params }
}
pub fn insert_filter(mut self, params: CreateGridFilterParams) -> Self {
self.params.insert_filter = Some(params);
self
}
pub fn delete_filter(mut self, filter_id: &str) -> Self {
self.params.delete_filter = Some(filter_id.to_string());
self
}
pub fn build(self) -> GridSettingChangesetParams {
self.params
}
}

View File

@ -2,6 +2,7 @@ use bytes::Bytes;
use flowy_grid::services::field::*; use flowy_grid::services::field::*;
use flowy_grid::services::grid_editor::{GridPadBuilder, GridRevisionEditor}; use flowy_grid::services::grid_editor::{GridPadBuilder, GridRevisionEditor};
use flowy_grid::services::row::CreateRowRevisionPayload; use flowy_grid::services::row::CreateRowRevisionPayload;
use flowy_grid::services::setting::GridSettingChangesetBuilder;
use flowy_grid_data_model::entities::*; use flowy_grid_data_model::entities::*;
use flowy_grid_data_model::revision::*; use flowy_grid_data_model::revision::*;
use flowy_revision::REVISION_WRITE_INTERVAL_IN_MILLIS; use flowy_revision::REVISION_WRITE_INTERVAL_IN_MILLIS;
@ -66,8 +67,17 @@ pub enum EditorScript {
UpdateGridSetting { UpdateGridSetting {
params: GridSettingChangesetParams, params: GridSettingChangesetParams,
}, },
InsertGridTableFilter {
payload: CreateGridFilterPayload,
},
AssertTableFilterCount {
count: i32,
},
DeleteGridTableFilter {
filter_id: String,
},
AssertGridSetting { AssertGridSetting {
expected_setting: GridSettingRevision, expected_setting: GridSetting,
}, },
AssertGridRevisionPad, AssertGridRevisionPad,
} }
@ -239,6 +249,26 @@ impl GridEditorTest {
EditorScript::UpdateGridSetting { params } => { EditorScript::UpdateGridSetting { params } => {
let _ = self.editor.update_grid_setting(params).await.unwrap(); let _ = self.editor.update_grid_setting(params).await.unwrap();
} }
EditorScript::InsertGridTableFilter { payload } => {
let params: CreateGridFilterParams = payload.try_into().unwrap();
let layout_type = GridLayoutType::Table;
let params = GridSettingChangesetBuilder::new(&self.grid_id, &layout_type)
.insert_filter(params)
.build();
let _ = self.editor.update_grid_setting(params).await.unwrap();
}
EditorScript::AssertTableFilterCount { count } => {
let layout_type = GridLayoutType::Table;
let filters = self.editor.get_grid_filter(&layout_type).await.unwrap();
assert_eq!(count as usize, filters.len());
}
EditorScript::DeleteGridTableFilter { filter_id } => {
let layout_type = GridLayoutType::Table;
let params = GridSettingChangesetBuilder::new(&self.grid_id, &layout_type)
.delete_filter(&filter_id)
.build();
let _ = self.editor.update_grid_setting(params).await.unwrap();
}
EditorScript::AssertGridSetting { expected_setting } => { EditorScript::AssertGridSetting { expected_setting } => {
let setting = self.editor.get_grid_setting().await.unwrap(); let setting = self.editor.get_grid_setting().await.unwrap();
assert_eq!(expected_setting, setting); assert_eq!(expected_setting, setting);
@ -262,8 +292,18 @@ impl GridEditorTest {
.row_revs .row_revs
} }
pub(crate) async fn get_grid_setting(&self) -> GridSettingRevision { pub async fn grid_filters(&self) -> Vec<GridFilter> {
self.editor.get_grid_setting().await.unwrap() let layout_type = GridLayoutType::Table;
self.editor.get_grid_filter(&layout_type).await.unwrap()
}
pub fn text_field(&self) -> &FieldRevision {
self.field_revs
.iter()
.filter(|field_rev| field_rev.field_type == FieldType::RichText)
.collect::<Vec<_>>()
.pop()
.unwrap()
} }
} }

View File

@ -1,29 +1,72 @@
use crate::grid::script::EditorScript::*; use crate::grid::script::EditorScript::*;
use crate::grid::script::*; use crate::grid::script::*;
use flowy_grid_data_model::entities::{ use flowy_grid_data_model::entities::{
CreateGridFilterParams, CreateGridFilterPayload, GridLayoutType, GridSettingChangesetParams, CreateGridFilterParams, CreateGridFilterPayload, GridLayoutType, GridSettingChangesetParams, TextFilterCondition,
}; };
use flowy_grid_data_model::revision::GridSettingRevision;
#[tokio::test] #[tokio::test]
async fn grid_setting_create_filter_test() { async fn grid_setting_create_text_filter_test() {
let test = GridEditorTest::new().await; let test = GridEditorTest::new().await;
let field_rev = test.text_field();
let condition = TextFilterCondition::TextIsEmpty as i32;
let layout_type = GridLayoutType::Table; let scripts = vec![
let field_rev = test.field_revs.last().unwrap(); InsertGridTableFilter {
let create_params: CreateGridFilterParams = CreateGridFilterPayload { payload: CreateGridFilterPayload {
field_id: field_rev.id.clone(), field_id: field_rev.id.clone(),
field_type: field_rev.field_type.clone(), field_type: field_rev.field_type.clone(),
} condition,
.try_into() content: Some("abc".to_owned()),
.unwrap(); },
let params = GridSettingChangesetParams::from_insert_filter(&test.grid_id, layout_type, create_params); },
AssertTableFilterCount { count: 1 },
let scripts = vec![UpdateGridSetting { params }]; ];
GridEditorTest::new().await.run_scripts(scripts).await; GridEditorTest::new().await.run_scripts(scripts).await;
// let mut expected_grid_setting = test.get_grid_setting().await;
} }
#[tokio::test]
#[should_panic]
async fn grid_setting_create_text_filter_panic_test() {
let test = GridEditorTest::new().await;
let field_rev = test.text_field();
let scripts = vec![InsertGridTableFilter {
payload: CreateGridFilterPayload {
field_id: field_rev.id.clone(),
field_type: field_rev.field_type.clone(),
condition: 20, // Invalid condition type
content: Some("abc".to_owned()),
},
}];
GridEditorTest::new().await.run_scripts(scripts).await;
}
#[tokio::test]
async fn grid_setting_delete_text_filter_test() {
let mut test = GridEditorTest::new().await;
let field_rev = test.text_field();
let condition = TextFilterCondition::TextIsEmpty as i32;
let scripts = vec![
InsertGridTableFilter {
payload: CreateGridFilterPayload {
field_id: field_rev.id.clone(),
field_type: field_rev.field_type.clone(),
condition,
content: Some("abc".to_owned()),
},
},
AssertTableFilterCount { count: 1 },
];
test.run_scripts(scripts).await;
let filter = test.grid_filters().await.pop().unwrap();
test.run_scripts(vec![
DeleteGridTableFilter { filter_id: filter.id },
AssertTableFilterCount { count: 0 },
])
.await;
}
#[tokio::test] #[tokio::test]
async fn grid_setting_sort_test() {} async fn grid_setting_sort_test() {}

View File

@ -11,6 +11,7 @@ static RUST_TYPE_MAP: phf::Map<&'static str, &'static str> = phf_map! {
"i32" => "int32", "i32" => "int32",
"u64" => "uint64", "u64" => "uint64",
"u32" => "uint32", "u32" => "uint32",
"u8" => "uint8",
"Vec" => "repeated", "Vec" => "repeated",
"f64" => "double", "f64" => "double",
"HashMap" => "map", "HashMap" => "map",

View File

@ -3,49 +3,13 @@ use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use flowy_error_code::ErrorCode; use flowy_error_code::ErrorCode;
use crate::entities::FieldType; use crate::entities::FieldType;
use crate::revision::{ use crate::revision::GridFilterRevision;
FilterInfoRevision, GridFilterRevision, NumberFilterConditionRevision, TextFilterConditionRevision,
};
use std::convert::TryInto; use std::convert::TryInto;
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] #[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
pub struct GridFilter { pub struct GridFilter {
#[pb(index = 1)] #[pb(index = 1)]
pub id: String, 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)] #[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
@ -54,10 +18,16 @@ pub struct RepeatedGridFilter {
pub items: Vec<GridFilter>, pub items: Vec<GridFilter>,
} }
impl std::convert::From<Vec<GridFilterRevision>> for RepeatedGridFilter { impl std::convert::From<&GridFilterRevision> for GridFilter {
fn from(revs: Vec<GridFilterRevision>) -> Self { fn from(rev: &GridFilterRevision) -> Self {
Self { id: rev.id.clone() }
}
}
impl std::convert::From<&Vec<GridFilterRevision>> for RepeatedGridFilter {
fn from(revs: &Vec<GridFilterRevision>) -> Self {
RepeatedGridFilter { RepeatedGridFilter {
items: revs.into_iter().map(|rev| rev.into()).collect(), items: revs.iter().map(|rev| rev.into()).collect(),
} }
} }
} }
@ -75,11 +45,19 @@ pub struct CreateGridFilterPayload {
#[pb(index = 2)] #[pb(index = 2)]
pub field_type: FieldType, pub field_type: FieldType,
#[pb(index = 3)]
pub condition: i32,
#[pb(index = 4, one_of)]
pub content: Option<String>,
} }
pub struct CreateGridFilterParams { pub struct CreateGridFilterParams {
pub field_id: String, pub field_id: String,
pub field_type: FieldType, pub field_type: FieldType,
pub condition: u8,
pub content: Option<String>,
} }
impl TryInto<CreateGridFilterParams> for CreateGridFilterPayload { impl TryInto<CreateGridFilterParams> for CreateGridFilterPayload {
@ -89,14 +67,40 @@ impl TryInto<CreateGridFilterParams> for CreateGridFilterPayload {
let field_id = NotEmptyStr::parse(self.field_id) let field_id = NotEmptyStr::parse(self.field_id)
.map_err(|_| ErrorCode::FieldIdIsEmpty)? .map_err(|_| ErrorCode::FieldIdIsEmpty)?
.0; .0;
let condition = self.condition as u8;
match self.field_type {
FieldType::RichText | FieldType::Checkbox | FieldType::URL => {
let _ = TextFilterCondition::try_from(condition)?;
}
FieldType::Number => {
let _ = NumberFilterCondition::try_from(condition)?;
}
FieldType::DateTime => {
let _ = DateFilterCondition::try_from(condition)?;
}
FieldType::SingleSelect | FieldType::MultiSelect => {
let _ = SelectOptionCondition::try_from(condition)?;
}
}
Ok(CreateGridFilterParams { Ok(CreateGridFilterParams {
field_id, field_id,
field_type: self.field_type, field_type: self.field_type,
condition,
content: self.content,
}) })
} }
} }
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
pub struct GridTextFilter {
#[pb(index = 1)]
pub condition: TextFilterCondition,
#[pb(index = 2, one_of)]
pub content: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum)] #[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum)]
#[repr(u8)] #[repr(u8)]
pub enum TextFilterCondition { pub enum TextFilterCondition {
@ -110,19 +114,45 @@ pub enum TextFilterCondition {
TextIsNotEmpty = 7, TextIsNotEmpty = 7,
} }
impl std::convert::From<TextFilterConditionRevision> for TextFilterCondition { impl std::default::Default for TextFilterCondition {
fn from(rev: TextFilterConditionRevision) -> Self { fn default() -> Self {
match rev { TextFilterCondition::Is
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,
} }
} }
impl std::convert::TryFrom<u8> for TextFilterCondition {
type Error = ErrorCode;
fn try_from(value: u8) -> Result<Self, Self::Error> {
match value {
0 => Ok(TextFilterCondition::Is),
1 => Ok(TextFilterCondition::IsNot),
2 => Ok(TextFilterCondition::Contains),
3 => Ok(TextFilterCondition::DoesNotContain),
4 => Ok(TextFilterCondition::StartsWith),
5 => Ok(TextFilterCondition::EndsWith),
6 => Ok(TextFilterCondition::TextIsEmpty),
7 => Ok(TextFilterCondition::TextIsNotEmpty),
_ => Err(ErrorCode::InvalidData),
}
}
}
impl std::convert::From<GridFilterRevision> for GridTextFilter {
fn from(rev: GridFilterRevision) -> Self {
GridTextFilter {
condition: TextFilterCondition::try_from(rev.condition).unwrap_or(TextFilterCondition::Is),
content: rev.content,
}
}
}
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
pub struct GridNumberFilter {
#[pb(index = 1)]
pub condition: NumberFilterCondition,
#[pb(index = 2, one_of)]
pub content: Option<String>,
} }
#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum)] #[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum)]
@ -137,18 +167,134 @@ pub enum NumberFilterCondition {
NumberIsEmpty = 6, NumberIsEmpty = 6,
NumberIsNotEmpty = 7, NumberIsNotEmpty = 7,
} }
impl std::default::Default for NumberFilterCondition {
fn default() -> Self {
NumberFilterCondition::Equal
}
}
impl std::convert::From<NumberFilterConditionRevision> for NumberFilterCondition { impl std::convert::TryFrom<u8> for NumberFilterCondition {
fn from(rev: NumberFilterConditionRevision) -> Self { type Error = ErrorCode;
match rev {
NumberFilterConditionRevision::Equal => NumberFilterCondition::Equal, fn try_from(n: u8) -> Result<Self, Self::Error> {
NumberFilterConditionRevision::NotEqual => NumberFilterCondition::NotEqual, match n {
NumberFilterConditionRevision::GreaterThan => NumberFilterCondition::GreaterThan, 0 => Ok(NumberFilterCondition::Equal),
NumberFilterConditionRevision::LessThan => NumberFilterCondition::LessThan, 1 => Ok(NumberFilterCondition::NotEqual),
NumberFilterConditionRevision::GreaterThanOrEqualTo => NumberFilterCondition::GreaterThan, 2 => Ok(NumberFilterCondition::GreaterThan),
NumberFilterConditionRevision::LessThanOrEqualTo => NumberFilterCondition::LessThanOrEqualTo, 3 => Ok(NumberFilterCondition::LessThan),
NumberFilterConditionRevision::IsEmpty => NumberFilterCondition::NumberIsEmpty, 4 => Ok(NumberFilterCondition::GreaterThanOrEqualTo),
NumberFilterConditionRevision::IsNotEmpty => NumberFilterCondition::NumberIsNotEmpty, 5 => Ok(NumberFilterCondition::LessThanOrEqualTo),
6 => Ok(NumberFilterCondition::NumberIsEmpty),
7 => Ok(NumberFilterCondition::NumberIsNotEmpty),
_ => Err(ErrorCode::InvalidData),
}
}
}
impl std::convert::From<GridFilterRevision> for GridNumberFilter {
fn from(rev: GridFilterRevision) -> Self {
GridNumberFilter {
condition: NumberFilterCondition::try_from(rev.condition).unwrap_or(NumberFilterCondition::Equal),
content: rev.content,
}
}
}
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
pub struct GridSelectOptionFilter {
#[pb(index = 1)]
pub condition: SelectOptionCondition,
#[pb(index = 2, one_of)]
pub content: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum)]
#[repr(u8)]
pub enum SelectOptionCondition {
OptionIs = 0,
OptionIsNot = 1,
OptionIsEmpty = 2,
OptionIsNotEmpty = 3,
}
impl std::default::Default for SelectOptionCondition {
fn default() -> Self {
SelectOptionCondition::OptionIs
}
}
impl std::convert::TryFrom<u8> for SelectOptionCondition {
type Error = ErrorCode;
fn try_from(value: u8) -> Result<Self, Self::Error> {
match value {
0 => Ok(SelectOptionCondition::OptionIs),
1 => Ok(SelectOptionCondition::OptionIsNot),
2 => Ok(SelectOptionCondition::OptionIsEmpty),
3 => Ok(SelectOptionCondition::OptionIsNotEmpty),
_ => Err(ErrorCode::InvalidData),
}
}
}
impl std::convert::From<GridFilterRevision> for GridSelectOptionFilter {
fn from(rev: GridFilterRevision) -> Self {
GridSelectOptionFilter {
condition: SelectOptionCondition::try_from(rev.condition).unwrap_or(SelectOptionCondition::OptionIs),
content: rev.content,
}
}
}
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
pub struct GridDateFilter {
#[pb(index = 1)]
pub condition: DateFilterCondition,
#[pb(index = 2, one_of)]
pub content: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum)]
#[repr(u8)]
pub enum DateFilterCondition {
DateIs = 0,
DateBefore = 1,
DateAfter = 2,
DateOnOrBefore = 3,
DateOnOrAfter = 4,
DateWithIn = 5,
DateIsEmpty = 6,
}
impl std::default::Default for DateFilterCondition {
fn default() -> Self {
DateFilterCondition::DateIs
}
}
impl std::convert::TryFrom<u8> for DateFilterCondition {
type Error = ErrorCode;
fn try_from(value: u8) -> Result<Self, Self::Error> {
match value {
0 => Ok(DateFilterCondition::DateIs),
1 => Ok(DateFilterCondition::DateBefore),
2 => Ok(DateFilterCondition::DateAfter),
3 => Ok(DateFilterCondition::DateOnOrBefore),
4 => Ok(DateFilterCondition::DateOnOrAfter),
5 => Ok(DateFilterCondition::DateWithIn),
6 => Ok(DateFilterCondition::DateIsEmpty),
_ => Err(ErrorCode::InvalidData),
}
}
}
impl std::convert::From<GridFilterRevision> for GridDateFilter {
fn from(rev: GridFilterRevision) -> Self {
GridDateFilter {
condition: DateFilterCondition::try_from(rev.condition).unwrap_or(DateFilterCondition::DateIs),
content: rev.content,
} }
} }
} }

View File

@ -17,12 +17,12 @@ pub struct GridGroup {
pub sub_group_field_id: Option<String>, pub sub_group_field_id: Option<String>,
} }
impl std::convert::From<GridGroupRevision> for GridGroup { impl std::convert::From<&GridGroupRevision> for GridGroup {
fn from(rev: GridGroupRevision) -> Self { fn from(rev: &GridGroupRevision) -> Self {
GridGroup { GridGroup {
id: rev.id, id: rev.id.clone(),
group_field_id: rev.field_id, group_field_id: rev.field_id.clone(),
sub_group_field_id: rev.sub_field_id, sub_group_field_id: rev.sub_field_id.clone(),
} }
} }
} }
@ -39,10 +39,10 @@ impl std::convert::From<Vec<GridGroup>> for RepeatedGridGroup {
} }
} }
impl std::convert::From<Vec<GridGroupRevision>> for RepeatedGridGroup { impl std::convert::From<&Vec<GridGroupRevision>> for RepeatedGridGroup {
fn from(revs: Vec<GridGroupRevision>) -> Self { fn from(revs: &Vec<GridGroupRevision>) -> Self {
RepeatedGridGroup { RepeatedGridGroup {
items: revs.into_iter().map(|rev| rev.into()).collect(), items: revs.iter().map(|rev| rev.into()).collect(),
} }
} }
} }

View File

@ -21,23 +21,23 @@ pub struct GridSetting {
pub sorts_by_layout_ty: HashMap<String, RepeatedGridSort>, pub sorts_by_layout_ty: HashMap<String, RepeatedGridSort>,
} }
impl std::convert::From<GridSettingRevision> for GridSetting { impl std::convert::From<&GridSettingRevision> for GridSetting {
fn from(rev: GridSettingRevision) -> Self { fn from(rev: &GridSettingRevision) -> Self {
let filters_by_layout_ty: HashMap<String, RepeatedGridFilter> = rev let filters_by_layout_ty: HashMap<String, RepeatedGridFilter> = rev
.filter .filter
.into_iter() .iter()
.map(|(layout_rev, filter_revs)| (layout_rev.to_string(), filter_revs.into())) .map(|(layout_rev, filter_revs)| (layout_rev.to_string(), filter_revs.into()))
.collect(); .collect();
let groups_by_layout_ty: HashMap<String, RepeatedGridGroup> = rev let groups_by_layout_ty: HashMap<String, RepeatedGridGroup> = rev
.group .group
.into_iter() .iter()
.map(|(layout_rev, group_revs)| (layout_rev.to_string(), group_revs.into())) .map(|(layout_rev, group_revs)| (layout_rev.to_string(), group_revs.into()))
.collect(); .collect();
let sorts_by_layout_ty: HashMap<String, RepeatedGridSort> = rev let sorts_by_layout_ty: HashMap<String, RepeatedGridSort> = rev
.sort .sort
.into_iter() .iter()
.map(|(layout_rev, sort_revs)| (layout_rev.to_string(), sort_revs.into())) .map(|(layout_rev, sort_revs)| (layout_rev.to_string(), sort_revs.into()))
.collect(); .collect();
@ -118,34 +118,6 @@ pub struct GridSettingChangesetParams {
pub delete_sort: Option<String>, 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 {
type Error = ErrorCode; type Error = ErrorCode;

View File

@ -14,11 +14,12 @@ pub struct GridSort {
pub field_id: Option<String>, pub field_id: Option<String>,
} }
impl std::convert::From<GridSortRevision> for GridSort { impl std::convert::From<&GridSortRevision> for GridSort {
fn from(rev: GridSortRevision) -> Self { fn from(rev: &GridSortRevision) -> Self {
GridSort { GridSort {
id: rev.id, id: rev.id.clone(),
field_id: rev.field_id,
field_id: rev.field_id.clone(),
} }
} }
} }
@ -29,10 +30,10 @@ pub struct RepeatedGridSort {
pub items: Vec<GridSort>, pub items: Vec<GridSort>,
} }
impl std::convert::From<Vec<GridSortRevision>> for RepeatedGridSort { impl std::convert::From<&Vec<GridSortRevision>> for RepeatedGridSort {
fn from(revs: Vec<GridSortRevision>) -> Self { fn from(revs: &Vec<GridSortRevision>) -> Self {
RepeatedGridSort { RepeatedGridSort {
items: revs.into_iter().map(|rev| rev.into()).collect(), items: revs.iter().map(|rev| rev.into()).collect(),
} }
} }
} }

View File

@ -0,0 +1,94 @@
use crate::entities::NumberFilterCondition;
use indexmap::IndexMap;
use nanoid::nanoid;
use serde::{Deserialize, Serialize};
use serde_repr::*;
use std::str::FromStr;
#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
pub struct GridFilterRevision {
pub id: String,
pub field_id: String,
pub condition: u8,
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 FromStr for TextFilterConditionRevision {
type Err = serde_json::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let rev = serde_json::from_str(s)?;
Ok(rev)
}
}
#[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 FromStr for NumberFilterConditionRevision {
type Err = serde_json::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let rev = serde_json::from_str(s)?;
Ok(rev)
}
}
#[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize_repr, Deserialize_repr)]
#[repr(u8)]
pub enum SelectOptionConditionRevision {
OptionIs = 0,
OptionIsNot = 1,
OptionIsEmpty = 2,
OptionIsNotEmpty = 3,
}
impl ToString for SelectOptionConditionRevision {
fn to_string(&self) -> String {
(self.clone() as u8).to_string()
}
}
impl FromStr for SelectOptionConditionRevision {
type Err = serde_json::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let rev = serde_json::from_str(s)?;
Ok(rev)
}
}

View File

@ -31,6 +31,8 @@ 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(default)]
pub setting: GridSettingRevision, pub setting: GridSettingRevision,
} }

View File

@ -2,7 +2,6 @@ use indexmap::IndexMap;
use nanoid::nanoid; use nanoid::nanoid;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_repr::*; use serde_repr::*;
use std::str::FromStr;
pub fn gen_grid_filter_id() -> String { pub fn gen_grid_filter_id() -> String {
nanoid!(6) nanoid!(6)
@ -52,7 +51,8 @@ impl std::default::Default for GridLayoutRevision {
pub struct GridFilterRevision { pub struct GridFilterRevision {
pub id: String, pub id: String,
pub field_id: String, pub field_id: String,
pub info: FilterInfoRevision, pub condition: u8,
pub content: Option<String>,
} }
#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)] #[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
@ -67,65 +67,3 @@ pub struct GridSortRevision {
pub id: String, pub id: String,
pub field_id: Option<String>, pub field_id: Option<String>,
} }
#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
pub struct FilterInfoRevision {
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 FromStr for TextFilterConditionRevision {
type Err = serde_json::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let rev = serde_json::from_str(s)?;
Ok(rev)
}
}
#[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 FromStr for NumberFilterConditionRevision {
type Err = serde_json::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let rev = serde_json::from_str(s)?;
Ok(rev)
}
}

View File

@ -330,8 +330,8 @@ impl GridRevisionPad {
}) })
} }
pub fn get_grid_setting_rev(&self) -> GridSettingRevision { pub fn get_grid_setting_rev(&self) -> &GridSettingRevision {
self.grid_rev.setting.clone() &self.grid_rev.setting
} }
pub fn update_grid_setting_rev( pub fn update_grid_setting_rev(
@ -346,8 +346,10 @@ impl GridRevisionPad {
let rev = GridFilterRevision { let rev = GridFilterRevision {
id: gen_grid_filter_id(), id: gen_grid_filter_id(),
field_id: params.field_id, field_id: params.field_id,
info: Default::default(), condition: params.condition,
content: params.content,
}; };
grid_rev grid_rev
.setting .setting
.filter .filter