chore: save group revision and fix warnings

This commit is contained in:
appflowy
2022-08-20 23:54:51 +08:00
parent 3c022d4de5
commit 6e6a812243
20 changed files with 203 additions and 180 deletions

View File

@ -31,7 +31,7 @@ class BoardPluginBuilder implements PluginBuilder {
class BoardPluginConfig implements PluginConfig { class BoardPluginConfig implements PluginConfig {
@override @override
bool get creatable => false; bool get creatable => true;
} }
class BoardPlugin extends Plugin { class BoardPlugin extends Plugin {

View File

@ -3,7 +3,6 @@ import 'package:flowy_sdk/dispatch/dispatch.dart';
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/block_entities.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/block_entities.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/board_card.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/grid_entities.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/grid_entities.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/group.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/group.pb.dart';

View File

@ -168,10 +168,12 @@ impl GridRevisionEditor {
pub async fn update_field(&self, params: FieldChangesetParams) -> FlowyResult<()> { pub async fn update_field(&self, params: FieldChangesetParams) -> FlowyResult<()> {
let field_id = params.field_id.clone(); let field_id = params.field_id.clone();
let field_type: Option<FieldType> = match self.grid_pad.read().await.get_field_rev(params.field_id.as_str()) { let field_type: Option<FieldType> = self
None => None, .grid_pad
Some((_, field_rev)) => Some(field_rev.ty.into()), .read()
}; .await
.get_field_rev(params.field_id.as_str())
.map(|(_, field_rev)| field_rev.ty.into());
match field_type { match field_type {
None => Err(ErrorCode::FieldDoesNotExist.into()), None => Err(ErrorCode::FieldDoesNotExist.into()),
@ -341,7 +343,7 @@ impl GridRevisionEditor {
Ok(row_pb) Ok(row_pb)
} }
pub async fn move_group(&self, params: MoveGroupParams) -> FlowyResult<GroupsChangesetPB> { pub async fn move_group(&self, _params: MoveGroupParams) -> FlowyResult<GroupsChangesetPB> {
// //
todo!() todo!()
} }

View File

@ -183,7 +183,7 @@ impl GridViewRevisionEditor {
grid_setting grid_setting
} }
pub(crate) async fn update_setting(&self, changeset: GridSettingChangesetParams) -> FlowyResult<()> { pub(crate) async fn update_setting(&self, _changeset: GridSettingChangesetParams) -> FlowyResult<()> {
// let _ = self.modify(|pad| Ok(pad.update_setting(changeset)?)).await; // let _ = self.modify(|pad| Ok(pad.update_setting(changeset)?)).await;
// Ok(()) // Ok(())
todo!() todo!()
@ -207,6 +207,7 @@ impl GridViewRevisionEditor {
.send(); .send();
} }
#[allow(dead_code)]
async fn modify<F>(&self, f: F) -> FlowyResult<()> async fn modify<F>(&self, f: F) -> FlowyResult<()>
where where
F: for<'a> FnOnce(&'a mut GridViewRevisionPad) -> FlowyResult<Option<GridViewRevisionChangeset>>, F: for<'a> FnOnce(&'a mut GridViewRevisionPad) -> FlowyResult<Option<GridViewRevisionChangeset>>,
@ -230,7 +231,7 @@ async fn apply_change(
let GridViewRevisionChangeset { delta, md5 } = change; let GridViewRevisionChangeset { delta, md5 } = change;
let (base_rev_id, rev_id) = rev_manager.next_rev_id_pair(); let (base_rev_id, rev_id) = rev_manager.next_rev_id_pair();
let delta_data = delta.json_bytes(); let delta_data = delta.json_bytes();
let revision = Revision::new(&rev_manager.object_id, base_rev_id, rev_id, delta_data, &user_id, md5); let revision = Revision::new(&rev_manager.object_id, base_rev_id, rev_id, delta_data, user_id, md5);
let _ = rev_manager.add_local_revision(&revision).await?; let _ = rev_manager.add_local_revision(&revision).await?;
Ok(()) Ok(())
} }
@ -287,49 +288,29 @@ impl GroupConfigurationWriter for GroupConfigurationWriterImpl {
&self, &self,
field_id: &str, field_id: &str,
field_type: FieldTypeRevision, field_type: FieldTypeRevision,
group_id: &str, configuration_id: &str,
mut_fn: impl FnOnce(&mut GroupConfigurationRevision), content: String,
) -> AFFuture<FlowyResult<()>> { ) -> AFFuture<FlowyResult<()>> {
let user_id = self.user_id.clone(); let user_id = self.user_id.clone();
let group_id = group_id.to_owned(); let configuration_id = configuration_id.to_owned();
let rev_manager = self.rev_manager.clone(); let rev_manager = self.rev_manager.clone();
let view_pad = self.view_pad.clone(); let view_pad = self.view_pad.clone();
let field_id = field_id.to_owned(); let field_id = field_id.to_owned();
wrap_future(async move { wrap_future(async move {
match view_pad match view_pad.write().await.get_mut_group(
.write() &field_id,
.await &field_type,
.get_mut_group(&field_id, &field_type, &group_id, mut_fn)? &configuration_id,
{ |group_configuration| {
group_configuration.content = content;
},
)? {
None => Ok(()), None => Ok(()),
Some(changeset) => apply_change(&user_id, rev_manager, changeset).await, Some(changeset) => apply_change(&user_id, rev_manager, changeset).await,
} }
}) })
} }
// fn save_group_configuration(
// &self,
// field_id: &str,
// field_type: FieldTypeRevision,
//
// configuration: GroupConfigurationRevision,
// ) -> AFFuture<FlowyResult<()>> {
// let user_id = self.user_id.clone();
// let rev_manager = self.rev_manager.clone();
// let view_pad = self.view_pad.clone();
// let field_id = field_id.to_owned();
//
// wrap_future(async move {
// match view_pad
// .write()
// .await
// .insert_group_configuration(&field_id, &field_type, configuration)?
// {
// None => Ok(()),
// Some(changeset) => apply_change(&user_id, rev_manager, changeset).await,
// }
// })
// }
} }
pub fn make_grid_setting(view_pad: &GridViewRevisionPad, field_revs: &[Arc<FieldRevision>]) -> GridSettingPB { pub fn make_grid_setting(view_pad: &GridViewRevisionPad, field_revs: &[Arc<FieldRevision>]) -> GridSettingPB {

View File

@ -131,6 +131,7 @@ impl GridViewManager {
} }
} }
#[allow(dead_code)]
pub(crate) async fn move_group(&self) {} pub(crate) async fn move_group(&self) {}
pub(crate) async fn get_view_editor(&self, view_id: &str) -> FlowyResult<Arc<GridViewRevisionEditor>> { pub(crate) async fn get_view_editor(&self, view_id: &str) -> FlowyResult<Arc<GridViewRevisionEditor>> {

View File

@ -1,8 +1,9 @@
use crate::services::group::Group; use crate::services::group::Group;
use flowy_error::FlowyResult; use flowy_error::FlowyResult;
use flowy_grid_data_model::revision::{ use flowy_grid_data_model::revision::{
FieldRevision, FieldTypeRevision, GroupConfigurationContentSerde, GroupConfigurationRevision, GroupRecordRevision, FieldRevision, FieldTypeRevision, GroupConfigurationContent, GroupConfigurationRevision, GroupRecordRevision,
}; };
use lib_infra::future::AFFuture; use lib_infra::future::AFFuture;
use std::sync::Arc; use std::sync::Arc;
@ -10,34 +11,28 @@ pub trait GroupConfigurationReader: Send + Sync + 'static {
fn get_group_configuration(&self, field_rev: Arc<FieldRevision>) -> AFFuture<Arc<GroupConfigurationRevision>>; fn get_group_configuration(&self, field_rev: Arc<FieldRevision>) -> AFFuture<Arc<GroupConfigurationRevision>>;
} }
pub trait GroupConfigurationWriter: Send + Sync + 'static + ?Sized { pub trait GroupConfigurationWriter: Send + Sync + 'static {
fn save_group_configuration( fn save_group_configuration(
&self, &self,
field_id: &str, field_id: &str,
field_type: FieldTypeRevision, field_type: FieldTypeRevision,
group_id: &str, configuration_id: &str,
mut_fn: fn(&mut GroupConfigurationRevision), content: String,
) -> AFFuture<FlowyResult<()>>; ) -> AFFuture<FlowyResult<()>>;
} }
pub trait GroupConfigurationAction: Send + Sync {
fn group_records(&self) -> &[GroupRecordRevision];
fn merge_groups(&self, groups: Vec<Group>) -> FlowyResult<()>;
fn hide_group(&self, group_id: &str) -> FlowyResult<()>;
fn show_group(&self, group_id: &str) -> FlowyResult<()>;
}
pub struct GenericGroupConfiguration<C> { pub struct GenericGroupConfiguration<C> {
pub configuration: C,
// pub groups_map: IndexMap<String, Group>,
configuration_id: String,
field_rev: Arc<FieldRevision>, field_rev: Arc<FieldRevision>,
reader: Arc<dyn GroupConfigurationReader>, reader: Arc<dyn GroupConfigurationReader>,
configuration_rev: Arc<GroupConfigurationRevision>,
writer: Arc<dyn GroupConfigurationWriter>, writer: Arc<dyn GroupConfigurationWriter>,
pub(crate) configuration: C,
} }
impl<C> GenericGroupConfiguration<C> impl<C> GenericGroupConfiguration<C>
where where
C: GroupConfigurationContentSerde, C: GroupConfigurationContent,
{ {
pub async fn new( pub async fn new(
field_rev: Arc<FieldRevision>, field_rev: Arc<FieldRevision>,
@ -45,17 +40,58 @@ where
writer: Arc<dyn GroupConfigurationWriter>, writer: Arc<dyn GroupConfigurationWriter>,
) -> FlowyResult<Self> { ) -> FlowyResult<Self> {
let configuration_rev = reader.get_group_configuration(field_rev.clone()).await; let configuration_rev = reader.get_group_configuration(field_rev.clone()).await;
let configuration_id = configuration_rev.id.clone();
let configuration = C::from_configuration_content(&configuration_rev.content)?; let configuration = C::from_configuration_content(&configuration_rev.content)?;
Ok(Self { Ok(Self {
configuration_id,
field_rev, field_rev,
configuration_rev,
reader, reader,
writer, writer,
configuration, configuration,
}) })
} }
pub async fn save_configuration(&self) {} #[allow(dead_code)]
fn group_records(&self) -> &[GroupRecordRevision] {
todo!()
}
pub(crate) async fn merge_groups(&mut self, groups: &[Group]) -> FlowyResult<()> {
match merge_groups(self.configuration.get_groups(), groups) {
None => Ok(()),
Some(new_groups) => {
self.configuration.set_groups(new_groups);
let _ = self.save_configuration().await?;
Ok(())
}
}
}
#[allow(dead_code)]
pub(crate) async fn hide_group(&mut self, group_id: &str) -> FlowyResult<()> {
self.configuration.mut_group(group_id, |group_rev| {
group_rev.visible = false;
});
let _ = self.save_configuration().await?;
Ok(())
}
#[allow(dead_code)]
pub(crate) async fn show_group(&mut self, group_id: &str) -> FlowyResult<()> {
self.configuration.mut_group(group_id, |group_rev| {
group_rev.visible = true;
});
let _ = self.save_configuration().await?;
Ok(())
}
pub async fn save_configuration(&self) -> FlowyResult<()> {
let content = self.configuration.to_configuration_content()?;
let _ = self
.writer
.save_group_configuration(&self.field_rev.id, self.field_rev.ty, &self.configuration_id, content)
.await?;
Ok(())
}
} }
impl<T> GroupConfigurationReader for Arc<T> impl<T> GroupConfigurationReader for Arc<T>
@ -67,25 +103,29 @@ where
} }
} }
impl<T> GroupConfigurationWriter for Arc<T> fn merge_groups(old_group: &[GroupRecordRevision], groups: &[Group]) -> Option<Vec<GroupRecordRevision>> {
where // tracing::trace!("Merge group: old: {}, new: {}", old_group.len(), groups.len());
T: GroupConfigurationWriter, if old_group.is_empty() {
{ let new_groups = groups
fn save_group_configuration( .iter()
&self, .map(|group| GroupRecordRevision::new(group.id.clone()))
field_id: &str, .collect();
field_type: FieldTypeRevision, return Some(new_groups);
group_id: &str,
mut_fn: impl FnOnce(&mut GroupConfigurationRevision),
) -> AFFuture<FlowyResult<()>> {
todo!()
} }
// fn save_group_configuration(
// &self, let new_groups = groups
// field_id: &str, .iter()
// field_type: FieldTypeRevision, .filter(|group| !old_group.iter().any(|group_rev| group_rev.group_id == group.id))
// configuration: GroupConfigurationRevision, .collect::<Vec<&Group>>();
// ) -> AFFuture<FlowyResult<()>> {
// (**self).save_group_configuration(field_id, field_type, configuration) if new_groups.is_empty() {
// } return None;
}
let mut old_group = old_group.to_vec();
let new_groups = new_groups
.iter()
.map(|group| GroupRecordRevision::new(group.id.clone()));
old_group.extend(new_groups);
Some(old_group)
} }

