mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: generic GroupGenerator
This commit is contained in:
parent
461751cf59
commit
707ddb4e73
@ -66,7 +66,7 @@ pub fn apply_cell_data_changeset<C: ToString, T: AsRef<FieldRevision>>(
|
|||||||
SingleSelectTypeOptionPB::from(field_rev).apply_changeset(changeset.into(), cell_rev)
|
SingleSelectTypeOptionPB::from(field_rev).apply_changeset(changeset.into(), cell_rev)
|
||||||
}
|
}
|
||||||
FieldType::MultiSelect => MultiSelectTypeOptionPB::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::Checkbox => CheckboxTypeOptionPB::from(field_rev).apply_changeset(changeset.into(), cell_rev),
|
||||||
FieldType::URL => URLTypeOptionPB::from(field_rev).apply_changeset(changeset.into(), cell_rev),
|
FieldType::URL => URLTypeOptionPB::from(field_rev).apply_changeset(changeset.into(), cell_rev),
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
@ -116,7 +116,7 @@ pub fn try_decode_cell_data(
|
|||||||
.get_type_option_entry::<MultiSelectTypeOptionPB>(field_type)?
|
.get_type_option_entry::<MultiSelectTypeOptionPB>(field_type)?
|
||||||
.decode_cell_data(cell_data.into(), s_field_type, field_rev),
|
.decode_cell_data(cell_data.into(), s_field_type, field_rev),
|
||||||
FieldType::Checkbox => field_rev
|
FieldType::Checkbox => field_rev
|
||||||
.get_type_option_entry::<CheckboxTypeOption>(field_type)?
|
.get_type_option_entry::<CheckboxTypeOptionPB>(field_type)?
|
||||||
.decode_cell_data(cell_data.into(), s_field_type, field_rev),
|
.decode_cell_data(cell_data.into(), s_field_type, field_rev),
|
||||||
FieldType::URL => field_rev
|
FieldType::URL => field_rev
|
||||||
.get_type_option_entry::<URLTypeOptionPB>(field_type)?
|
.get_type_option_entry::<URLTypeOptionPB>(field_type)?
|
||||||
|
@ -95,7 +95,7 @@ pub fn default_type_option_builder_from_type(field_type: &FieldType) -> Box<dyn
|
|||||||
FieldType::DateTime => DateTypeOptionPB::default().into(),
|
FieldType::DateTime => DateTypeOptionPB::default().into(),
|
||||||
FieldType::SingleSelect => SingleSelectTypeOptionPB::default().into(),
|
FieldType::SingleSelect => SingleSelectTypeOptionPB::default().into(),
|
||||||
FieldType::MultiSelect => MultiSelectTypeOptionPB::default().into(),
|
FieldType::MultiSelect => MultiSelectTypeOptionPB::default().into(),
|
||||||
FieldType::Checkbox => CheckboxTypeOption::default().into(),
|
FieldType::Checkbox => CheckboxTypeOptionPB::default().into(),
|
||||||
FieldType::URL => URLTypeOptionPB::default().into(),
|
FieldType::URL => URLTypeOptionPB::default().into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn checkout_box_description_test() {
|
fn checkout_box_description_test() {
|
||||||
let type_option = CheckboxTypeOption::default();
|
let type_option = CheckboxTypeOptionPB::default();
|
||||||
let field_type = FieldType::Checkbox;
|
let field_type = FieldType::Checkbox;
|
||||||
let field_rev = FieldBuilder::from_field_type(&field_type).build();
|
let field_rev = FieldBuilder::from_field_type(&field_type).build();
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn assert_checkbox(
|
fn assert_checkbox(
|
||||||
type_option: &CheckboxTypeOption,
|
type_option: &CheckboxTypeOptionPB,
|
||||||
input_str: &str,
|
input_str: &str,
|
||||||
expected_str: &str,
|
expected_str: &str,
|
||||||
field_type: &FieldType,
|
field_type: &FieldType,
|
||||||
|
@ -10,9 +10,9 @@ use serde::{Deserialize, Serialize};
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct CheckboxTypeOptionBuilder(CheckboxTypeOption);
|
pub struct CheckboxTypeOptionBuilder(CheckboxTypeOptionPB);
|
||||||
impl_into_box_type_option_builder!(CheckboxTypeOptionBuilder);
|
impl_into_box_type_option_builder!(CheckboxTypeOptionBuilder);
|
||||||
impl_builder_from_json_str_and_from_bytes!(CheckboxTypeOptionBuilder, CheckboxTypeOption);
|
impl_builder_from_json_str_and_from_bytes!(CheckboxTypeOptionBuilder, CheckboxTypeOptionPB);
|
||||||
|
|
||||||
impl CheckboxTypeOptionBuilder {
|
impl CheckboxTypeOptionBuilder {
|
||||||
pub fn set_selected(mut self, is_selected: bool) -> Self {
|
pub fn set_selected(mut self, is_selected: bool) -> Self {
|
||||||
@ -32,13 +32,13 @@ impl TypeOptionBuilder for CheckboxTypeOptionBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, Default, ProtoBuf)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Default, ProtoBuf)]
|
||||||
pub struct CheckboxTypeOption {
|
pub struct CheckboxTypeOptionPB {
|
||||||
#[pb(index = 1)]
|
#[pb(index = 1)]
|
||||||
pub is_selected: bool,
|
pub is_selected: bool,
|
||||||
}
|
}
|
||||||
impl_type_option!(CheckboxTypeOption, FieldType::Checkbox);
|
impl_type_option!(CheckboxTypeOptionPB, FieldType::Checkbox);
|
||||||
|
|
||||||
impl CellDisplayable<CheckboxCellData> for CheckboxTypeOption {
|
impl CellDisplayable<CheckboxCellData> for CheckboxTypeOptionPB {
|
||||||
fn display_data(
|
fn display_data(
|
||||||
&self,
|
&self,
|
||||||
cell_data: CellData<CheckboxCellData>,
|
cell_data: CellData<CheckboxCellData>,
|
||||||
@ -50,7 +50,7 @@ impl CellDisplayable<CheckboxCellData> for CheckboxTypeOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CellDataOperation<CheckboxCellData, String> for CheckboxTypeOption {
|
impl CellDataOperation<CheckboxCellData, String> for CheckboxTypeOptionPB {
|
||||||
fn decode_cell_data(
|
fn decode_cell_data(
|
||||||
&self,
|
&self,
|
||||||
cell_data: CellData<CheckboxCellData>,
|
cell_data: CellData<CheckboxCellData>,
|
||||||
|
@ -3,7 +3,7 @@ use crate::entities::{FieldType, GridBlockChangesetPB};
|
|||||||
use crate::services::block_manager::GridBlockManager;
|
use crate::services::block_manager::GridBlockManager;
|
||||||
use crate::services::cell::{AnyCellData, CellFilterOperation};
|
use crate::services::cell::{AnyCellData, CellFilterOperation};
|
||||||
use crate::services::field::{
|
use crate::services::field::{
|
||||||
CheckboxTypeOption, DateTypeOptionPB, MultiSelectTypeOptionPB, NumberTypeOptionPB, RichTextTypeOptionPB,
|
CheckboxTypeOptionPB, DateTypeOptionPB, MultiSelectTypeOptionPB, NumberTypeOptionPB, RichTextTypeOptionPB,
|
||||||
SingleSelectTypeOptionPB, URLTypeOptionPB,
|
SingleSelectTypeOptionPB, URLTypeOptionPB,
|
||||||
};
|
};
|
||||||
use crate::services::filter::filter_cache::{
|
use crate::services::filter::filter_cache::{
|
||||||
@ -222,7 +222,7 @@ fn filter_cell(
|
|||||||
FieldType::Checkbox => filter_cache.checkbox_filter.get(&filter_id).and_then(|filter| {
|
FieldType::Checkbox => filter_cache.checkbox_filter.get(&filter_id).and_then(|filter| {
|
||||||
Some(
|
Some(
|
||||||
field_rev
|
field_rev
|
||||||
.get_type_option_entry::<CheckboxTypeOption>(field_type_rev)?
|
.get_type_option_entry::<CheckboxTypeOptionPB>(field_type_rev)?
|
||||||
.apply_filter(any_cell_data, filter.value())
|
.apply_filter(any_cell_data, filter.value())
|
||||||
.ok(),
|
.ok(),
|
||||||
)
|
)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::entities::{CheckboxCondition, CheckboxFilterConfigurationPB};
|
use crate::entities::{CheckboxCondition, CheckboxFilterConfigurationPB};
|
||||||
use crate::services::cell::{AnyCellData, CellData, CellFilterOperation};
|
use crate::services::cell::{AnyCellData, CellData, CellFilterOperation};
|
||||||
use crate::services::field::{CheckboxCellData, CheckboxTypeOption};
|
use crate::services::field::{CheckboxCellData, CheckboxTypeOptionPB};
|
||||||
use flowy_error::FlowyResult;
|
use flowy_error::FlowyResult;
|
||||||
|
|
||||||
impl CheckboxFilterConfigurationPB {
|
impl CheckboxFilterConfigurationPB {
|
||||||
@ -13,7 +13,7 @@ impl CheckboxFilterConfigurationPB {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CellFilterOperation<CheckboxFilterConfigurationPB> for CheckboxTypeOption {
|
impl CellFilterOperation<CheckboxFilterConfigurationPB> for CheckboxTypeOptionPB {
|
||||||
fn apply_filter(&self, any_cell_data: AnyCellData, filter: &CheckboxFilterConfigurationPB) -> FlowyResult<bool> {
|
fn apply_filter(&self, any_cell_data: AnyCellData, filter: &CheckboxFilterConfigurationPB) -> FlowyResult<bool> {
|
||||||
if !any_cell_data.is_checkbox() {
|
if !any_cell_data.is_checkbox() {
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
|
@ -0,0 +1,70 @@
|
|||||||
|
use crate::entities::{
|
||||||
|
CheckboxGroupConfigurationPB, DateGroupConfigurationPB, NumberGroupConfigurationPB,
|
||||||
|
SelectOptionGroupConfigurationPB, TextGroupConfigurationPB, UrlGroupConfigurationPB,
|
||||||
|
};
|
||||||
|
use crate::services::cell::CellBytes;
|
||||||
|
use crate::services::field::{
|
||||||
|
CheckboxCellDataParser, DateCellDataParser, NumberCellDataParser, NumberFormat, SelectOptionCellDataParser,
|
||||||
|
TextCellDataParser, URLCellDataParser,
|
||||||
|
};
|
||||||
|
use crate::services::group::GroupAction;
|
||||||
|
|
||||||
|
// impl GroupAction for TextGroupConfigurationPB {
|
||||||
|
// fn should_group(&self, content: &str, cell_bytes: CellBytes) -> bool {
|
||||||
|
// if let Ok(cell_data) = cell_bytes.with_parser(TextCellDataParser()) {
|
||||||
|
// cell_data.as_ref() == content
|
||||||
|
// } else {
|
||||||
|
// false
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// impl GroupAction for NumberGroupConfigurationPB {
|
||||||
|
// fn should_group(&self, content: &str, cell_bytes: CellBytes) -> bool {
|
||||||
|
// if let Ok(cell_data) = cell_bytes.with_parser(NumberCellDataParser(NumberFormat::Num)) {
|
||||||
|
// false
|
||||||
|
// } else {
|
||||||
|
// false
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// impl GroupAction for DateGroupConfigurationPB {
|
||||||
|
// fn should_group(&self, content: &str, cell_bytes: CellBytes) -> bool {
|
||||||
|
// if let Ok(cell_data) = cell_bytes.with_parser(DateCellDataParser()) {
|
||||||
|
// false
|
||||||
|
// } else {
|
||||||
|
// false
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// impl GroupAction for SelectOptionGroupConfigurationPB {
|
||||||
|
// fn should_group(&self, content: &str, cell_bytes: CellBytes) -> bool {
|
||||||
|
// if let Ok(cell_data) = cell_bytes.with_parser(SelectOptionCellDataParser()) {
|
||||||
|
// false
|
||||||
|
// } else {
|
||||||
|
// false
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// impl GroupAction for UrlGroupConfigurationPB {
|
||||||
|
// fn should_group(&self, content: &str, cell_bytes: CellBytes) -> bool {
|
||||||
|
// if let Ok(cell_data) = cell_bytes.with_parser(URLCellDataParser()) {
|
||||||
|
// false
|
||||||
|
// } else {
|
||||||
|
// false
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// impl GroupAction for CheckboxGroupConfigurationPB {
|
||||||
|
// fn should_group(&self, content: &str, cell_bytes: CellBytes) -> bool {
|
||||||
|
// if let Ok(cell_data) = cell_bytes.with_parser(CheckboxCellDataParser()) {
|
||||||
|
// false
|
||||||
|
// } else {
|
||||||
|
// false
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
@ -0,0 +1,7 @@
|
|||||||
|
use crate::entities::CheckboxGroupConfigurationPB;
|
||||||
|
use crate::services::cell::{AnyCellData, CellData, CellGroupOperation};
|
||||||
|
use crate::services::field::{CheckboxCellData, CheckboxTypeOptionPB};
|
||||||
|
use crate::services::group::GroupController;
|
||||||
|
use flowy_error::FlowyResult;
|
||||||
|
|
||||||
|
// pub type CheckboxGroupGenerator = GroupGenerator<CheckboxGroupConfigurationPB, CheckboxTypeOptionPB>;
|
@ -0,0 +1,5 @@
|
|||||||
|
use crate::entities::CheckboxGroupConfigurationPB;
|
||||||
|
use crate::services::field::DateTypeOptionPB;
|
||||||
|
use crate::services::group::GroupController;
|
||||||
|
|
||||||
|
// pub type CheckboxGroupGenerator = GroupGenerator<CheckboxGroupConfigurationPB, DateTypeOptionPB>;
|
@ -0,0 +1,88 @@
|
|||||||
|
use crate::services::cell::{decode_any_cell_data, CellBytes};
|
||||||
|
use bytes::Bytes;
|
||||||
|
use flowy_error::FlowyResult;
|
||||||
|
use flowy_grid_data_model::revision::{
|
||||||
|
CellRevision, FieldRevision, GroupConfigurationRevision, RowRevision, TypeOptionDataDeserializer,
|
||||||
|
};
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
pub trait GroupAction {
|
||||||
|
fn should_group(&mut self, content: &str, cell_bytes: CellBytes) -> bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait GroupCellContentProvider {
|
||||||
|
/// We need to group the rows base on the deduplication cell content when the field type is
|
||||||
|
/// RichText.
|
||||||
|
fn deduplication_cell_content(&self, field_id: &str) -> Vec<String> {
|
||||||
|
vec![]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait GroupGenerator<C, T> {
|
||||||
|
fn gen_groups(
|
||||||
|
configuration: &Option<C>,
|
||||||
|
type_option: &Option<T>,
|
||||||
|
cell_content_provider: &dyn GroupCellContentProvider,
|
||||||
|
) -> Vec<Group>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct GroupController<C, T, G> {
|
||||||
|
field_rev: Arc<FieldRevision>,
|
||||||
|
groups: Vec<Group>,
|
||||||
|
type_option: Option<T>,
|
||||||
|
configuration: Option<C>,
|
||||||
|
phantom: PhantomData<G>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Group {
|
||||||
|
row_ids: Vec<String>,
|
||||||
|
content: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C, T, G> GroupController<C, T, G>
|
||||||
|
where
|
||||||
|
C: TryFrom<Bytes, Error = protobuf::ProtobufError>,
|
||||||
|
T: TypeOptionDataDeserializer,
|
||||||
|
G: GroupGenerator<C, T>,
|
||||||
|
{
|
||||||
|
pub fn new(
|
||||||
|
field_rev: Arc<FieldRevision>,
|
||||||
|
configuration: GroupConfigurationRevision,
|
||||||
|
cell_content_provider: &dyn GroupCellContentProvider,
|
||||||
|
) -> FlowyResult<Self> {
|
||||||
|
let configuration = match configuration.content {
|
||||||
|
None => None,
|
||||||
|
Some(content) => Some(C::try_from(Bytes::from(content))?),
|
||||||
|
};
|
||||||
|
let field_type_rev = field_rev.field_type_rev.clone();
|
||||||
|
let type_option = field_rev.get_type_option_entry::<T>(field_type_rev);
|
||||||
|
Ok(Self {
|
||||||
|
field_rev,
|
||||||
|
groups: G::gen_groups(&configuration, &type_option, cell_content_provider),
|
||||||
|
type_option,
|
||||||
|
configuration,
|
||||||
|
phantom: PhantomData,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C, T, G> GroupController<C, T, G>
|
||||||
|
where
|
||||||
|
Self: GroupAction,
|
||||||
|
{
|
||||||
|
pub fn group_row(&mut self, row: &RowRevision) {
|
||||||
|
if self.configuration.is_none() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if let Some(cell_rev) = row.cells.get(&self.field_rev.id) {
|
||||||
|
for group in self.groups.iter_mut() {
|
||||||
|
let cell_rev: CellRevision = cell_rev.clone();
|
||||||
|
let cell_bytes = decode_any_cell_data(cell_rev.data, &self.field_rev);
|
||||||
|
// if self.should_group(&group.content, cell_bytes) {
|
||||||
|
// group.row_ids.push(row.id.clone());
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,15 @@
|
|||||||
mod checkbox_group;
|
mod checkbox_group;
|
||||||
mod date_group;
|
mod date_group;
|
||||||
|
mod generator;
|
||||||
mod number_group;
|
mod number_group;
|
||||||
mod select_option_group;
|
mod select_option_group;
|
||||||
mod text_group;
|
mod text_group;
|
||||||
|
mod url_group;
|
||||||
|
|
||||||
pub use checkbox_group::*;
|
pub use checkbox_group::*;
|
||||||
pub use date_group::*;
|
pub use date_group::*;
|
||||||
|
pub use generator::*;
|
||||||
pub use number_group::*;
|
pub use number_group::*;
|
||||||
pub use select_option_group::*;
|
pub use select_option_group::*;
|
||||||
pub use text_group::*;
|
pub use text_group::*;
|
||||||
|
pub use url_group::*;
|
@ -0,0 +1,5 @@
|
|||||||
|
use crate::entities::NumberGroupConfigurationPB;
|
||||||
|
use crate::services::field::NumberTypeOptionPB;
|
||||||
|
use crate::services::group::GroupController;
|
||||||
|
|
||||||
|
// pub type NumberGroupGenerator = GroupGenerator<NumberGroupConfigurationPB, NumberTypeOptionPB>;
|
@ -0,0 +1,44 @@
|
|||||||
|
use crate::entities::SelectOptionGroupConfigurationPB;
|
||||||
|
use crate::services::cell::CellBytes;
|
||||||
|
use crate::services::field::{MultiSelectTypeOptionPB, SelectedSelectOptions, SingleSelectTypeOptionPB};
|
||||||
|
use crate::services::group::{Group, GroupAction, GroupCellContentProvider, GroupController, GroupGenerator};
|
||||||
|
|
||||||
|
pub type SingleSelectGroupController =
|
||||||
|
GroupController<SelectOptionGroupConfigurationPB, SingleSelectTypeOptionPB, SingleSelectGroupGen>;
|
||||||
|
|
||||||
|
pub struct SingleSelectGroupGen();
|
||||||
|
impl GroupGenerator<SelectOptionGroupConfigurationPB, SingleSelectTypeOptionPB> for SingleSelectGroupGen {
|
||||||
|
fn gen_groups(
|
||||||
|
configuration: &Option<SelectOptionGroupConfigurationPB>,
|
||||||
|
type_option: &Option<SingleSelectTypeOptionPB>,
|
||||||
|
cell_content_provider: &dyn GroupCellContentProvider,
|
||||||
|
) -> Vec<Group> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GroupAction for SingleSelectGroupController {
|
||||||
|
fn should_group(&mut self, content: &str, cell_bytes: CellBytes) -> bool {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type MultiSelectGroupController =
|
||||||
|
GroupController<SelectOptionGroupConfigurationPB, MultiSelectTypeOptionPB, MultiSelectGroupGen>;
|
||||||
|
|
||||||
|
pub struct MultiSelectGroupGen();
|
||||||
|
impl GroupGenerator<SelectOptionGroupConfigurationPB, MultiSelectTypeOptionPB> for MultiSelectGroupGen {
|
||||||
|
fn gen_groups(
|
||||||
|
configuration: &Option<SelectOptionGroupConfigurationPB>,
|
||||||
|
type_option: &Option<MultiSelectTypeOptionPB>,
|
||||||
|
cell_content_provider: &dyn GroupCellContentProvider,
|
||||||
|
) -> Vec<Group> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GroupAction for MultiSelectGroupController {
|
||||||
|
fn should_group(&mut self, content: &str, cell_bytes: CellBytes) -> bool {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
use crate::entities::TextGroupConfigurationPB;
|
||||||
|
use crate::services::field::RichTextTypeOptionPB;
|
||||||
|
use crate::services::group::GroupController;
|
||||||
|
|
||||||
|
// pub type TextGroupGenerator = GroupGenerator<TextGroupConfigurationPB, RichTextTypeOptionPB>;
|
@ -0,0 +1,5 @@
|
|||||||
|
use crate::entities::UrlGroupConfigurationPB;
|
||||||
|
use crate::services::field::URLTypeOptionPB;
|
||||||
|
use crate::services::group::GroupController;
|
||||||
|
|
||||||
|
// pub type UrlGroupGenerator = GroupGenerator<UrlGroupConfigurationPB, URLTypeOptionPB>;
|
@ -4,7 +4,9 @@ use crate::entities::{
|
|||||||
};
|
};
|
||||||
use crate::services::block_manager::GridBlockManager;
|
use crate::services::block_manager::GridBlockManager;
|
||||||
use crate::services::cell::{decode_any_cell_data, CellBytes};
|
use crate::services::cell::{decode_any_cell_data, CellBytes};
|
||||||
|
use crate::services::field::TextCellDataParser;
|
||||||
use crate::services::grid_editor_task::GridServiceTaskScheduler;
|
use crate::services::grid_editor_task::GridServiceTaskScheduler;
|
||||||
|
use crate::services::group::{GroupAction, GroupCellContentProvider, SingleSelectGroupController};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use flowy_error::FlowyResult;
|
use flowy_error::FlowyResult;
|
||||||
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, GroupConfigurationRevision, RowRevision};
|
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, GroupConfigurationRevision, RowRevision};
|
||||||
@ -56,94 +58,42 @@ impl GridGroupService {
|
|||||||
.flatten()
|
.flatten()
|
||||||
.collect::<Vec<Arc<RowRevision>>>();
|
.collect::<Vec<Arc<RowRevision>>>();
|
||||||
|
|
||||||
|
// let a = SingleSelectGroupController::new;
|
||||||
|
// let b = a(field_rev.clone(), configuration, &self.grid_pad);
|
||||||
|
|
||||||
let groups = match field_type {
|
let groups = match field_type {
|
||||||
FieldType::RichText => {
|
FieldType::RichText => {
|
||||||
let generator = GroupGenerator::<TextGroupConfigurationPB>::from_configuration(configuration);
|
// let generator = GroupGenerator::<TextGroupConfigurationPB>::from_configuration(configuration);
|
||||||
}
|
}
|
||||||
FieldType::Number => {
|
FieldType::Number => {
|
||||||
let generator = GroupGenerator::<NumberGroupConfigurationPB>::from_configuration(configuration);
|
// let generator = GroupGenerator::<NumberGroupConfigurationPB>::from_configuration(configuration);
|
||||||
}
|
}
|
||||||
FieldType::DateTime => {
|
FieldType::DateTime => {
|
||||||
let generator = GroupGenerator::<DateGroupConfigurationPB>::from_configuration(configuration);
|
// let generator = GroupGenerator::<DateGroupConfigurationPB>::from_configuration(configuration);
|
||||||
}
|
}
|
||||||
FieldType::SingleSelect => {
|
FieldType::SingleSelect => {
|
||||||
let generator = GroupGenerator::<SelectOptionGroupConfigurationPB>::from_configuration(configuration);
|
let group_controller =
|
||||||
|
SingleSelectGroupController::new(field_rev.clone(), configuration, &self.grid_pad);
|
||||||
}
|
}
|
||||||
FieldType::MultiSelect => {
|
FieldType::MultiSelect => {
|
||||||
let generator = GroupGenerator::<SelectOptionGroupConfigurationPB>::from_configuration(configuration);
|
// let group_generator = MultiSelectGroupControllern(configuration);
|
||||||
}
|
}
|
||||||
FieldType::Checkbox => {
|
FieldType::Checkbox => {
|
||||||
let generator = GroupGenerator::<CheckboxGroupConfigurationPB>::from_configuration(configuration);
|
// let generator = GroupGenerator::<CheckboxGroupConfigurationPB>::from_configuration(configuration);
|
||||||
}
|
}
|
||||||
FieldType::URL => {
|
FieldType::URL => {
|
||||||
let generator = GroupGenerator::<UrlGroupConfigurationPB>::from_configuration(configuration);
|
// let generator = GroupGenerator::<UrlGroupConfigurationPB>::from_configuration(configuration);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct GroupGenerator<T> {
|
|
||||||
field_id: String,
|
|
||||||
groups: Vec<Group>,
|
|
||||||
configuration: Option<T>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Group {
|
|
||||||
row_ids: Vec<String>,
|
|
||||||
content: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> GroupGenerator<T>
|
|
||||||
where
|
|
||||||
T: TryFrom<Bytes, Error = protobuf::ProtobufError>,
|
|
||||||
{
|
|
||||||
pub fn from_configuration(configuration: GroupConfigurationRevision) -> FlowyResult<Self> {
|
|
||||||
let bytes = Bytes::from(configuration.content.unwrap_or(vec![]));
|
|
||||||
Self::from_bytes(&configuration.field_id, bytes)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_bytes(field_id: &str, bytes: Bytes) -> FlowyResult<Self> {
|
|
||||||
let configuration = if bytes.is_empty() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(T::try_from(bytes)?)
|
|
||||||
};
|
|
||||||
Ok(Self {
|
|
||||||
field_id: field_id.to_owned(),
|
|
||||||
groups: vec![],
|
|
||||||
configuration,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub trait GroupConfiguration {
|
|
||||||
fn should_group(&self, content: &str, cell_bytes: CellBytes) -> bool;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> GroupGenerator<T>
|
|
||||||
where
|
|
||||||
T: GroupConfiguration,
|
|
||||||
{
|
|
||||||
pub fn group_row(&mut self, field_rev: &Arc<FieldRevision>, row: &RowRevision) {
|
|
||||||
if self.configuration.is_none() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let configuration = self.configuration.as_ref().unwrap();
|
|
||||||
if let Some(cell_rev) = row.cells.get(&self.field_id) {
|
|
||||||
for group in self.groups.iter_mut() {
|
|
||||||
let cell_rev: CellRevision = cell_rev.clone();
|
|
||||||
let cell_bytes = decode_any_cell_data(cell_rev.data, field_rev);
|
|
||||||
if configuration.should_group(&group.content, cell_bytes) {
|
|
||||||
group.row_ids.push(row.id.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn find_group_field(field_revs: &[Arc<FieldRevision>]) -> Option<&Arc<FieldRevision>> {
|
fn find_group_field(field_revs: &[Arc<FieldRevision>]) -> Option<&Arc<FieldRevision>> {
|
||||||
field_revs.iter().find(|field_rev| {
|
field_revs.iter().find(|field_rev| {
|
||||||
let field_type: FieldType = field_rev.field_type_rev.into();
|
let field_type: FieldType = field_rev.field_type_rev.into();
|
||||||
field_type.can_be_group()
|
field_type.can_be_group()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl GroupCellContentProvider for Arc<RwLock<GridRevisionPad>> {}
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
use crate::entities::CheckboxGroupConfigurationPB;
|
|
||||||
use crate::services::cell::{AnyCellData, CellData, CellGroupOperation};
|
|
||||||
use crate::services::field::{CheckboxCellData, CheckboxTypeOption};
|
|
||||||
use flowy_error::FlowyResult;
|
|
||||||
|
|
||||||
impl CellGroupOperation for CheckboxTypeOption {
|
|
||||||
fn apply_group(&self, any_cell_data: AnyCellData, content: &str) -> FlowyResult<bool> {
|
|
||||||
if !any_cell_data.is_checkbox() {
|
|
||||||
return Ok(true);
|
|
||||||
}
|
|
||||||
let cell_data: CellData<CheckboxCellData> = any_cell_data.into();
|
|
||||||
let checkbox_cell_data = cell_data.try_into_inner()?;
|
|
||||||
|
|
||||||
// Ok(checkbox_cell_data.as_ref() == content)
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
use crate::entities::SelectOptionGroupConfigurationPB;
|
|
||||||
use crate::services::field::SelectedSelectOptions;
|
|
||||||
|
|
||||||
impl SelectOptionGroupConfigurationPB {
|
|
||||||
pub fn is_visible(&self, selected_options: &SelectedSelectOptions) -> bool {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +1,7 @@
|
|||||||
|
mod group_configuration;
|
||||||
|
mod group_generator;
|
||||||
mod group_service;
|
mod group_service;
|
||||||
mod impls;
|
|
||||||
|
|
||||||
|
pub(crate) use group_configuration::*;
|
||||||
|
pub(crate) use group_generator::*;
|
||||||
pub(crate) use group_service::*;
|
pub(crate) use group_service::*;
|
||||||
pub(crate) use impls::*;
|
|
||||||
|
Loading…
Reference in New Issue
Block a user