mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: add filter service
This commit is contained in:
parent
3dddd907b0
commit
f1ac38dd59
@ -1,14 +1,15 @@
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/checkbox_filter.pbenum.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/date_filter.pbenum.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/checkbox_filter.pbserver.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/date_filter.pbserver.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/number_filter.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_option_filter.pbserver.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/setting_entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/text_filter.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/util.pb.dart';
|
||||
import 'package:fixnum/fixnum.dart' as $fixnum;
|
||||
|
||||
class FilterFFIService {
|
||||
final String viewId;
|
||||
@ -19,11 +20,14 @@ class FilterFFIService {
|
||||
required TextFilterCondition condition,
|
||||
String content = "",
|
||||
}) {
|
||||
final filter = TextFilterPB()
|
||||
..condition = condition
|
||||
..content = content;
|
||||
|
||||
return createFilter(
|
||||
fieldId: fieldId,
|
||||
fieldType: FieldType.RichText,
|
||||
condition: condition.value,
|
||||
content: content,
|
||||
data: filter.writeToBuffer(),
|
||||
);
|
||||
}
|
||||
|
||||
@ -31,10 +35,12 @@ class FilterFFIService {
|
||||
required String fieldId,
|
||||
required CheckboxFilterCondition condition,
|
||||
}) {
|
||||
final filter = CheckboxFilterPB()..condition = condition;
|
||||
|
||||
return createFilter(
|
||||
fieldId: fieldId,
|
||||
fieldType: FieldType.Checkbox,
|
||||
condition: condition.value,
|
||||
data: filter.writeToBuffer(),
|
||||
);
|
||||
}
|
||||
|
||||
@ -43,20 +49,42 @@ class FilterFFIService {
|
||||
required NumberFilterCondition condition,
|
||||
String content = "",
|
||||
}) {
|
||||
final filter = NumberFilterPB()
|
||||
..condition = condition
|
||||
..content = content;
|
||||
|
||||
return createFilter(
|
||||
fieldId: fieldId,
|
||||
fieldType: FieldType.Checkbox,
|
||||
condition: condition.value,
|
||||
content: content,
|
||||
fieldType: FieldType.Number,
|
||||
data: filter.writeToBuffer(),
|
||||
);
|
||||
}
|
||||
|
||||
Future<Either<Unit, FlowyError>> createDateFilter({
|
||||
required String fieldId,
|
||||
required DateFilterCondition condition,
|
||||
String content = "",
|
||||
int? start,
|
||||
int? end,
|
||||
int? timestamp,
|
||||
}) {
|
||||
throw UnimplementedError();
|
||||
var filter = DateFilterPB();
|
||||
if (timestamp != null) {
|
||||
filter.timestamp = $fixnum.Int64(timestamp);
|
||||
} else {
|
||||
if (start != null && end != null) {
|
||||
filter.start = $fixnum.Int64(start);
|
||||
filter.end = $fixnum.Int64(end);
|
||||
} else {
|
||||
throw Exception(
|
||||
"Start and end should not be null if the timestamp is null");
|
||||
}
|
||||
}
|
||||
|
||||
return createFilter(
|
||||
fieldId: fieldId,
|
||||
fieldType: FieldType.DateTime,
|
||||
data: filter.writeToBuffer(),
|
||||
);
|
||||
}
|
||||
|
||||
Future<Either<Unit, FlowyError>> createURLFilter({
|
||||
@ -64,11 +92,14 @@ class FilterFFIService {
|
||||
required TextFilterCondition condition,
|
||||
String content = "",
|
||||
}) {
|
||||
final filter = TextFilterPB()
|
||||
..condition = condition
|
||||
..content = content;
|
||||
|
||||
return createFilter(
|
||||
fieldId: fieldId,
|
||||
fieldType: FieldType.URL,
|
||||
condition: condition.value,
|
||||
content: content,
|
||||
data: filter.writeToBuffer(),
|
||||
);
|
||||
}
|
||||
|
||||
@ -77,10 +108,14 @@ class FilterFFIService {
|
||||
required SelectOptionCondition condition,
|
||||
List<String> optionIds = const [],
|
||||
}) {
|
||||
final filter = SelectOptionFilterPB()
|
||||
..condition = condition
|
||||
..optionIds.addAll(optionIds);
|
||||
|
||||
return createFilter(
|
||||
fieldId: fieldId,
|
||||
fieldType: FieldType.SingleSelect,
|
||||
condition: condition.value,
|
||||
data: filter.writeToBuffer(),
|
||||
);
|
||||
}
|
||||
|
||||
@ -89,26 +124,28 @@ class FilterFFIService {
|
||||
required SelectOptionCondition condition,
|
||||
List<String> optionIds = const [],
|
||||
}) {
|
||||
final filter = SelectOptionFilterPB()
|
||||
..condition = condition
|
||||
..optionIds.addAll(optionIds);
|
||||
|
||||
return createFilter(
|
||||
fieldId: fieldId,
|
||||
fieldType: FieldType.MultiSelect,
|
||||
condition: condition.value,
|
||||
data: filter.writeToBuffer(),
|
||||
);
|
||||
}
|
||||
|
||||
Future<Either<Unit, FlowyError>> createFilter({
|
||||
required String fieldId,
|
||||
required FieldType fieldType,
|
||||
required int condition,
|
||||
String content = "",
|
||||
required List<int> data,
|
||||
}) {
|
||||
TextFilterCondition.DoesNotContain.value;
|
||||
|
||||
final insertFilterPayload = CreateFilterPayloadPB.create()
|
||||
..fieldId = fieldId
|
||||
..fieldType = fieldType
|
||||
..condition = condition
|
||||
..content = content;
|
||||
..data = data;
|
||||
|
||||
final payload = GridSettingChangesetPB.create()
|
||||
..gridId = viewId
|
||||
|
@ -1,9 +1,10 @@
|
||||
use crate::entities::parser::NotEmptyStr;
|
||||
use crate::entities::{
|
||||
CheckboxFilterCondition, DateFilterCondition, FieldType, NumberFilterCondition, SelectOptionCondition,
|
||||
TextFilterCondition,
|
||||
CheckboxFilterPB, DateFilterContent, DateFilterPB, FieldType, NumberFilterPB, SelectOptionFilterPB, TextFilterPB,
|
||||
};
|
||||
use crate::services::field::SelectOptionIds;
|
||||
use crate::services::filter::FilterType;
|
||||
use bytes::Bytes;
|
||||
use flowy_derive::ProtoBuf;
|
||||
use flowy_error::ErrorCode;
|
||||
use grid_rev_model::{FieldRevision, FieldTypeRevision, FilterRevision};
|
||||
@ -89,20 +90,17 @@ pub struct CreateFilterPayloadPB {
|
||||
pub field_type: FieldType,
|
||||
|
||||
#[pb(index = 3)]
|
||||
pub condition: u32,
|
||||
|
||||
#[pb(index = 4)]
|
||||
pub content: String,
|
||||
pub data: Vec<u8>,
|
||||
}
|
||||
|
||||
impl CreateFilterPayloadPB {
|
||||
#[allow(dead_code)]
|
||||
pub fn new<T: Into<u32>>(field_rev: &FieldRevision, condition: T, content: String) -> Self {
|
||||
pub fn new<T: TryInto<Bytes, Error = ::protobuf::ProtobufError>>(field_rev: &FieldRevision, data: T) -> Self {
|
||||
let data = data.try_into().unwrap_or_else(|_| Bytes::new());
|
||||
Self {
|
||||
field_id: field_rev.id.clone(),
|
||||
field_type: field_rev.ty.into(),
|
||||
condition: condition.into(),
|
||||
content,
|
||||
data: data.to_vec(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -114,22 +112,39 @@ impl TryInto<CreateFilterParams> for CreateFilterPayloadPB {
|
||||
let field_id = NotEmptyStr::parse(self.field_id)
|
||||
.map_err(|_| ErrorCode::FieldIdIsEmpty)?
|
||||
.0;
|
||||
let condition = self.condition as u8;
|
||||
let condition;
|
||||
let mut content = "".to_string();
|
||||
let bytes: &[u8] = self.data.as_ref();
|
||||
|
||||
match self.field_type {
|
||||
FieldType::RichText | FieldType::URL => {
|
||||
let _ = TextFilterCondition::try_from(condition)?;
|
||||
let filter = TextFilterPB::try_from(bytes).map_err(|_| ErrorCode::ProtobufSerde)?;
|
||||
condition = filter.condition as u8;
|
||||
content = filter.content;
|
||||
}
|
||||
FieldType::Checkbox => {
|
||||
let _ = CheckboxFilterCondition::try_from(condition)?;
|
||||
let filter = CheckboxFilterPB::try_from(bytes).map_err(|_| ErrorCode::ProtobufSerde)?;
|
||||
condition = filter.condition as u8;
|
||||
}
|
||||
FieldType::Number => {
|
||||
let _ = NumberFilterCondition::try_from(condition)?;
|
||||
let filter = NumberFilterPB::try_from(bytes).map_err(|_| ErrorCode::ProtobufSerde)?;
|
||||
condition = filter.condition as u8;
|
||||
content = filter.content;
|
||||
}
|
||||
FieldType::DateTime => {
|
||||
let _ = DateFilterCondition::try_from(condition)?;
|
||||
let filter = DateFilterPB::try_from(bytes).map_err(|_| ErrorCode::ProtobufSerde)?;
|
||||
condition = filter.condition as u8;
|
||||
content = DateFilterContent {
|
||||
start: filter.start,
|
||||
end: filter.end,
|
||||
timestamp: filter.timestamp,
|
||||
}
|
||||
.to_string();
|
||||
}
|
||||
FieldType::SingleSelect | FieldType::MultiSelect => {
|
||||
let _ = SelectOptionCondition::try_from(condition)?;
|
||||
let filter = SelectOptionFilterPB::try_from(bytes).map_err(|_| ErrorCode::ProtobufSerde)?;
|
||||
condition = filter.condition as u8;
|
||||
content = SelectOptionIds::from(filter.option_ids).to_string();
|
||||
}
|
||||
}
|
||||
|
||||
@ -137,7 +152,7 @@ impl TryInto<CreateFilterParams> for CreateFilterPayloadPB {
|
||||
field_id,
|
||||
field_type_rev: self.field_type.into(),
|
||||
condition,
|
||||
content: self.content,
|
||||
content,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -3,8 +3,9 @@
|
||||
#![allow(dead_code)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use bytes::Bytes;
|
||||
use futures::TryFutureExt;
|
||||
use flowy_grid::entities::{CreateFilterParams, CreateFilterPayloadPB, DeleteFilterParams, GridLayout, GridSettingChangesetParams, GridSettingPB, RowPB, TextFilterCondition, FieldType, NumberFilterCondition, CheckboxFilterCondition, DateFilterCondition, DateFilterContent, SelectOptionCondition};
|
||||
use flowy_grid::entities::{CreateFilterParams, CreateFilterPayloadPB, DeleteFilterParams, GridLayout, GridSettingChangesetParams, GridSettingPB, RowPB, TextFilterCondition, FieldType, NumberFilterCondition, CheckboxFilterCondition, DateFilterCondition, DateFilterContent, SelectOptionCondition, TextFilterPB, NumberFilterPB, CheckboxFilterPB, DateFilterPB, SelectOptionFilterPB};
|
||||
use flowy_grid::services::field::SelectOptionIds;
|
||||
use flowy_grid::services::setting::GridSettingChangesetBuilder;
|
||||
use grid_rev_model::{FieldRevision, FieldTypeRevision};
|
||||
@ -85,49 +86,60 @@ impl GridFilterTest {
|
||||
self.insert_filter(payload).await;
|
||||
}
|
||||
FilterScript::CreateTextFilter { condition, content} => {
|
||||
|
||||
let field_rev = self.get_field_rev(FieldType::RichText);
|
||||
let text_filter= TextFilterPB {
|
||||
condition,
|
||||
content
|
||||
};
|
||||
let payload =
|
||||
CreateFilterPayloadPB::new(field_rev, condition, content);
|
||||
CreateFilterPayloadPB::new(field_rev, text_filter);
|
||||
self.insert_filter(payload).await;
|
||||
}
|
||||
FilterScript::CreateNumberFilter {condition, content} => {
|
||||
let field_rev = self.get_field_rev(FieldType::Number);
|
||||
let number_filter = NumberFilterPB {
|
||||
condition,
|
||||
content
|
||||
};
|
||||
let payload =
|
||||
CreateFilterPayloadPB::new(field_rev, condition, content);
|
||||
CreateFilterPayloadPB::new(field_rev, number_filter);
|
||||
self.insert_filter(payload).await;
|
||||
}
|
||||
FilterScript::CreateCheckboxFilter {condition} => {
|
||||
let field_rev = self.get_field_rev(FieldType::Checkbox);
|
||||
let checkbox_filter = CheckboxFilterPB {
|
||||
condition
|
||||
};
|
||||
let payload =
|
||||
CreateFilterPayloadPB::new(field_rev, condition, "".to_string());
|
||||
CreateFilterPayloadPB::new(field_rev, checkbox_filter);
|
||||
self.insert_filter(payload).await;
|
||||
}
|
||||
FilterScript::CreateDateFilter { condition, start, end, timestamp} => {
|
||||
let field_rev = self.get_field_rev(FieldType::DateTime);
|
||||
let content = DateFilterContent {
|
||||
let date_filter = DateFilterPB {
|
||||
condition,
|
||||
start,
|
||||
end,
|
||||
timestamp,
|
||||
}.to_string();
|
||||
let payload =
|
||||
CreateFilterPayloadPB::new(field_rev, condition, content);
|
||||
timestamp
|
||||
};
|
||||
|
||||
let payload =
|
||||
CreateFilterPayloadPB::new(field_rev, date_filter);
|
||||
self.insert_filter(payload).await;
|
||||
}
|
||||
FilterScript::CreateMultiSelectFilter { condition, option_ids} => {
|
||||
let field_rev = self.get_field_rev(FieldType::MultiSelect);
|
||||
let content =
|
||||
SelectOptionIds::from(option_ids).to_string();
|
||||
let filter = SelectOptionFilterPB { condition, option_ids };
|
||||
let payload =
|
||||
CreateFilterPayloadPB::new(field_rev, condition, content);
|
||||
CreateFilterPayloadPB::new(field_rev, filter);
|
||||
self.insert_filter(payload).await;
|
||||
}
|
||||
FilterScript::CreateSingleSelectFilter { condition, option_ids} => {
|
||||
let field_rev = self.get_field_rev(FieldType::SingleSelect);
|
||||
let content =
|
||||
SelectOptionIds::from(option_ids).to_string();
|
||||
let filter = SelectOptionFilterPB { condition, option_ids };
|
||||
let payload =
|
||||
CreateFilterPayloadPB::new(field_rev, condition, content);
|
||||
CreateFilterPayloadPB::new(field_rev, filter);
|
||||
self.insert_filter(payload).await;
|
||||
}
|
||||
FilterScript::AssertFilterCount { count } => {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::grid::filter_test::script::FilterScript::*;
|
||||
use crate::grid::filter_test::script::*;
|
||||
use flowy_grid::entities::{CreateFilterPayloadPB, FieldType, TextFilterCondition};
|
||||
use flowy_grid::entities::{CreateFilterPayloadPB, FieldType, TextFilterCondition, TextFilterPB};
|
||||
use flowy_grid::services::filter::FilterType;
|
||||
|
||||
#[tokio::test]
|
||||
@ -73,7 +73,11 @@ async fn grid_filter_ends_with_text_test() {
|
||||
async fn grid_filter_delete_test() {
|
||||
let mut test = GridFilterTest::new().await;
|
||||
let field_rev = test.get_field_rev(FieldType::RichText).clone();
|
||||
let payload = CreateFilterPayloadPB::new(&field_rev, TextFilterCondition::TextIsEmpty, "".to_string());
|
||||
let text_filter = TextFilterPB {
|
||||
condition: TextFilterCondition::TextIsEmpty,
|
||||
content: "".to_string(),
|
||||
};
|
||||
let payload = CreateFilterPayloadPB::new(&field_rev, text_filter);
|
||||
let scripts = vec![
|
||||
InsertFilter { payload },
|
||||
AssertFilterCount { count: 1 },
|
||||
|
@ -129,6 +129,9 @@ pub enum ErrorCode {
|
||||
#[display(fmt = "Serde")]
|
||||
Serde = 1001,
|
||||
|
||||
#[display(fmt = "Protobuf serde")]
|
||||
ProtobufSerde = 1002,
|
||||
|
||||
#[display(fmt = "Out of bounds")]
|
||||
OutOfBounds = 10001,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user