View File

@ -1,15 +1,14 @@
use crate::entities::{GroupRowsChangesetPB, RowPB}; use crate::entities::{GroupRowsChangesetPB, RowPB};
use crate::services::cell::{decode_any_cell_data, CellBytesParser}; use crate::services::cell::{decode_any_cell_data, CellBytesParser};
use crate::services::group::action::GroupAction; use crate::services::group::action::GroupAction;
use crate::services::group::configuration::{GenericGroupConfiguration, GroupConfigurationReader}; use crate::services::group::configuration::GenericGroupConfiguration;
use crate::services::group::entities::Group; use crate::services::group::entities::Group;
use flowy_error::FlowyResult; use flowy_error::FlowyResult;
use flowy_grid_data_model::revision::{ use flowy_grid_data_model::revision::{
FieldRevision, GroupConfigurationContentSerde, RowChangeset, RowRevision, TypeOptionDataDeserializer, FieldRevision, GroupConfigurationContent, RowChangeset, RowRevision, TypeOptionDataDeserializer,
}; };
use indexmap::IndexMap; use indexmap::IndexMap;
use crate::services::group::GroupConfigurationWriter;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::sync::Arc; use std::sync::Arc;
@ -18,7 +17,7 @@ const DEFAULT_GROUP_ID: &str = "default_group";
// Each kind of group must implement this trait to provide custom group // Each kind of group must implement this trait to provide custom group
// operations. For example, insert cell data to the row_rev when creating // operations. For example, insert cell data to the row_rev when creating
// a new row. // a new row.
pub trait GroupController: GroupControllerSharedAction + Send + Sync { pub trait GroupController: GroupControllerSharedOperation + Send + Sync {
fn will_create_row(&mut self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str); fn will_create_row(&mut self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str);
} }
@ -34,9 +33,10 @@ pub trait GroupGenerator {
} }
// Defines the shared actions each group controller can perform. // Defines the shared actions each group controller can perform.
pub trait GroupControllerSharedAction: Send + Sync { pub trait GroupControllerSharedOperation: Send + Sync {
// The field that is used for grouping the rows // The field that is used for grouping the rows
fn field_id(&self) -> &str; fn field_id(&self) -> &str;
fn groups(&self) -> &[Group];
fn fill_groups(&mut self, row_revs: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<Vec<Group>>; fn fill_groups(&mut self, row_revs: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<Vec<Group>>;
fn did_update_row( fn did_update_row(
&mut self, &mut self,
@ -66,32 +66,28 @@ pub trait GroupControllerSharedAction: Send + Sync {
pub struct GenericGroupController<C, T, G, P> { pub struct GenericGroupController<C, T, G, P> {
pub field_id: String, pub field_id: String,
pub groups_map: IndexMap<String, Group>, pub groups_map: IndexMap<String, Group>,
/// default_group is used to store the rows that don't belong to any groups.
default_group: Group,
pub type_option: Option<T>, pub type_option: Option<T>,
pub configuration: GenericGroupConfiguration<C>, pub configuration: GenericGroupConfiguration<C>,
/// default_group is used to store the rows that don't belong to any groups.
default_group: Group,
group_action_phantom: PhantomData<G>, group_action_phantom: PhantomData<G>,
cell_parser_phantom: PhantomData<P>, cell_parser_phantom: PhantomData<P>,
} }
impl<C, T, G, P> GenericGroupController<C, T, G, P> impl<C, T, G, P> GenericGroupController<C, T, G, P>
where where
C: GroupConfigurationContentSerde, C: GroupConfigurationContent,
T: TypeOptionDataDeserializer, T: TypeOptionDataDeserializer,
G: GroupGenerator<ConfigurationType = GenericGroupConfiguration<C>, TypeOptionType = T>, G: GroupGenerator<ConfigurationType = GenericGroupConfiguration<C>, TypeOptionType = T>,
{ {
pub async fn new( pub async fn new(
field_rev: &Arc<FieldRevision>, field_rev: &Arc<FieldRevision>,
configuration_reader: Arc<dyn GroupConfigurationReader>, mut configuration: GenericGroupConfiguration<C>,
configuration_writer: Arc<dyn GroupConfigurationWriter>,
) -> FlowyResult<Self> { ) -> FlowyResult<Self> {
let configuration =
GenericGroupConfiguration::<C>::new(field_rev.clone(), configuration_reader, configuration_writer).await?;
let field_type_rev = field_rev.ty; let field_type_rev = field_rev.ty;
let type_option = field_rev.get_type_option_entry::<T>(field_type_rev); let type_option = field_rev.get_type_option_entry::<T>(field_type_rev);
let groups = G::generate_groups(&field_rev.id, &configuration, &type_option); let groups = G::generate_groups(&field_rev.id, &configuration, &type_option);
let _ = configuration.merge_groups(&groups).await?;
let default_group = Group::new( let default_group = Group::new(
DEFAULT_GROUP_ID.to_owned(), DEFAULT_GROUP_ID.to_owned(),
field_rev.id.clone(), field_rev.id.clone(),
@ -111,20 +107,21 @@ where
} }
} }
impl<C, T, G, P> GroupControllerSharedAction for GenericGroupController<C, T, G, P> impl<C, T, G, P> GroupControllerSharedOperation for GenericGroupController<C, T, G, P>
where where
P: CellBytesParser, P: CellBytesParser,
C: GroupConfigurationContent,
Self: GroupAction<CellDataType = P::Object>, Self: GroupAction<CellDataType = P::Object>,
{ {
fn field_id(&self) -> &str { fn field_id(&self) -> &str {
&self.field_id &self.field_id
} }
fn fill_groups(&mut self, row_revs: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<Vec<Group>> { fn groups(&self) -> &[Group] {
// if self.configuration.is_none() { todo!()
// return Ok(vec![]); }
// }
fn fill_groups(&mut self, row_revs: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<Vec<Group>> {
for row_rev in row_revs { for row_rev in row_revs {
if let Some(cell_rev) = row_rev.cells.get(&self.field_id) { if let Some(cell_rev) = row_rev.cells.get(&self.field_id) {
let mut group_rows: Vec<GroupRow> = vec![]; let mut group_rows: Vec<GroupRow> = vec![];

View File

@ -1,13 +1,11 @@
use crate::entities::GroupRowsChangesetPB; use crate::entities::GroupRowsChangesetPB;
use crate::services::field::{CheckboxCellData, CheckboxCellDataParser, CheckboxTypeOptionPB, CHECK, UNCHECK}; use crate::services::field::{CheckboxCellData, CheckboxCellDataParser, CheckboxTypeOptionPB, CHECK, UNCHECK};
use crate::services::group::action::GroupAction; use crate::services::group::action::GroupAction;
use crate::services::group::configuration::{GenericGroupConfiguration, GroupConfigurationAction}; use crate::services::group::configuration::GenericGroupConfiguration;
use crate::services::group::controller::{GenericGroupController, GroupController, GroupGenerator};
use crate::services::group::entities::Group; use crate::services::group::entities::Group;
use crate::services::group::group_controller::{GenericGroupController, GroupController, GroupGenerator};
use flowy_error::FlowyResult; use flowy_grid_data_model::revision::{CheckboxGroupConfigurationRevision, FieldRevision, RowChangeset, RowRevision};
use flowy_grid_data_model::revision::{
CheckboxGroupConfigurationRevision, FieldRevision, GroupRecordRevision, RowChangeset, RowRevision,
};
pub type CheckboxGroupController = GenericGroupController< pub type CheckboxGroupController = GenericGroupController<
CheckboxGroupConfigurationRevision, CheckboxGroupConfigurationRevision,
@ -17,23 +15,6 @@ pub type CheckboxGroupController = GenericGroupController<
>; >;
pub type CheckboxGroupConfiguration = GenericGroupConfiguration<CheckboxGroupConfigurationRevision>; pub type CheckboxGroupConfiguration = GenericGroupConfiguration<CheckboxGroupConfigurationRevision>;
impl GroupConfigurationAction for CheckboxGroupConfiguration {
fn group_records(&self) -> &[GroupRecordRevision] {
&[]
}
fn merge_groups(&self, groups: Vec<Group>) -> FlowyResult<()> {
Ok(())
}
fn hide_group(&self, group_id: &str) -> FlowyResult<()> {
Ok(())
}
fn show_group(&self, group_id: &str) -> FlowyResult<()> {
Ok(())
}
}
impl GroupAction for CheckboxGroupController { impl GroupAction for CheckboxGroupController {
type CellDataType = CheckboxCellData; type CellDataType = CheckboxCellData;
@ -82,8 +63,8 @@ impl GroupGenerator for CheckboxGroupGenerator {
fn generate_groups( fn generate_groups(
field_id: &str, field_id: &str,
configuration: &Self::ConfigurationType, _configuration: &Self::ConfigurationType,
type_option: &Option<Self::TypeOptionType>, _type_option: &Option<Self::TypeOptionType>,
) -> Vec<Group> { ) -> Vec<Group> {
let check_group = Group::new( let check_group = Group::new(
"true".to_string(), "true".to_string(),

View File

@ -4,3 +4,4 @@ mod util;
pub use multi_select_controller::*; pub use multi_select_controller::*;
pub use single_select_controller::*; pub use single_select_controller::*;
pub use util::*;

View File

@ -3,9 +3,9 @@ use crate::services::cell::insert_select_option_cell;
use crate::services::field::{MultiSelectTypeOptionPB, SelectOptionCellDataPB, SelectOptionCellDataParser}; use crate::services::field::{MultiSelectTypeOptionPB, SelectOptionCellDataPB, SelectOptionCellDataParser};
use crate::services::group::action::GroupAction; use crate::services::group::action::GroupAction;
use crate::services::group::controller::{GenericGroupController, GroupController, GroupGenerator};
use crate::services::group::controller_impls::select_option_controller::util::*; use crate::services::group::controller_impls::select_option_controller::util::*;
use crate::services::group::entities::Group; use crate::services::group::entities::Group;
use crate::services::group::group_controller::{GenericGroupController, GroupController, GroupGenerator};
use flowy_grid_data_model::revision::{ use flowy_grid_data_model::revision::{
FieldRevision, RowChangeset, RowRevision, SelectOptionGroupConfigurationRevision, FieldRevision, RowChangeset, RowRevision, SelectOptionGroupConfigurationRevision,
}; };
@ -88,7 +88,7 @@ impl GroupGenerator for MultiSelectGroupGenerator {
type TypeOptionType = MultiSelectTypeOptionPB; type TypeOptionType = MultiSelectTypeOptionPB;
fn generate_groups( fn generate_groups(
field_id: &str, field_id: &str,
configuration: &Self::ConfigurationType, _configuration: &Self::ConfigurationType,
type_option: &Option<Self::TypeOptionType>, type_option: &Option<Self::TypeOptionType>,
) -> Vec<Group> { ) -> Vec<Group> {
match type_option { match type_option {

View File

@ -3,9 +3,9 @@ use crate::services::cell::insert_select_option_cell;
use crate::services::field::{SelectOptionCellDataPB, SelectOptionCellDataParser, SingleSelectTypeOptionPB}; use crate::services::field::{SelectOptionCellDataPB, SelectOptionCellDataParser, SingleSelectTypeOptionPB};
use crate::services::group::action::GroupAction; use crate::services::group::action::GroupAction;
use crate::services::group::controller::{GenericGroupController, GroupController, GroupGenerator};
use crate::services::group::controller_impls::select_option_controller::util::*; use crate::services::group::controller_impls::select_option_controller::util::*;
use crate::services::group::entities::Group; use crate::services::group::entities::Group;
use crate::services::group::group_controller::{GenericGroupController, GroupController, GroupGenerator};
use flowy_grid_data_model::revision::{ use flowy_grid_data_model::revision::{
FieldRevision, RowChangeset, RowRevision, SelectOptionGroupConfigurationRevision, FieldRevision, RowChangeset, RowRevision, SelectOptionGroupConfigurationRevision,
@ -89,7 +89,7 @@ impl GroupGenerator for SingleSelectGroupGenerator {
type TypeOptionType = SingleSelectTypeOptionPB; type TypeOptionType = SingleSelectTypeOptionPB;
fn generate_groups( fn generate_groups(
field_id: &str, field_id: &str,
configuration: &Self::ConfigurationType, _configuration: &Self::ConfigurationType,
type_option: &Option<Self::TypeOptionType>, type_option: &Option<Self::TypeOptionType>,
) -> Vec<Group> { ) -> Vec<Group> {
match type_option { match type_option {

View File

@ -1,33 +1,14 @@
use crate::entities::{GroupRowsChangesetPB, InsertedRowPB, RowPB}; use crate::entities::{GroupRowsChangesetPB, InsertedRowPB, RowPB};
use crate::services::cell::insert_select_option_cell; use crate::services::cell::insert_select_option_cell;
use crate::services::field::SelectOptionCellDataPB; use crate::services::field::SelectOptionCellDataPB;
use crate::services::group::configuration::{GenericGroupConfiguration, GroupConfigurationAction}; use crate::services::group::configuration::GenericGroupConfiguration;
use crate::services::group::Group; use crate::services::group::Group;
use flowy_error::FlowyResult;
use flowy_grid_data_model::revision::{ use flowy_grid_data_model::revision::{
FieldRevision, GroupRecordRevision, RowChangeset, RowRevision, SelectOptionGroupConfigurationRevision, FieldRevision, RowChangeset, RowRevision, SelectOptionGroupConfigurationRevision,
}; };
pub type SelectOptionGroupConfiguration = GenericGroupConfiguration<SelectOptionGroupConfigurationRevision>; pub type SelectOptionGroupConfiguration = GenericGroupConfiguration<SelectOptionGroupConfigurationRevision>;
impl GroupConfigurationAction for SelectOptionGroupConfiguration {
fn group_records(&self) -> &[GroupRecordRevision] {
// self.configuration.as_slice()
todo!()
}
fn merge_groups(&self, groups: Vec<Group>) -> FlowyResult<()> {
// self.writer.save_group_configuration()
todo!()
}
fn hide_group(&self, group_id: &str) -> FlowyResult<()> {
todo!()
}
fn show_group(&self, group_id: &str) -> FlowyResult<()> {
todo!()
}
}
pub fn add_row( pub fn add_row(
group: &mut Group, group: &mut Group,

View File

@ -1,7 +1,8 @@
use crate::services::group::configuration::GroupConfigurationReader; use crate::services::group::configuration::GroupConfigurationReader;
use crate::services::group::group_controller::GroupController; use crate::services::group::controller::GroupController;
use crate::services::group::{ use crate::services::group::{
CheckboxGroupController, Group, GroupConfigurationWriter, MultiSelectGroupController, SingleSelectGroupController, CheckboxGroupConfiguration, CheckboxGroupController, Group, GroupConfigurationWriter, MultiSelectGroupController,
SelectOptionGroupConfiguration, SingleSelectGroupController,
}; };
use flowy_error::FlowyResult; use flowy_error::FlowyResult;
use flowy_grid_data_model::revision::{ use flowy_grid_data_model::revision::{
@ -35,8 +36,8 @@ impl GroupService {
} }
pub(crate) async fn groups(&self) -> Vec<Group> { pub(crate) async fn groups(&self) -> Vec<Group> {
// if let Some(group_action_handler) = self.group_controller.as_ref() { // if let Some(group_controller) = self.group_controller.as_ref() {
// group_action_handler.read().await.groups() // group_controller.read().await.groups()
// } else { // } else {
// vec![] // vec![]
// } // }
@ -182,30 +183,33 @@ impl GroupService {
// let generator = GroupGenerator::<DateGroupConfigurationPB>::from_configuration(configuration); // let generator = GroupGenerator::<DateGroupConfigurationPB>::from_configuration(configuration);
} }
FieldType::SingleSelect => { FieldType::SingleSelect => {
let controller = SingleSelectGroupController::new( let configuration = SelectOptionGroupConfiguration::new(
field_rev, field_rev.clone(),
self.configuration_reader.clone(), self.configuration_reader.clone(),
self.configuration_writer.clone(), self.configuration_writer.clone(),
) )
.await?; .await?;
let controller = SingleSelectGroupController::new(field_rev, configuration).await?;
group_controller = Some(Arc::new(RwLock::new(controller))); group_controller = Some(Arc::new(RwLock::new(controller)));
} }
FieldType::MultiSelect => { FieldType::MultiSelect => {
let controller = MultiSelectGroupController::new( let configuration = SelectOptionGroupConfiguration::new(
field_rev, field_rev.clone(),
self.configuration_reader.clone(), self.configuration_reader.clone(),
self.configuration_writer.clone(), self.configuration_writer.clone(),
) )
.await?; .await?;
let controller = MultiSelectGroupController::new(field_rev, configuration).await?;
group_controller = Some(Arc::new(RwLock::new(controller))); group_controller = Some(Arc::new(RwLock::new(controller)));
} }
FieldType::Checkbox => { FieldType::Checkbox => {
let controller = CheckboxGroupController::new( let configuration = CheckboxGroupConfiguration::new(
field_rev, field_rev.clone(),
self.configuration_reader.clone(), self.configuration_reader.clone(),
self.configuration_writer.clone(), self.configuration_writer.clone(),
) )
.await?; .await?;
let controller = CheckboxGroupController::new(field_rev, configuration).await?;
group_controller = Some(Arc::new(RwLock::new(controller))) group_controller = Some(Arc::new(RwLock::new(controller)))
} }
FieldType::URL => { FieldType::URL => {
@ -229,7 +233,7 @@ fn find_group_field(field_revs: &[Arc<FieldRevision>]) -> Option<Arc<FieldRevisi
pub fn default_group_configuration(field_rev: &FieldRevision) -> GroupConfigurationRevision { pub fn default_group_configuration(field_rev: &FieldRevision) -> GroupConfigurationRevision {
let field_id = field_rev.id.clone(); let field_id = field_rev.id.clone();
let field_type_rev = field_rev.ty.clone(); let field_type_rev = field_rev.ty;
let field_type: FieldType = field_rev.ty.into(); let field_type: FieldType = field_rev.ty.into();
match field_type { match field_type {
FieldType::RichText => { FieldType::RichText => {

View File

@ -1,8 +1,8 @@
mod action; mod action;
mod configuration; mod configuration;
mod controller;
mod controller_impls; mod controller_impls;
mod entities; mod entities;
mod group_controller;
mod group_service; mod group_service;
pub(crate) use configuration::*; pub(crate) use configuration::*;

View File

@ -1,7 +1,6 @@
use crate::grid::grid_editor::GridEditorTest; use crate::grid::grid_editor::GridEditorTest;
use flowy_grid::entities::InsertFieldParams; use flowy_grid::entities::{FieldChangesetParams, InsertFieldParams};
use flowy_grid_data_model::revision::FieldRevision; use flowy_grid_data_model::revision::FieldRevision;
use flowy_sync::entities::grid::FieldChangesetParams;
pub enum FieldScript { pub enum FieldScript {
CreateField { CreateField {

View File

@ -1,10 +1,10 @@
use crate::grid::field_test::script::FieldScript::*; use crate::grid::field_test::script::FieldScript::*;
use crate::grid::field_test::script::GridFieldTest; use crate::grid::field_test::script::GridFieldTest;
use crate::grid::field_test::util::*; use crate::grid::field_test::util::*;
use flowy_grid::entities::FieldChangesetParams;
use flowy_grid::services::field::selection_type_option::SelectOptionPB; use flowy_grid::services::field::selection_type_option::SelectOptionPB;
use flowy_grid::services::field::SingleSelectTypeOptionPB; use flowy_grid::services::field::SingleSelectTypeOptionPB;
use flowy_grid_data_model::revision::TypeOptionDataEntry; use flowy_grid_data_model::revision::TypeOptionDataEntry;
use flowy_sync::entities::grid::FieldChangesetParams;
#[tokio::test] #[tokio::test]
async fn grid_create_field() { async fn grid_create_field() {

View File

@ -3,10 +3,9 @@
#![allow(dead_code)] #![allow(dead_code)]
#![allow(unused_imports)] #![allow(unused_imports)]
use flowy_grid::entities::{CreateGridFilterPayloadPB, GridLayout, GridSettingPB}; use flowy_grid::entities::{CreateFilterParams, CreateGridFilterPayloadPB, DeleteFilterParams, GridLayout, GridSettingChangesetParams, GridSettingPB};
use flowy_grid::services::setting::GridSettingChangesetBuilder; use flowy_grid::services::setting::GridSettingChangesetBuilder;
use flowy_grid_data_model::revision::{FieldRevision, FieldTypeRevision}; use flowy_grid_data_model::revision::{FieldRevision, FieldTypeRevision};
use flowy_sync::entities::grid::{CreateFilterParams, DeleteFilterParams, GridSettingChangesetParams};
use crate::grid::grid_editor::GridEditorTest; use crate::grid::grid_editor::GridEditorTest;
pub enum FilterScript { pub enum FilterScript {

View File

@ -12,9 +12,6 @@ use flowy_grid::services::setting::GridSettingChangesetBuilder;
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;
use flowy_sync::client_grid::GridBuilder; use flowy_sync::client_grid::GridBuilder;
use flowy_sync::entities::grid::{
CreateFilterParams, DeleteFilterParams, FieldChangesetParams, GridSettingChangesetParams,
};
use flowy_test::helper::ViewTest; use flowy_test::helper::ViewTest;
use flowy_test::FlowySDKTest; use flowy_test::FlowySDKTest;
use std::collections::HashMap; use std::collections::HashMap;

View File

@ -3,8 +3,21 @@ use serde::{Deserialize, Serialize};
use serde_json::Error; use serde_json::Error;
use serde_repr::*; use serde_repr::*;
pub trait GroupConfigurationContentSerde: Sized { pub trait GroupConfigurationContent: Sized {
fn from_configuration_content(s: &str) -> Result<Self, serde_json::Error>; fn from_configuration_content(s: &str) -> Result<Self, serde_json::Error>;
fn get_groups(&self) -> &[GroupRecordRevision] {
&[]
}
fn mut_group<F>(&mut self, _group_id: &str, _f: F)
where
F: FnOnce(&mut GroupRecordRevision),
{
}
fn set_groups(&mut self, _new_groups: Vec<GroupRecordRevision>) {}
fn to_configuration_content(&self) -> Result<String, serde_json::Error>; fn to_configuration_content(&self) -> Result<String, serde_json::Error>;
} }
@ -36,7 +49,7 @@ pub struct TextGroupConfigurationRevision {
pub hide_empty: bool, pub hide_empty: bool,
} }
impl GroupConfigurationContentSerde for TextGroupConfigurationRevision { impl GroupConfigurationContent for TextGroupConfigurationRevision {
fn from_configuration_content(s: &str) -> Result<Self, Error> { fn from_configuration_content(s: &str) -> Result<Self, Error> {
serde_json::from_str(s) serde_json::from_str(s)
} }
@ -50,7 +63,7 @@ pub struct NumberGroupConfigurationRevision {
pub hide_empty: bool, pub hide_empty: bool,
} }
impl GroupConfigurationContentSerde for NumberGroupConfigurationRevision { impl GroupConfigurationContent for NumberGroupConfigurationRevision {
fn from_configuration_content(s: &str) -> Result<Self, Error> { fn from_configuration_content(s: &str) -> Result<Self, Error> {
serde_json::from_str(s) serde_json::from_str(s)
} }
@ -64,7 +77,7 @@ pub struct UrlGroupConfigurationRevision {
pub hide_empty: bool, pub hide_empty: bool,
} }
impl GroupConfigurationContentSerde for UrlGroupConfigurationRevision { impl GroupConfigurationContent for UrlGroupConfigurationRevision {
fn from_configuration_content(s: &str) -> Result<Self, Error> { fn from_configuration_content(s: &str) -> Result<Self, Error> {
serde_json::from_str(s) serde_json::from_str(s)
} }
@ -78,7 +91,7 @@ pub struct CheckboxGroupConfigurationRevision {
pub hide_empty: bool, pub hide_empty: bool,
} }
impl GroupConfigurationContentSerde for CheckboxGroupConfigurationRevision { impl GroupConfigurationContent for CheckboxGroupConfigurationRevision {
fn from_configuration_content(s: &str) -> Result<Self, Error> { fn from_configuration_content(s: &str) -> Result<Self, Error> {
serde_json::from_str(s) serde_json::from_str(s)
} }
@ -94,17 +107,35 @@ pub struct SelectOptionGroupConfigurationRevision {
pub groups: Vec<GroupRecordRevision>, pub groups: Vec<GroupRecordRevision>,
} }
impl GroupConfigurationContentSerde for SelectOptionGroupConfigurationRevision { impl GroupConfigurationContent for SelectOptionGroupConfigurationRevision {
fn from_configuration_content(s: &str) -> Result<Self, Error> { fn from_configuration_content(s: &str) -> Result<Self, Error> {
serde_json::from_str(s) serde_json::from_str(s)
} }
fn get_groups(&self) -> &[GroupRecordRevision] {
&self.groups
}
fn mut_group<F>(&mut self, group_id: &str, f: F)
where
F: FnOnce(&mut GroupRecordRevision),
{
match self.groups.iter_mut().find(|group| group.group_id == group_id) {
None => {}
Some(group) => f(group),
}
}
fn set_groups(&mut self, new_groups: Vec<GroupRecordRevision>) {
self.groups = new_groups;
}
fn to_configuration_content(&self) -> Result<String, Error> { fn to_configuration_content(&self) -> Result<String, Error> {
serde_json::to_string(self) serde_json::to_string(self)
} }
} }
#[derive(Default, Serialize, Deserialize)] #[derive(Clone, Default, Serialize, Deserialize)]
pub struct GroupRecordRevision { pub struct GroupRecordRevision {
pub group_id: String, pub group_id: String,
@ -113,13 +144,22 @@ pub struct GroupRecordRevision {
} }
const DEFAULT_GROUP_RECORD_VISIBILITY: fn() -> bool = || true; const DEFAULT_GROUP_RECORD_VISIBILITY: fn() -> bool = || true;
impl GroupRecordRevision {
pub fn new(group_id: String) -> Self {
Self {
group_id,
visible: true,
}
}
}
#[derive(Default, Serialize, Deserialize)] #[derive(Default, Serialize, Deserialize)]
pub struct DateGroupConfigurationRevision { pub struct DateGroupConfigurationRevision {
pub hide_empty: bool, pub hide_empty: bool,
pub condition: DateCondition, pub condition: DateCondition,
} }
impl GroupConfigurationContentSerde for DateGroupConfigurationRevision { impl GroupConfigurationContent for DateGroupConfigurationRevision {
fn from_configuration_content(s: &str) -> Result<Self, Error> { fn from_configuration_content(s: &str) -> Result<Self, Error> {
serde_json::from_str(s) serde_json::from_str(s)
} }

View File

@ -70,15 +70,15 @@ impl GridViewRevisionPad {
&mut self, &mut self,
field_id: &str, field_id: &str,
field_type: &FieldTypeRevision, field_type: &FieldTypeRevision,
group_id: &str, configuration_id: &str,
mut_group_fn: F, mut_configuration_fn: F,
) -> CollaborateResult<Option<GridViewRevisionChangeset>> { ) -> CollaborateResult<Option<GridViewRevisionChangeset>> {
self.modify(|view| match view.groups.get_mut_objects(field_id, field_type) { self.modify(|view| match view.groups.get_mut_objects(field_id, field_type) {
None => Ok(None), None => Ok(None),
Some(groups) => { Some(configurations_revs) => {
for mut group in groups { for configuration_rev in configurations_revs {
if group.id == group_id { if configuration_rev.id == configuration_id {
mut_group_fn(Arc::make_mut(&mut group)); mut_configuration_fn(Arc::make_mut(configuration_rev));
return Ok(Some(())); return Ok(Some(()));
} }
} }
@ -170,6 +170,7 @@ impl GridViewRevisionPad {
} }
} }
#[derive(Debug)]
pub struct GridViewRevisionChangeset { pub struct GridViewRevisionChangeset {
pub delta: TextDelta, pub delta: TextDelta,
pub md5: String, pub md5: String,