chore: refactor multi-select type option and add GroupPB

This commit is contained in:
appflowy 2022-08-11 13:04:45 +08:00
parent 29ea3c83c8
commit aae2d96a4f
34 changed files with 561 additions and 245 deletions

View File

@ -0,0 +1,20 @@
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
class BoardGroupService {
final String gridId;
GridFieldPB? groupField;
BoardGroupService(this.gridId);
void setGroupField(GridFieldPB field) {
groupField = field;
}
}
abstract class CanBeGroupField {
String get groupContent;
}
// class SingleSelectGroup extends CanBeGroupField {
// final SingleSelectTypeOptionContext typeOptionContext;
// }

View File

@ -4,22 +4,29 @@ import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
import 'dart:async';
import 'select_option_type_option_bloc.dart';
import 'type_option_context.dart';
import 'type_option_data_controller.dart';
import 'type_option_service.dart';
import 'package:protobuf/protobuf.dart';
class MultiSelectTypeOptionContext
extends TypeOptionContext<MultiSelectTypeOption> with ISelectOptionAction {
class MultiSelectAction with ISelectOptionAction {
final String gridId;
final String fieldId;
final TypeOptionFFIService service;
final MultiSelectTypeOptionContext typeOptionContext;
MultiSelectTypeOptionContext({
required MultiSelectTypeOptionWidgetDataParser dataParser,
required TypeOptionDataController dataController,
MultiSelectAction({
required this.gridId,
required this.fieldId,
required this.typeOptionContext,
}) : service = TypeOptionFFIService(
gridId: dataController.gridId,
fieldId: dataController.field.id,
),
super(dataParser: dataParser, dataController: dataController);
gridId: gridId,
fieldId: fieldId,
);
MultiSelectTypeOptionPB get typeOption => typeOptionContext.typeOption;
set typeOption(MultiSelectTypeOptionPB newTypeOption) {
typeOptionContext.typeOption = newTypeOption;
}
@override
List<SelectOptionPB> Function(SelectOptionPB) get deleteOption {

View File

@ -0,0 +1,195 @@
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_type_option.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
import 'package:dartz/dartz.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/multi_select_type_option.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/number_type_option.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/single_select_type_option.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/text_type_option.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/url_type_option.pb.dart';
import 'package:protobuf/protobuf.dart';
import 'type_option_data_controller.dart';
abstract class TypeOptionDataParser<T> {
T fromBuffer(List<int> buffer);
}
// Number
typedef NumberTypeOptionContext = TypeOptionContext<NumberTypeOption>;
class NumberTypeOptionWidgetDataParser
extends TypeOptionDataParser<NumberTypeOption> {
@override
NumberTypeOption fromBuffer(List<int> buffer) {
return NumberTypeOption.fromBuffer(buffer);
}
}
// RichText
typedef RichTextTypeOptionContext = TypeOptionContext<RichTextTypeOption>;
class RichTextTypeOptionWidgetDataParser
extends TypeOptionDataParser<RichTextTypeOption> {
@override
RichTextTypeOption fromBuffer(List<int> buffer) {
return RichTextTypeOption.fromBuffer(buffer);
}
}
// Checkbox
typedef CheckboxTypeOptionContext = TypeOptionContext<CheckboxTypeOption>;
class CheckboxTypeOptionWidgetDataParser
extends TypeOptionDataParser<CheckboxTypeOption> {
@override
CheckboxTypeOption fromBuffer(List<int> buffer) {
return CheckboxTypeOption.fromBuffer(buffer);
}
}
// URL
typedef URLTypeOptionContext = TypeOptionContext<URLTypeOption>;
class URLTypeOptionWidgetDataParser
extends TypeOptionDataParser<URLTypeOption> {
@override
URLTypeOption fromBuffer(List<int> buffer) {
return URLTypeOption.fromBuffer(buffer);
}
}
// Date
typedef DateTypeOptionContext = TypeOptionContext<DateTypeOption>;
class DateTypeOptionDataParser extends TypeOptionDataParser<DateTypeOption> {
@override
DateTypeOption fromBuffer(List<int> buffer) {
return DateTypeOption.fromBuffer(buffer);
}
}
// SingleSelect
typedef SingleSelectTypeOptionContext
= TypeOptionContext<SingleSelectTypeOptionPB>;
class SingleSelectTypeOptionWidgetDataParser
extends TypeOptionDataParser<SingleSelectTypeOptionPB> {
@override
SingleSelectTypeOptionPB fromBuffer(List<int> buffer) {
return SingleSelectTypeOptionPB.fromBuffer(buffer);
}
}
// Multi-select
typedef MultiSelectTypeOptionContext
= TypeOptionContext<MultiSelectTypeOptionPB>;
class MultiSelectTypeOptionWidgetDataParser
extends TypeOptionDataParser<MultiSelectTypeOptionPB> {
@override
MultiSelectTypeOptionPB fromBuffer(List<int> buffer) {
return MultiSelectTypeOptionPB.fromBuffer(buffer);
}
}
class TypeOptionContext<T extends GeneratedMessage> {
T? _typeOptionObject;
final TypeOptionDataParser<T> dataParser;
final TypeOptionDataController _dataController;
TypeOptionContext({
required this.dataParser,
required TypeOptionDataController dataController,
}) : _dataController = dataController;
String get gridId => _dataController.gridId;
String get fieldId => _dataController.field.id;
Future<void> loadTypeOptionData({
required void Function(T) onCompleted,
required void Function(FlowyError) onError,
}) async {
await _dataController.loadTypeOptionData().then((result) {
result.fold((l) => null, (err) => onError(err));
});
onCompleted(typeOption);
}
T get typeOption {
if (_typeOptionObject != null) {
return _typeOptionObject!;
}
final T object = _dataController.getTypeOption(dataParser);
_typeOptionObject = object;
return object;
}
set typeOption(T typeOption) {
_dataController.typeOptionData = typeOption.writeToBuffer();
_typeOptionObject = typeOption;
}
}
abstract class TypeOptionFieldDelegate {
void onFieldChanged(void Function(String) callback);
void dispose();
}
abstract class IFieldTypeOptionLoader {
String get gridId;
Future<Either<FieldTypeOptionDataPB, FlowyError>> load();
Future<Either<FieldTypeOptionDataPB, FlowyError>> switchToField(
String fieldId, FieldType fieldType) {
final payload = EditFieldPayloadPB.create()
..gridId = gridId
..fieldId = fieldId
..fieldType = fieldType;
return GridEventSwitchToField(payload).send();
}
}
class NewFieldTypeOptionLoader extends IFieldTypeOptionLoader {
@override
final String gridId;
NewFieldTypeOptionLoader({
required this.gridId,
});
@override
Future<Either<FieldTypeOptionDataPB, FlowyError>> load() {
final payload = CreateFieldPayloadPB.create()
..gridId = gridId
..fieldType = FieldType.RichText;
return GridEventCreateFieldTypeOption(payload).send();
}
}
class FieldTypeOptionLoader extends IFieldTypeOptionLoader {
@override
final String gridId;
final GridFieldPB field;
FieldTypeOptionLoader({
required this.gridId,
required this.field,
});
@override
Future<Either<FieldTypeOptionDataPB, FlowyError>> load() {
final payload = GridFieldTypeOptionIdPB.create()
..gridId = gridId
..fieldId = field.id
..fieldType = field.fieldType;
return GridEventGetFieldTypeOption(payload).send();
}
}

View File

@ -92,11 +92,11 @@ TypeOptionWidgetBuilder makeTypeOptionWidgetBuilder({
);
case FieldType.MultiSelect:
return MultiSelectTypeOptionWidgetBuilder(
makeTypeOptionContextWithDataController<MultiSelectTypeOption>(
makeTypeOptionContextWithDataController<MultiSelectTypeOptionPB>(
gridId: gridId,
fieldType: fieldType,
dataController: dataController,
) as MultiSelectTypeOptionContext,
),
overlayDelegate,
);
case FieldType.Number:

View File

@ -9,7 +9,7 @@ class MultiSelectTypeOptionWidgetBuilder extends TypeOptionWidgetBuilder {
final MultiSelectTypeOptionWidget _widget;
MultiSelectTypeOptionWidgetBuilder(
MultiSelectTypeOptionContext typeOptionContext,
MultiSelectAction typeOptionContext,
TypeOptionOverlayDelegate overlayDelegate,
) : _widget = MultiSelectTypeOptionWidget(
typeOptionContext: typeOptionContext,
@ -21,7 +21,7 @@ class MultiSelectTypeOptionWidgetBuilder extends TypeOptionWidgetBuilder {
}
class MultiSelectTypeOptionWidget extends TypeOptionWidget {
final MultiSelectTypeOptionContext typeOptionContext;
final MultiSelectAction typeOptionContext;
final TypeOptionOverlayDelegate overlayDelegate;
const MultiSelectTypeOptionWidget({

View File

@ -981,6 +981,7 @@ dependencies = [
"serde",
"serde_json",
"serde_repr",
"tracing",
]
[[package]]

View File

@ -11,33 +11,33 @@ use std::convert::TryInto;
use std::sync::Arc;
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
pub struct GridFilter {
pub struct GridFilterConfiguration {
#[pb(index = 1)]
pub id: String,
}
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
pub struct RepeatedGridFilterPB {
pub struct RepeatedGridConfigurationFilterPB {
#[pb(index = 1)]
pub items: Vec<GridFilter>,
pub items: Vec<GridFilterConfiguration>,
}
impl std::convert::From<&GridFilterRevision> for GridFilter {
impl std::convert::From<&GridFilterRevision> for GridFilterConfiguration {
fn from(rev: &GridFilterRevision) -> Self {
Self { id: rev.id.clone() }
}
}
impl std::convert::From<Vec<Arc<GridFilterRevision>>> for RepeatedGridFilterPB {
impl std::convert::From<Vec<Arc<GridFilterRevision>>> for RepeatedGridConfigurationFilterPB {
fn from(revs: Vec<Arc<GridFilterRevision>>) -> Self {
RepeatedGridFilterPB {
RepeatedGridConfigurationFilterPB {
items: revs.into_iter().map(|rev| rev.as_ref().into()).collect(),
}
}
}
impl std::convert::From<Vec<GridFilter>> for RepeatedGridFilterPB {
fn from(items: Vec<GridFilter>) -> Self {
impl std::convert::From<Vec<GridFilterConfiguration>> for RepeatedGridConfigurationFilterPB {
fn from(items: Vec<GridFilterConfiguration>) -> Self {
Self { items }
}
}

View File

@ -1,4 +1,4 @@
use crate::entities::FieldType;
use crate::entities::{FieldType, GridRowPB};
use flowy_derive::ProtoBuf;
use flowy_error::ErrorCode;
use flowy_grid_data_model::parser::NotEmptyStr;
@ -8,7 +8,7 @@ use std::convert::TryInto;
use std::sync::Arc;
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
pub struct GridGroupPB {
pub struct GridGroupConfigurationPB {
#[pb(index = 1)]
pub id: String,
@ -19,9 +19,9 @@ pub struct GridGroupPB {
pub sub_group_field_id: Option<String>,
}
impl std::convert::From<&GridGroupRevision> for GridGroupPB {
impl std::convert::From<&GridGroupRevision> for GridGroupConfigurationPB {
fn from(rev: &GridGroupRevision) -> Self {
GridGroupPB {
GridGroupConfigurationPB {
id: rev.id.clone(),
group_field_id: rev.field_id.clone(),
sub_group_field_id: rev.sub_field_id.clone(),
@ -29,21 +29,39 @@ impl std::convert::From<&GridGroupRevision> for GridGroupPB {
}
}
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
#[derive(ProtoBuf, Debug, Default, Clone)]
pub struct RepeatedGridGroupPB {
#[pb(index = 1)]
pub items: Vec<GridGroupPB>,
groups: Vec<GroupPB>,
}
impl std::convert::From<Vec<GridGroupPB>> for RepeatedGridGroupPB {
fn from(items: Vec<GridGroupPB>) -> Self {
#[derive(ProtoBuf, Debug, Default, Clone)]
pub struct GroupPB {
#[pb(index = 1)]
pub group_id: String,
#[pb(index = 2)]
pub desc: String,
#[pb(index = 3)]
pub rows: Vec<GridRowPB>,
}
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
pub struct RepeatedGridGroupConfigurationPB {
#[pb(index = 1)]
pub items: Vec<GridGroupConfigurationPB>,
}
impl std::convert::From<Vec<GridGroupConfigurationPB>> for RepeatedGridGroupConfigurationPB {
fn from(items: Vec<GridGroupConfigurationPB>) -> Self {
Self { items }
}
}
impl std::convert::From<Vec<Arc<GridGroupRevision>>> for RepeatedGridGroupPB {
impl std::convert::From<Vec<Arc<GridGroupRevision>>> for RepeatedGridGroupConfigurationPB {
fn from(revs: Vec<Arc<GridGroupRevision>>) -> Self {
RepeatedGridGroupPB {
RepeatedGridGroupConfigurationPB {
items: revs.iter().map(|rev| rev.as_ref().into()).collect(),
}
}

View File

@ -1,6 +1,6 @@
use crate::entities::{
CreateGridFilterPayloadPB, CreateGridGroupPayloadPB, CreateGridSortPayloadPB, DeleteFilterPayloadPB,
DeleteGroupPayloadPB, RepeatedGridFilterPB, RepeatedGridGroupPB, RepeatedGridSortPB,
DeleteGroupPayloadPB, RepeatedGridConfigurationFilterPB, RepeatedGridGroupConfigurationPB, RepeatedGridSortPB,
};
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use flowy_error::ErrorCode;
@ -22,10 +22,10 @@ pub struct GridSettingPB {
pub current_layout_type: GridLayoutType,
#[pb(index = 3)]
pub filters_by_field_id: HashMap<String, RepeatedGridFilterPB>,
pub filter_configuration_by_field_id: HashMap<String, RepeatedGridConfigurationFilterPB>,
#[pb(index = 4)]
pub groups_by_field_id: HashMap<String, RepeatedGridGroupPB>,
pub group_configuration_by_field_id: HashMap<String, RepeatedGridGroupConfigurationPB>,
#[pb(index = 5)]
pub sorts_by_field_id: HashMap<String, RepeatedGridSortPB>,

View File

@ -405,3 +405,14 @@ pub(crate) async fn update_date_cell_handler(
let _ = editor.update_cell(params.into()).await?;
Ok(())
}
#[tracing::instrument(level = "trace", skip_all, err)]
pub(crate) async fn get_group_handler(
data: Data<GridIdPB>,
manager: AppData<Arc<GridManager>>,
) -> DataResult<RepeatedGridGroupPB, FlowyError> {
let params: GridIdPB = data.into_inner();
let editor = manager.get_grid_editor(&params.value)?;
let group = editor.get_group().await?;
data_result(group)
}

View File

@ -37,7 +37,9 @@ pub fn create(grid_manager: Arc<GridManager>) -> Module {
.event(GridEvent::GetSelectOptionCellData, get_select_option_handler)
.event(GridEvent::UpdateSelectOptionCell, update_select_option_cell_handler)
// Date
.event(GridEvent::UpdateDateCell, update_date_cell_handler);
.event(GridEvent::UpdateDateCell, update_date_cell_handler)
// Group
.event(GridEvent::GetGroup, update_date_cell_handler);
module
}
@ -204,4 +206,7 @@ pub enum GridEvent {
/// will be used by the `update_cell` function.
#[event(input = "DateChangesetPayloadPB")]
UpdateDateCell = 80,
#[event(input = "GridIdPB", output = "RepeatedGridGroupPB")]
GetGroup = 100,
}

View File

@ -61,7 +61,7 @@ pub fn apply_cell_data_changeset<C: ToString, T: AsRef<FieldRevision>>(
FieldType::SingleSelect => {
SingleSelectTypeOptionPB::from(field_rev).apply_changeset(changeset.into(), cell_rev)
}
FieldType::MultiSelect => MultiSelectTypeOption::from(field_rev).apply_changeset(changeset.into(), cell_rev),
FieldType::MultiSelect => MultiSelectTypeOptionPB::from(field_rev).apply_changeset(changeset.into(), cell_rev),
FieldType::Checkbox => CheckboxTypeOption::from(field_rev).apply_changeset(changeset.into(), cell_rev),
FieldType::URL => URLTypeOption::from(field_rev).apply_changeset(changeset.into(), cell_rev),
}?;
@ -109,7 +109,7 @@ pub fn try_decode_cell_data(
.get_type_option_entry::<SingleSelectTypeOptionPB>(field_type)?
.decode_cell_data(cell_data.into(), s_field_type, field_rev),
FieldType::MultiSelect => field_rev
.get_type_option_entry::<MultiSelectTypeOption>(field_type)?
.get_type_option_entry::<MultiSelectTypeOptionPB>(field_type)?
.decode_cell_data(cell_data.into(), s_field_type, field_rev),
FieldType::Checkbox => field_rev
.get_type_option_entry::<CheckboxTypeOption>(field_type)?

View File

@ -94,7 +94,7 @@ pub fn default_type_option_builder_from_type(field_type: &FieldType) -> Box<dyn
FieldType::Number => NumberTypeOption::default().into(),
FieldType::DateTime => DateTypeOption::default().into(),
FieldType::SingleSelect => SingleSelectTypeOptionPB::default().into(),
FieldType::MultiSelect => MultiSelectTypeOption::default().into(),
FieldType::MultiSelect => MultiSelectTypeOptionPB::default().into(),
FieldType::Checkbox => CheckboxTypeOption::default().into(),
FieldType::URL => URLTypeOption::default().into(),
};

View File

@ -14,16 +14,16 @@ use serde::{Deserialize, Serialize};
// Multiple select
#[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)]
pub struct MultiSelectTypeOption {
pub struct MultiSelectTypeOptionPB {
#[pb(index = 1)]
pub options: Vec<SelectOptionPB>,
#[pb(index = 2)]
pub disable_color: bool,
}
impl_type_option!(MultiSelectTypeOption, FieldType::MultiSelect);
impl_type_option!(MultiSelectTypeOptionPB, FieldType::MultiSelect);
impl SelectOptionOperation for MultiSelectTypeOption {
impl SelectOptionOperation for MultiSelectTypeOptionPB {
fn selected_select_option(&self, cell_data: CellData<SelectOptionIds>) -> SelectOptionCellDataPB {
let select_options = make_selected_select_options(cell_data, &self.options);
SelectOptionCellDataPB {
@ -41,7 +41,7 @@ impl SelectOptionOperation for MultiSelectTypeOption {
}
}
impl CellDataOperation<SelectOptionIds, SelectOptionCellChangeset> for MultiSelectTypeOption {
impl CellDataOperation<SelectOptionIds, SelectOptionCellChangeset> for MultiSelectTypeOptionPB {
fn decode_cell_data(
&self,
cell_data: CellData<SelectOptionIds>,
@ -93,9 +93,9 @@ impl CellDataOperation<SelectOptionIds, SelectOptionCellChangeset> for MultiSele
}
#[derive(Default)]
pub struct MultiSelectTypeOptionBuilder(MultiSelectTypeOption);
pub struct MultiSelectTypeOptionBuilder(MultiSelectTypeOptionPB);
impl_into_box_type_option_builder!(MultiSelectTypeOptionBuilder);
impl_builder_from_json_str_and_from_bytes!(MultiSelectTypeOptionBuilder, MultiSelectTypeOption);
impl_builder_from_json_str_and_from_bytes!(MultiSelectTypeOptionBuilder, MultiSelectTypeOptionPB);
impl MultiSelectTypeOptionBuilder {
pub fn option(mut self, opt: SelectOptionPB) -> Self {
self.0.options.push(opt);
@ -118,7 +118,7 @@ mod tests {
use crate::services::cell::CellDataOperation;
use crate::services::field::type_options::selection_type_option::*;
use crate::services::field::FieldBuilder;
use crate::services::field::{MultiSelectTypeOption, MultiSelectTypeOptionBuilder};
use crate::services::field::{MultiSelectTypeOptionBuilder, MultiSelectTypeOptionPB};
use flowy_grid_data_model::revision::FieldRevision;
#[test]
@ -136,7 +136,7 @@ mod tests {
.visibility(true)
.build();
let type_option = MultiSelectTypeOption::from(&field_rev);
let type_option = MultiSelectTypeOptionPB::from(&field_rev);
let option_ids = vec![google_option.id.clone(), facebook_option.id.clone()].join(SELECTION_IDS_SEPARATOR);
let data = SelectOptionCellChangeset::from_insert(&option_ids).to_str();
@ -170,7 +170,7 @@ mod tests {
fn assert_multi_select_options(
cell_data: String,
type_option: &MultiSelectTypeOption,
type_option: &MultiSelectTypeOptionPB,
field_rev: &FieldRevision,
expected: Vec<SelectOptionPB>,
) {

View File

@ -1,6 +1,6 @@
use crate::entities::{CellChangesetPB, FieldType, GridCellIdPB, GridCellIdParams};
use crate::services::cell::{CellBytes, CellBytesParser, CellData, CellDisplayable, FromCellChangeset, FromCellString};
use crate::services::field::{MultiSelectTypeOption, SingleSelectTypeOptionPB};
use crate::services::field::{MultiSelectTypeOptionPB, SingleSelectTypeOptionPB};
use bytes::Bytes;
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use flowy_error::{internal_error, ErrorCode, FlowyResult};
@ -130,7 +130,7 @@ pub fn select_option_operation(field_rev: &FieldRevision) -> FlowyResult<Box<dyn
Ok(Box::new(type_option))
}
FieldType::MultiSelect => {
let type_option = MultiSelectTypeOption::from(field_rev);
let type_option = MultiSelectTypeOptionPB::from(field_rev);
Ok(Box::new(type_option))
}
ty => {

View File

@ -159,7 +159,7 @@ mod tests {
.option(google_option.clone())
.option(facebook_option.clone());
let multi_select_field_rev = FieldBuilder::new(multi_select).build();
let multi_type_option = MultiSelectTypeOption::from(&multi_select_field_rev);
let multi_type_option = MultiSelectTypeOptionPB::from(&multi_select_field_rev);
let cell_data = multi_type_option
.apply_changeset(cell_data_changeset.into(), None)
.unwrap();

View File

@ -3,7 +3,7 @@ use crate::entities::{FieldType, GridBlockChangesetPB};
use crate::services::block_manager::GridBlockManager;
use crate::services::cell::{AnyCellData, CellFilterOperation};
use crate::services::field::{
CheckboxTypeOption, DateTypeOption, MultiSelectTypeOption, NumberTypeOption, RichTextTypeOption,
CheckboxTypeOption, DateTypeOption, MultiSelectTypeOptionPB, NumberTypeOption, RichTextTypeOption,
SingleSelectTypeOptionPB, URLTypeOption,
};
use crate::services::filter::filter_cache::{
@ -22,8 +22,6 @@ use std::sync::Arc;
use tokio::sync::RwLock;
pub(crate) struct GridFilterService {
#[allow(dead_code)]
grid_id: String,
scheduler: Arc<dyn GridServiceTaskScheduler>,
grid_pad: Arc<RwLock<GridRevisionPad>>,
block_manager: Arc<GridBlockManager>,
@ -36,12 +34,10 @@ impl GridFilterService {
block_manager: Arc<GridBlockManager>,
scheduler: S,
) -> Self {
let grid_id = grid_pad.read().await.grid_id();
let scheduler = Arc::new(scheduler);
let filter_cache = FilterCache::from_grid_pad(&grid_pad).await;
let filter_result_cache = FilterResultCache::new();
Self {
grid_id,
grid_pad,
block_manager,
scheduler,
@ -134,8 +130,9 @@ impl GridFilterService {
}
async fn notify(&self, changesets: Vec<GridBlockChangesetPB>) {
let grid_id = self.grid_pad.read().await.grid_id();
for changeset in changesets {
send_dart_notification(&self.grid_id, GridNotification::DidUpdateGridBlock)
send_dart_notification(&grid_id, GridNotification::DidUpdateGridBlock)
.payload(changeset)
.send();
}
@ -217,7 +214,7 @@ fn filter_cell(
FieldType::MultiSelect => filter_cache.select_option_filter.get(&filter_id).and_then(|filter| {
Some(
field_rev
.get_type_option_entry::<MultiSelectTypeOption>(field_type_rev)?
.get_type_option_entry::<MultiSelectTypeOptionPB>(field_type_rev)?
.apply_filter(any_cell_data, filter.value())
.ok(),
)

View File

@ -2,7 +2,7 @@
use crate::entities::{GridSelectOptionFilter, SelectOptionCondition};
use crate::services::cell::{AnyCellData, CellFilterOperation};
use crate::services::field::{MultiSelectTypeOption, SingleSelectTypeOptionPB};
use crate::services::field::{MultiSelectTypeOptionPB, SingleSelectTypeOptionPB};
use crate::services::field::{SelectOptionOperation, SelectedSelectOptions};
use flowy_error::FlowyResult;
@ -39,7 +39,7 @@ impl GridSelectOptionFilter {
}
}
impl CellFilterOperation<GridSelectOptionFilter> for MultiSelectTypeOption {
impl CellFilterOperation<GridSelectOptionFilter> for MultiSelectTypeOptionPB {
fn apply_filter(&self, any_cell_data: AnyCellData, filter: &GridSelectOptionFilter) -> FlowyResult<bool> {
if !any_cell_data.is_multi_select() {
return Ok(true);

View File

@ -61,7 +61,8 @@ impl GridRevisionEditor {
let block_manager = Arc::new(GridBlockManager::new(grid_id, &user, block_meta_revs, persistence).await?);
let filter_service =
Arc::new(GridFilterService::new(grid_pad.clone(), block_manager.clone(), task_scheduler.clone()).await);
let group_service = Arc::new(GridGroupService::new());
let group_service =
Arc::new(GridGroupService::new(grid_pad.clone(), block_manager.clone(), task_scheduler.clone()).await);
let editor = Arc::new(Self {
grid_id: grid_id.to_owned(),
user,
@ -455,14 +456,14 @@ impl GridRevisionEditor {
Ok(grid_setting)
}
pub async fn get_grid_filter(&self, layout_type: &GridLayoutType) -> FlowyResult<Vec<GridFilter>> {
pub async fn get_grid_filter(&self, layout_type: &GridLayoutType) -> FlowyResult<Vec<GridFilterConfiguration>> {
let read_guard = self.grid_pad.read().await;
let layout_rev = layout_type.clone().into();
match read_guard.get_filters(Some(&layout_rev), None) {
Some(filter_revs) => Ok(filter_revs
.iter()
.map(|filter_rev| filter_rev.as_ref().into())
.collect::<Vec<GridFilter>>()),
.collect::<Vec<GridFilterConfiguration>>()),
None => Ok(vec![]),
}
}
@ -561,6 +562,10 @@ impl GridRevisionEditor {
})
}
pub async fn get_group(&self) -> FlowyResult<RepeatedGridGroupPB> {
todo!()
}
async fn modify<F>(&self, f: F) -> FlowyResult<()>
where
F: for<'a> FnOnce(&'a mut GridRevisionPad) -> FlowyResult<Option<GridChangeset>>,

View File

@ -1,7 +1,26 @@
pub struct GridGroupService {}
use crate::services::block_manager::GridBlockManager;
use crate::services::grid_editor_task::GridServiceTaskScheduler;
use flowy_sync::client_grid::GridRevisionPad;
use std::sync::Arc;
use tokio::sync::RwLock;
pub(crate) struct GridGroupService {
scheduler: Arc<dyn GridServiceTaskScheduler>,
grid_pad: Arc<RwLock<GridRevisionPad>>,
block_manager: Arc<GridBlockManager>,
}
impl GridGroupService {
pub fn new() -> Self {
Self {}
pub(crate) async fn new<S: GridServiceTaskScheduler>(
grid_pad: Arc<RwLock<GridRevisionPad>>,
block_manager: Arc<GridBlockManager>,
scheduler: S,
) -> Self {
let scheduler = Arc::new(scheduler);
Self {
scheduler,
grid_pad,
block_manager,
}
}
}

View File

@ -1,5 +1,6 @@
use crate::entities::{
GridLayoutPB, GridLayoutType, GridSettingPB, RepeatedGridFilterPB, RepeatedGridGroupPB, RepeatedGridSortPB,
GridLayoutPB, GridLayoutType, GridSettingPB, RepeatedGridConfigurationFilterPB, RepeatedGridGroupConfigurationPB,
RepeatedGridSortPB,
};
use flowy_grid_data_model::revision::{FieldRevision, GridSettingRevision};
use flowy_sync::entities::grid::{CreateGridFilterParams, DeleteFilterParams, GridSettingChangesetParams};
@ -43,21 +44,21 @@ impl GridSettingChangesetBuilder {
pub fn make_grid_setting(grid_setting_rev: &GridSettingRevision, field_revs: &[Arc<FieldRevision>]) -> GridSettingPB {
let current_layout_type: GridLayoutType = grid_setting_rev.layout.clone().into();
let filters_by_field_id = grid_setting_rev
.get_all_filter(field_revs)
.get_all_filters(field_revs)
.map(|filters_by_field_id| {
filters_by_field_id
.into_iter()
.map(|(k, v)| (k, v.into()))
.collect::<HashMap<String, RepeatedGridFilterPB>>()
.collect::<HashMap<String, RepeatedGridConfigurationFilterPB>>()
})
.unwrap_or_default();
let groups_by_field_id = grid_setting_rev
.get_all_group()
.get_all_groups(field_revs)
.map(|groups_by_field_id| {
groups_by_field_id
.into_iter()
.map(|(k, v)| (k, v.into()))
.collect::<HashMap<String, RepeatedGridGroupPB>>()
.collect::<HashMap<String, RepeatedGridGroupConfigurationPB>>()
})
.unwrap_or_default();
let sorts_by_field_id = grid_setting_rev
@ -73,8 +74,8 @@ pub fn make_grid_setting(grid_setting_rev: &GridSettingRevision, field_revs: &[A
GridSettingPB {
layouts: GridLayoutPB::all(),
current_layout_type,
filters_by_field_id,
groups_by_field_id,
filter_configuration_by_field_id: filters_by_field_id,
group_configuration_by_field_id: groups_by_field_id,
sorts_by_field_id,
}
}

View File

@ -2,7 +2,7 @@ use flowy_grid::entities::FieldType;
use std::sync::Arc;
use flowy_grid::services::field::{
DateCellChangesetPB, MultiSelectTypeOption, SelectOptionPB, SingleSelectTypeOptionPB, SELECTION_IDS_SEPARATOR,
DateCellChangesetPB, MultiSelectTypeOptionPB, SelectOptionPB, SingleSelectTypeOptionPB, SELECTION_IDS_SEPARATOR,
};
use flowy_grid::services::row::RowRevisionBuilder;
use flowy_grid_data_model::revision::{FieldRevision, RowRevision};
@ -87,7 +87,7 @@ impl<'a> GridRowTestBuilder<'a> {
F: Fn(Vec<SelectOptionPB>) -> Vec<SelectOptionPB>,
{
let multi_select_field = self.field_rev_with_type(&FieldType::MultiSelect);
let type_option = MultiSelectTypeOption::from(&multi_select_field);
let type_option = MultiSelectTypeOptionPB::from(&multi_select_field);
let options = f(type_option.options);
let ops_ids = options
.iter()

View File

@ -3,7 +3,7 @@ use crate::grid::cell_test::script::GridCellTest;
use crate::grid::field_test::util::make_date_cell_string;
use flowy_grid::entities::{CellChangesetPB, FieldType};
use flowy_grid::services::field::selection_type_option::SelectOptionCellChangeset;
use flowy_grid::services::field::{MultiSelectTypeOption, SingleSelectTypeOptionPB};
use flowy_grid::services::field::{MultiSelectTypeOptionPB, SingleSelectTypeOptionPB};
#[tokio::test]
async fn grid_cell_update() {
@ -28,7 +28,7 @@ async fn grid_cell_update() {
SelectOptionCellChangeset::from_insert(&type_option.options.first().unwrap().id).to_str()
}
FieldType::MultiSelect => {
let type_option = MultiSelectTypeOption::from(field_rev);
let type_option = MultiSelectTypeOptionPB::from(field_rev);
SelectOptionCellChangeset::from_insert(&type_option.options.first().unwrap().id).to_str()
}
FieldType::Checkbox => "1".to_string(),

View File

@ -75,7 +75,7 @@ impl GridEditorTest {
.row_revs
}
pub async fn grid_filters(&self) -> Vec<GridFilter> {
pub async fn grid_filters(&self) -> Vec<GridFilterConfiguration> {
let layout_type = GridLayoutType::Table;
self.editor.get_grid_filter(&layout_type).await.unwrap()
}

View File

@ -2,7 +2,7 @@ use crate::grid::script::EditorScript::*;
use crate::grid::script::*;
use chrono::NaiveDateTime;
use flowy_grid::services::field::{
DateCellContentChangeset, DateCellData, MultiSelectTypeOption, SelectOption, SelectOptionCellContentChangeset,
DateCellContentChangeset, DateCellData, MultiSelectTypeOptionPB, SelectOption, SelectOptionCellContentChangeset,
SingleSelectTypeOption, SELECTION_IDS_SEPARATOR,
};
use flowy_grid::services::row::{decode_cell_data_from_type_option_cell_data, CreateRowMetaBuilder};
@ -250,7 +250,7 @@ async fn grid_row_add_cells_test() {
builder.add_select_option_cell(&field.id, option.id.clone()).unwrap();
}
FieldType::MultiSelect => {
let type_option = MultiSelectTypeOption::from(field);
let type_option = MultiSelectTypeOptionPB::from(field);
let ops_ids = type_option
.options
.iter()
@ -327,7 +327,7 @@ async fn grid_cell_update() {
SelectOptionCellContentChangeset::from_insert(&type_option.options.first().unwrap().id).to_str()
}
FieldType::MultiSelect => {
let type_option = MultiSelectTypeOption::from(field_meta);
let type_option = MultiSelectTypeOptionPB::from(field_meta);
SelectOptionCellContentChangeset::from_insert(&type_option.options.first().unwrap().id).to_str()
}
FieldType::Checkbox => "1".to_string(),

1
shared-lib/Cargo.lock generated
View File

@ -436,6 +436,7 @@ dependencies = [
"serde",
"serde_json",
"serde_repr",
"tracing",
]
[[package]]

View File

@ -13,6 +13,7 @@ serde_repr = "0.1"
nanoid = "0.4.0"
flowy-error-code = { path = "../flowy-error-code"}
indexmap = {version = "1.8.1", features = ["serde"]}
tracing = { version = "0.1", features = ["log"] }
[build-dependencies]
lib-infra = { path = "../lib-infra", features = ["protobuf_file_gen"] }

View File

@ -1,7 +1,4 @@
use crate::revision::FieldTypeRevision;
use indexmap::IndexMap;
use serde::{Deserialize, Serialize};
use std::sync::Arc;
#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq, Hash)]
pub struct GridFilterRevision {

View File

@ -1,7 +1,4 @@
use crate::revision::FieldTypeRevision;
use indexmap::IndexMap;
use serde::{Deserialize, Serialize};
use std::sync::Arc;
#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
pub struct GridGroupRevision {

View File

@ -1,5 +1,5 @@
use crate::revision::filter_rev::GridFilterRevision;
use crate::revision::group_rev::GridGroupRevision;
use crate::revision::grid_group::GridGroupRevision;
use crate::revision::{FieldRevision, FieldTypeRevision};
use indexmap::IndexMap;
use nanoid::nanoid;
@ -21,28 +21,28 @@ pub fn gen_grid_sort_id() -> String {
nanoid!(6)
}
pub type GridFilters = SettingContainer<GridFilterRevision>;
pub type GridFilterRevisionMap = GridObjectRevisionMap<GridFilterRevision>;
pub type FiltersByFieldId = HashMap<String, Vec<Arc<GridFilterRevision>>>;
//
pub type GridGroups = SettingContainer<GridGroupRevision>;
pub type GridGroupRevisionMap = GridObjectRevisionMap<GridGroupRevision>;
pub type GroupsByFieldId = HashMap<String, Vec<Arc<GridGroupRevision>>>;
//
pub type GridSorts = SettingContainer<GridSortRevision>;
pub type GridSortRevisionMap = GridObjectRevisionMap<GridSortRevision>;
pub type SortsByFieldId = HashMap<String, Vec<Arc<GridSortRevision>>>;
#[derive(Debug, Clone, Serialize, Deserialize, Default, Eq, PartialEq)]
pub struct GridSettingRevision {
pub layout: GridLayoutRevision,
/// Each layout contains multiple key/value.
/// Key: field_id
/// Value: this value contains key/value.
/// Key: FieldType,
/// Value: the corresponding filters.
#[serde(with = "indexmap::serde_seq")]
filters: IndexMap<GridLayoutRevision, IndexMap<String, GridFilterRevisionMap>>,
pub filters: GridFilters,
/// Each layout contains multiple key/value.
/// Key: field_id
/// Value: this value contains key/value.
/// Key: FieldType,
/// Value: the corresponding groups.
#[serde(skip, with = "indexmap::serde_seq")]
pub groups: IndexMap<GridLayoutRevision, IndexMap<String, GridGroupRevisionMap>>,
pub groups: GridGroups,
#[serde(skip, with = "indexmap::serde_seq")]
pub sorts: IndexMap<GridLayoutRevision, Vec<GridSortRevision>>,
#[serde(skip)]
pub sorts: GridSorts,
}
#[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize_repr, Deserialize_repr)]
@ -65,12 +65,18 @@ impl std::default::Default for GridLayoutRevision {
}
}
pub type FiltersByFieldId = HashMap<String, Vec<Arc<GridFilterRevision>>>;
pub type GroupsByFieldId = HashMap<String, Vec<Arc<GridGroupRevision>>>;
pub type SortsByFieldId = HashMap<String, Vec<Arc<GridSortRevision>>>;
impl GridSettingRevision {
pub fn get_all_group(&self) -> Option<GroupsByFieldId> {
None
pub fn get_all_groups(&self, field_revs: &[Arc<FieldRevision>]) -> Option<GroupsByFieldId> {
self.groups.get_all_objects(&self.layout, field_revs)
}
pub fn get_groups(
&self,
layout: &GridLayoutRevision,
field_id: &str,
field_type_rev: &FieldTypeRevision,
) -> Option<Vec<Arc<GridGroupRevision>>> {
self.groups.get_objects(layout, field_id, field_type_rev)
}
pub fn get_mut_groups(
@ -79,10 +85,7 @@ impl GridSettingRevision {
field_id: &str,
field_type: &FieldTypeRevision,
) -> Option<&mut Vec<Arc<GridGroupRevision>>> {
self.groups
.get_mut(layout)
.and_then(|group_rev_map_by_field_id| group_rev_map_by_field_id.get_mut(field_id))
.and_then(|group_rev_map| group_rev_map.get_mut(field_type))
self.groups.get_mut_objects(layout, field_id, field_type)
}
pub fn insert_group(
@ -90,59 +93,13 @@ impl GridSettingRevision {
layout: &GridLayoutRevision,
field_id: &str,
field_type: &FieldTypeRevision,
filter_rev: GridGroupRevision,
group_rev: GridGroupRevision,
) {
let filter_rev_map_by_field_id = self.groups.entry(layout.clone()).or_insert_with(IndexMap::new);
let filter_rev_map = filter_rev_map_by_field_id
.entry(field_id.to_string())
.or_insert_with(GridGroupRevisionMap::new);
filter_rev_map
.entry(field_type.to_owned())
.or_insert_with(Vec::new)
.push(Arc::new(filter_rev))
self.groups.insert_object(layout, field_id, field_type, group_rev);
}
pub fn get_all_sort(&self) -> Option<SortsByFieldId> {
None
}
/// Return the Filters of the current layout
pub fn get_all_filter(&self, field_revs: &[Arc<FieldRevision>]) -> Option<FiltersByFieldId> {
let layout = &self.layout;
// Acquire the read lock of the filters.
let filter_rev_map_by_field_id = self.filters.get(layout)?;
// Get the filters according to the FieldType, so we need iterate the field_revs.
let filters_by_field_id = field_revs
.iter()
.flat_map(|field_rev| {
let field_type = &field_rev.field_type_rev;
let field_id = &field_rev.id;
let filter_rev_map: &GridFilterRevisionMap = filter_rev_map_by_field_id.get(field_id)?;
let filters: Vec<Arc<GridFilterRevision>> = filter_rev_map.get(field_type)?.clone();
Some((field_rev.id.clone(), filters))
})
.collect::<FiltersByFieldId>();
Some(filters_by_field_id)
}
#[allow(dead_code)]
fn get_filter_rev_map(&self, layout: &GridLayoutRevision, field_id: &str) -> Option<&GridFilterRevisionMap> {
let filter_rev_map_by_field_id = self.filters.get(layout)?;
filter_rev_map_by_field_id.get(field_id)
}
pub fn get_mut_filters(
&mut self,
layout: &GridLayoutRevision,
field_id: &str,
field_type: &FieldTypeRevision,
) -> Option<&mut Vec<Arc<GridFilterRevision>>> {
self.filters
.get_mut(layout)
.and_then(|filter_rev_map_by_field_id| filter_rev_map_by_field_id.get_mut(field_id))
.and_then(|filter_rev_map| filter_rev_map.get_mut(field_type))
pub fn get_all_filters(&self, field_revs: &[Arc<FieldRevision>]) -> Option<FiltersByFieldId> {
self.filters.get_all_objects(&self.layout, field_revs)
}
pub fn get_filters(
@ -151,11 +108,16 @@ impl GridSettingRevision {
field_id: &str,
field_type_rev: &FieldTypeRevision,
) -> Option<Vec<Arc<GridFilterRevision>>> {
self.filters
.get(layout)
.and_then(|filter_rev_map_by_field_id| filter_rev_map_by_field_id.get(field_id))
.and_then(|filter_rev_map| filter_rev_map.get(field_type_rev))
.cloned()
self.filters.get_objects(layout, field_id, field_type_rev)
}
pub fn get_mut_filters(
&mut self,
layout: &GridLayoutRevision,
field_id: &str,
field_type: &FieldTypeRevision,
) -> Option<&mut Vec<Arc<GridFilterRevision>>> {
self.filters.get_mut_objects(layout, field_id, field_type)
}
pub fn insert_filter(
@ -165,15 +127,11 @@ impl GridSettingRevision {
field_type: &FieldTypeRevision,
filter_rev: GridFilterRevision,
) {
let filter_rev_map_by_field_id = self.filters.entry(layout.clone()).or_insert_with(IndexMap::new);
let filter_rev_map = filter_rev_map_by_field_id
.entry(field_id.to_string())
.or_insert_with(GridFilterRevisionMap::new);
self.filters.insert_object(layout, field_id, field_type, filter_rev);
}
filter_rev_map
.entry(field_type.to_owned())
.or_insert_with(Vec::new)
.push(Arc::new(filter_rev))
pub fn get_all_sort(&self) -> Option<SortsByFieldId> {
None
}
}
@ -183,8 +141,94 @@ pub struct GridSortRevision {
pub field_id: Option<String>,
}
pub type GridFilterRevisionMap = GridObjectRevisionMap<GridFilterRevision>;
pub type GridGroupRevisionMap = GridObjectRevisionMap<GridGroupRevision>;
#[derive(Debug, Clone, Serialize, Deserialize, Default, Eq, PartialEq)]
#[serde(transparent)]
pub struct SettingContainer<T>
where
T: Debug + Clone + Default + Eq + PartialEq + serde::Serialize + serde::de::DeserializeOwned + 'static,
{
/// Each layout contains multiple key/value.
/// Key: field_id
/// Value: this value contains key/value.
/// Key: FieldType,
/// Value: the corresponding objects.
#[serde(with = "indexmap::serde_seq")]
inner: IndexMap<GridLayoutRevision, IndexMap<String, GridObjectRevisionMap<T>>>,
}
impl<T> SettingContainer<T>
where
T: Debug + Clone + Default + Eq + PartialEq + serde::Serialize + serde::de::DeserializeOwned + 'static,
{
pub fn get_mut_objects(
&mut self,
layout: &GridLayoutRevision,
field_id: &str,
field_type: &FieldTypeRevision,
) -> Option<&mut Vec<Arc<T>>> {
let value = self
.inner
.get_mut(layout)
.and_then(|object_rev_map_by_field_id| object_rev_map_by_field_id.get_mut(field_id))
.and_then(|object_rev_map| object_rev_map.get_mut(field_type));
if value.is_none() {
tracing::warn!("Can't find the {:?} with", std::any::type_name::<T>());
}
value
}
pub fn get_objects(
&self,
layout: &GridLayoutRevision,
field_id: &str,
field_type_rev: &FieldTypeRevision,
) -> Option<Vec<Arc<T>>> {
self.inner
.get(layout)
.and_then(|object_rev_map_by_field_id| object_rev_map_by_field_id.get(field_id))
.and_then(|object_rev_map| object_rev_map.get(field_type_rev))
.cloned()
}
pub fn get_all_objects(
&self,
layout: &GridLayoutRevision,
field_revs: &[Arc<FieldRevision>],
) -> Option<HashMap<String, Vec<Arc<T>>>> {
// Acquire the read lock.
let object_rev_map_by_field_id = self.inner.get(layout)?;
// Get the objects according to the FieldType, so we need iterate the field_revs.
let objects_by_field_id = field_revs
.iter()
.flat_map(|field_rev| {
let field_type = &field_rev.field_type_rev;
let field_id = &field_rev.id;
let object_rev_map = object_rev_map_by_field_id.get(field_id)?;
let objects: Vec<Arc<T>> = object_rev_map.get(field_type)?.clone();
Some((field_rev.id.clone(), objects))
})
.collect::<HashMap<String, Vec<Arc<T>>>>();
Some(objects_by_field_id)
}
pub fn insert_object(
&mut self,
layout: &GridLayoutRevision,
field_id: &str,
field_type: &FieldTypeRevision,
object: T,
) {
let object_rev_map_by_field_id = self.inner.entry(layout.clone()).or_insert_with(IndexMap::new);
let object_rev_map = object_rev_map_by_field_id
.entry(field_id.to_string())
.or_insert_with(GridObjectRevisionMap::<T>::new);
object_rev_map
.entry(field_type.to_owned())
.or_insert_with(Vec::new)
.push(Arc::new(object))
}
}
#[derive(Debug, Clone, Serialize, Deserialize, Default, Eq, PartialEq)]
#[serde(transparent)]

View File

@ -1,9 +1,11 @@
mod filter_rev;
mod grid_group;
mod grid_rev;
mod grid_setting_rev;
mod group_rev;
mod grid_sort;
pub use filter_rev::*;
pub use grid_group::*;
pub use grid_rev::*;
pub use grid_setting_rev::*;
pub use group_rev::*;
pub use grid_sort::*;

View File

@ -457,7 +457,6 @@ mod tests {
AppRevision, FolderRevision, TrashRevision, ViewRevision, WorkspaceRevision,
};
use lib_ot::core::{OperationTransform, TextDelta, TextDeltaBuilder};
use serde_json::json;
#[test]
fn folder_add_workspace() {

View File

@ -1,4 +1,6 @@
use crate::entities::grid::{FieldChangesetParams, GridSettingChangesetParams};
use crate::entities::grid::{
CreateGridFilterParams, CreateGridGroupParams, FieldChangesetParams, GridSettingChangesetParams,
};
use crate::entities::revision::{md5, RepeatedRevision, Revision};
use crate::errors::{internal_error, CollaborateError, CollaborateResult};
use crate::util::{cal_diff, make_delta_from_revisions};
@ -380,88 +382,65 @@ impl GridRevisionPad {
self.modify_grid(|grid_rev| {
let mut is_changed = None;
let layout_rev = changeset.layout_type;
if let Some(params) = changeset.insert_filter {
let filter_rev = GridFilterRevision {
id: gen_grid_filter_id(),
field_id: params.field_id.clone(),
condition: params.condition,
content: params.content,
};
grid_rev
.setting
.insert_filter(&layout_rev, &params.field_id, &params.field_type_rev, filter_rev);
grid_rev.setting.insert_filter(
&layout_rev,
&params.field_id,
&params.field_type_rev,
make_filter_revision(&params),
);
is_changed = Some(())
}
if let Some(params) = changeset.delete_filter {
match grid_rev
if let Some(filters) =
grid_rev
.setting
.get_mut_filters(&layout_rev, &params.field_id, &params.field_type_rev)
{
Some(filters) => {
filters.retain(|filter| filter.id != params.filter_id);
}
None => {
tracing::warn!("Can't find the filter with {:?}", layout_rev);
}
}
}
if let Some(params) = changeset.insert_group {
let group_rev = GridGroupRevision {
id: gen_grid_group_id(),
field_id: params.field_id.clone(),
sub_field_id: params.sub_field_id,
};
grid_rev
.setting
.insert_group(&layout_rev, &params.field_id, &params.field_type_rev, group_rev);
grid_rev.setting.insert_group(
&layout_rev,
&params.field_id,
&params.field_type_rev,
make_group_revision(&params),
);
is_changed = Some(());
}
if let Some(params) = changeset.delete_group {
// match grid_rev.setting.groups.get_mut(&layout_rev) {
// Some(groups) => groups.retain(|group| group.id != delete_group_id),
// None => {
// tracing::warn!("Can't find the group with {:?}", layout_rev);
// }
// }
match grid_rev
if let Some(groups) =
grid_rev
.setting
.get_mut_groups(&layout_rev, &params.field_id, &params.field_type_rev)
{
Some(groups) => {
groups.retain(|filter| filter.id != params.group_id);
}
None => {
tracing::warn!("Can't find the group with {:?}", layout_rev);
}
}
}
if let Some(sort) = changeset.insert_sort {
let rev = GridSortRevision {
id: gen_grid_sort_id(),
field_id: sort.field_id,
};
grid_rev
.setting
.sorts
.entry(layout_rev.clone())
.or_insert_with(std::vec::Vec::new)
.push(rev);
// let rev = GridSortRevision {
// id: gen_grid_sort_id(),
// field_id: sort.field_id,
// };
//
// grid_rev
// .setting
// .sorts
// .entry(layout_rev.clone())
// .or_insert_with(std::vec::Vec::new)
// .push(rev);
is_changed = Some(())
}
if let Some(delete_sort_id) = changeset.delete_sort {
match grid_rev.setting.sorts.get_mut(&layout_rev) {
Some(sorts) => sorts.retain(|sort| sort.id != delete_sort_id),
None => {
tracing::warn!("Can't find the sort with {:?}", layout_rev);
}
}
// match grid_rev.setting.sorts.get_mut(&layout_rev) {
// Some(sorts) => sorts.retain(|sort| sort.id != delete_sort_id),
// None => {
// tracing::warn!("Can't find the sort with {:?}", layout_rev);
// }
// }
}
Ok(is_changed)
})
@ -579,3 +558,20 @@ impl std::default::Default for GridRevisionPad {
}
}
}
fn make_filter_revision(params: &CreateGridFilterParams) -> GridFilterRevision {
GridFilterRevision {
id: gen_grid_filter_id(),
field_id: params.field_id.clone(),
condition: params.condition.clone(),
content: params.content.clone(),
}
}
fn make_group_revision(params: &CreateGridGroupParams) -> GridGroupRevision {
GridGroupRevision {
id: gen_grid_group_id(),
field_id: params.field_id.clone(),
sub_field_id: params.sub_field_id.clone(),
}
}