mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: fix some bugs
This commit is contained in:
parent
9922645e59
commit
0ecb15cfa3
@ -112,6 +112,12 @@ pub struct InsertedRowPB {
|
|||||||
pub index: Option<i32>,
|
pub index: Option<i32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl InsertedRowPB {
|
||||||
|
pub fn new(row: RowPB) -> Self {
|
||||||
|
Self { row, index: None }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl std::convert::From<RowPB> for InsertedRowPB {
|
impl std::convert::From<RowPB> for InsertedRowPB {
|
||||||
fn from(row: RowPB) -> Self {
|
fn from(row: RowPB) -> Self {
|
||||||
Self { row, index: None }
|
Self { row, index: None }
|
||||||
|
@ -17,6 +17,9 @@ pub struct GroupRowsChangesetPB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl GroupRowsChangesetPB {
|
impl GroupRowsChangesetPB {
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.inserted_rows.is_empty() && self.deleted_rows.is_empty() && self.updated_rows.is_empty()
|
||||||
|
}
|
||||||
pub fn insert(group_id: String, inserted_rows: Vec<InsertedRowPB>) -> Self {
|
pub fn insert(group_id: String, inserted_rows: Vec<InsertedRowPB>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
group_id,
|
group_id,
|
||||||
|
@ -3,7 +3,7 @@ use crate::entities::GridCellIdParams;
|
|||||||
use crate::entities::*;
|
use crate::entities::*;
|
||||||
use crate::manager::{GridTaskSchedulerRwLock, GridUser};
|
use crate::manager::{GridTaskSchedulerRwLock, GridUser};
|
||||||
use crate::services::block_manager::GridBlockManager;
|
use crate::services::block_manager::GridBlockManager;
|
||||||
use crate::services::block_manager_trait_impl::*;
|
|
||||||
use crate::services::cell::{apply_cell_data_changeset, decode_any_cell_data, CellBytes};
|
use crate::services::cell::{apply_cell_data_changeset, decode_any_cell_data, CellBytes};
|
||||||
use crate::services::field::{default_type_option_builder_from_type, type_option_builder_from_bytes, FieldBuilder};
|
use crate::services::field::{default_type_option_builder_from_type, type_option_builder_from_bytes, FieldBuilder};
|
||||||
use crate::services::filter::GridFilterService;
|
use crate::services::filter::GridFilterService;
|
||||||
@ -405,7 +405,7 @@ impl GridRevisionEditor {
|
|||||||
content = Some(apply_cell_data_changeset(content.unwrap(), cell_rev, field_rev)?);
|
content = Some(apply_cell_data_changeset(content.unwrap(), cell_rev, field_rev)?);
|
||||||
let cell_changeset = CellChangesetPB {
|
let cell_changeset = CellChangesetPB {
|
||||||
grid_id,
|
grid_id,
|
||||||
row_id,
|
row_id: row_id.clone(),
|
||||||
field_id,
|
field_id,
|
||||||
content,
|
content,
|
||||||
};
|
};
|
||||||
@ -413,6 +413,8 @@ impl GridRevisionEditor {
|
|||||||
.block_manager
|
.block_manager
|
||||||
.update_cell(cell_changeset, make_row_from_row_rev)
|
.update_cell(cell_changeset, make_row_from_row_rev)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
self.view_manager.did_update_row(&row_id).await;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ use crate::entities::{
|
|||||||
};
|
};
|
||||||
use crate::services::grid_editor_task::GridServiceTaskScheduler;
|
use crate::services::grid_editor_task::GridServiceTaskScheduler;
|
||||||
use crate::services::grid_view_manager::{GridViewFieldDelegate, GridViewRowDelegate};
|
use crate::services::grid_view_manager::{GridViewFieldDelegate, GridViewRowDelegate};
|
||||||
use crate::services::group::{default_group_configuration, Group, GroupConfigurationDelegate, GroupService};
|
use crate::services::group::{default_group_configuration, GroupConfigurationDelegate, GroupService};
|
||||||
use crate::services::setting::make_grid_setting;
|
use crate::services::setting::make_grid_setting;
|
||||||
use flowy_error::{FlowyError, FlowyResult};
|
use flowy_error::{FlowyError, FlowyResult};
|
||||||
use flowy_grid_data_model::revision::{FieldRevision, GroupConfigurationRevision, RowRevision};
|
use flowy_grid_data_model::revision::{FieldRevision, GroupConfigurationRevision, RowRevision};
|
||||||
@ -105,11 +105,16 @@ impl GridViewRevisionEditor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn did_update_row(&self, row_rev: Arc<RowRevision>) {
|
pub(crate) async fn did_update_row(&self, row_rev: &RowRevision) {
|
||||||
match self.group_id_of_row(&row_rev.id).await {
|
if let Some(changesets) = self
|
||||||
None => {}
|
.group_service
|
||||||
Some(group_id) => {
|
.write()
|
||||||
// self.get_mut_group(&group_id, |group| Ok(()));
|
.await
|
||||||
|
.did_update_row(row_rev, |field_id| self.field_delegate.get_field_rev(&field_id))
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
for changeset in changesets {
|
||||||
|
self.notify_did_update_group(changeset).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -117,7 +122,7 @@ impl GridViewRevisionEditor {
|
|||||||
async fn group_id_of_row(&self, row_id: &str) -> Option<String> {
|
async fn group_id_of_row(&self, row_id: &str) -> Option<String> {
|
||||||
let read_guard = &self.group_service.read().await.groups;
|
let read_guard = &self.group_service.read().await.groups;
|
||||||
for group in read_guard.iter() {
|
for group in read_guard.iter() {
|
||||||
if group.rows.iter().any(|row| row.id == row_id) {
|
if group.contains_row(row_id) {
|
||||||
return Some(group.id.clone());
|
return Some(group.id.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ use crate::entities::{
|
|||||||
CreateRowParams, GridFilterConfiguration, GridLayout, GridSettingPB, MoveRowParams, RepeatedGridGroupPB, RowPB,
|
CreateRowParams, GridFilterConfiguration, GridLayout, GridSettingPB, MoveRowParams, RepeatedGridGroupPB, RowPB,
|
||||||
};
|
};
|
||||||
use crate::manager::GridUser;
|
use crate::manager::GridUser;
|
||||||
use crate::services::block_manager::GridBlockManager;
|
|
||||||
use crate::services::grid_editor_task::GridServiceTaskScheduler;
|
use crate::services::grid_editor_task::GridServiceTaskScheduler;
|
||||||
use crate::services::grid_view_editor::GridViewRevisionEditor;
|
use crate::services::grid_view_editor::GridViewRevisionEditor;
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
@ -11,13 +11,12 @@ use flowy_error::FlowyResult;
|
|||||||
use flowy_grid_data_model::revision::{FieldRevision, RowRevision};
|
use flowy_grid_data_model::revision::{FieldRevision, RowRevision};
|
||||||
use flowy_revision::disk::SQLiteGridViewRevisionPersistence;
|
use flowy_revision::disk::SQLiteGridViewRevisionPersistence;
|
||||||
use flowy_revision::{RevisionCompactor, RevisionManager, RevisionPersistence, SQLiteRevisionSnapshotPersistence};
|
use flowy_revision::{RevisionCompactor, RevisionManager, RevisionPersistence, SQLiteRevisionSnapshotPersistence};
|
||||||
use flowy_sync::client_grid::GridRevisionPad;
|
|
||||||
use flowy_sync::entities::grid::GridSettingChangesetParams;
|
use flowy_sync::entities::grid::GridSettingChangesetParams;
|
||||||
use flowy_sync::entities::revision::Revision;
|
use flowy_sync::entities::revision::Revision;
|
||||||
use flowy_sync::util::make_text_delta_from_revisions;
|
use flowy_sync::util::make_text_delta_from_revisions;
|
||||||
use lib_infra::future::{wrap_future, AFFuture};
|
use lib_infra::future::AFFuture;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tokio::sync::RwLock;
|
|
||||||
|
|
||||||
type ViewId = String;
|
type ViewId = String;
|
||||||
|
|
||||||
@ -74,7 +73,16 @@ impl GridViewManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn did_update_row(&self, row_id: &str) {
|
pub(crate) async fn did_update_row(&self, row_id: &str) {
|
||||||
let row = self.row_delegate.gv_get_row_rev(row_id).await;
|
match self.row_delegate.gv_get_row_rev(row_id).await {
|
||||||
|
None => {
|
||||||
|
tracing::warn!("Can not find the row in grid view");
|
||||||
|
}
|
||||||
|
Some(row_rev) => {
|
||||||
|
for view_editor in self.view_editors.iter() {
|
||||||
|
view_editor.did_update_row(&row_rev).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn did_create_row(&self, row_pb: &RowPB, params: &CreateRowParams) {
|
pub(crate) async fn did_create_row(&self, row_pb: &RowPB, params: &CreateRowParams) {
|
||||||
|
@ -1,13 +1,16 @@
|
|||||||
use crate::entities::CheckboxGroupConfigurationPB;
|
use crate::entities::{CheckboxGroupConfigurationPB, GroupRowsChangesetPB};
|
||||||
use flowy_error::FlowyResult;
|
|
||||||
use flowy_grid_data_model::revision::{FieldRevision, RowRevision};
|
use flowy_grid_data_model::revision::{FieldRevision, RowRevision};
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use crate::services::field::{CheckboxCellData, CheckboxCellDataParser, CheckboxTypeOptionPB, CHECK, UNCHECK};
|
use crate::services::field::{CheckboxCellData, CheckboxCellDataParser, CheckboxTypeOptionPB, CHECK, UNCHECK};
|
||||||
use crate::services::group::{Group, GroupActionHandler, GroupController, GroupGenerator, Groupable};
|
use crate::services::group::{GenericGroupController, Group, GroupController, GroupGenerator, Groupable};
|
||||||
|
|
||||||
pub type CheckboxGroupController =
|
pub type CheckboxGroupController = GenericGroupController<
|
||||||
GroupController<CheckboxGroupConfigurationPB, CheckboxTypeOptionPB, CheckboxGroupGenerator, CheckboxCellDataParser>;
|
CheckboxGroupConfigurationPB,
|
||||||
|
CheckboxTypeOptionPB,
|
||||||
|
CheckboxGroupGenerator,
|
||||||
|
CheckboxCellDataParser,
|
||||||
|
>;
|
||||||
|
|
||||||
impl Groupable for CheckboxGroupController {
|
impl Groupable for CheckboxGroupController {
|
||||||
type CellDataType = CheckboxCellData;
|
type CellDataType = CheckboxCellData;
|
||||||
@ -15,21 +18,13 @@ impl Groupable for CheckboxGroupController {
|
|||||||
fn can_group(&self, _content: &str, _cell_data: &Self::CellDataType) -> bool {
|
fn can_group(&self, _content: &str, _cell_data: &Self::CellDataType) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn group_row(&mut self, _row_rev: &RowRevision, _cell_data: &Self::CellDataType) -> Vec<GroupRowsChangesetPB> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GroupActionHandler for CheckboxGroupController {
|
impl GroupController for CheckboxGroupController {
|
||||||
fn field_id(&self) -> &str {
|
|
||||||
&self.field_id
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_groups(&self) -> Vec<Group> {
|
|
||||||
self.make_groups()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn group_rows(&mut self, row_revs: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<()> {
|
|
||||||
self.handle_rows(row_revs, field_rev)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fill_row(&self, _row_rev: &mut RowRevision, _field_rev: &FieldRevision, _group_id: &str) {
|
fn fill_row(&self, _row_rev: &mut RowRevision, _field_rev: &FieldRevision, _group_id: &str) {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
@ -44,20 +39,8 @@ impl GroupGenerator for CheckboxGroupGenerator {
|
|||||||
_configuration: &Option<Self::ConfigurationType>,
|
_configuration: &Option<Self::ConfigurationType>,
|
||||||
_type_option: &Option<Self::TypeOptionType>,
|
_type_option: &Option<Self::TypeOptionType>,
|
||||||
) -> Vec<Group> {
|
) -> Vec<Group> {
|
||||||
let check_group = Group {
|
let check_group = Group::new("true".to_string(), "".to_string(), CHECK.to_string());
|
||||||
id: "true".to_string(),
|
let uncheck_group = Group::new("false".to_string(), "".to_string(), UNCHECK.to_string());
|
||||||
desc: "".to_string(),
|
|
||||||
rows: vec![],
|
|
||||||
content: CHECK.to_string(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let uncheck_group = Group {
|
|
||||||
id: "false".to_string(),
|
|
||||||
desc: "".to_string(),
|
|
||||||
rows: vec![],
|
|
||||||
content: UNCHECK.to_string(),
|
|
||||||
};
|
|
||||||
|
|
||||||
vec![check_group, uncheck_group]
|
vec![check_group, uncheck_group]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
use crate::entities::{GroupPB, RowPB};
|
use crate::entities::{GroupPB, GroupRowsChangesetPB, RowPB};
|
||||||
use crate::services::cell::{decode_any_cell_data, CellBytesParser};
|
use crate::services::cell::{decode_any_cell_data, CellBytesParser};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use flowy_error::FlowyResult;
|
use flowy_error::FlowyResult;
|
||||||
use flowy_grid_data_model::revision::{
|
use flowy_grid_data_model::revision::{
|
||||||
FieldRevision, GroupConfigurationRevision, RowRevision, TypeOptionDataDeserializer,
|
FieldRevision, GroupConfigurationRevision, RowRevision, TypeOptionDataDeserializer,
|
||||||
};
|
};
|
||||||
|
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
@ -21,30 +19,35 @@ pub trait GroupGenerator {
|
|||||||
) -> Vec<Group>;
|
) -> Vec<Group>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Groupable {
|
pub trait Groupable: Send + Sync {
|
||||||
type CellDataType;
|
type CellDataType;
|
||||||
fn can_group(&self, content: &str, cell_data: &Self::CellDataType) -> bool;
|
fn can_group(&self, content: &str, cell_data: &Self::CellDataType) -> bool;
|
||||||
|
fn group_row(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType) -> Vec<GroupRowsChangesetPB>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait GroupActionHandler: Send + Sync {
|
pub trait GroupController: GroupControllerSharedAction + Send + Sync {
|
||||||
|
fn fill_row(&self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait GroupControllerSharedAction: 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 build_groups(&self) -> Vec<Group>;
|
fn build_groups(&self) -> Vec<Group>;
|
||||||
fn group_rows(&mut self, row_revs: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<()>;
|
fn group_rows(&mut self, row_revs: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<()>;
|
||||||
fn fill_row(&self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str);
|
fn did_update_row(
|
||||||
}
|
&mut self,
|
||||||
|
row_rev: &RowRevision,
|
||||||
pub trait GroupActionHandler2: Send + Sync {
|
field_rev: &FieldRevision,
|
||||||
fn create_card(&self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str);
|
) -> FlowyResult<Vec<GroupRowsChangesetPB>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DEFAULT_GROUP_ID: &str = "default_group";
|
const DEFAULT_GROUP_ID: &str = "default_group";
|
||||||
|
|
||||||
/// C: represents the group configuration structure
|
/// C: represents the group configuration structure
|
||||||
/// T: the type option data deserializer that impl [TypeOptionDataDeserializer]
|
/// T: the type option data deserializer that impl [TypeOptionDataDeserializer]
|
||||||
/// G: the group container generator
|
/// G: the group generator, [GroupGenerator]
|
||||||
/// P: the parser that impl [CellBytesParser] for the CellBytes
|
/// P: the parser that impl [CellBytesParser] for the CellBytes
|
||||||
pub struct GroupController<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: Group,
|
default_group: Group,
|
||||||
@ -58,7 +61,7 @@ pub struct GroupController<C, T, G, P> {
|
|||||||
pub struct Group {
|
pub struct Group {
|
||||||
pub id: String,
|
pub id: String,
|
||||||
pub desc: String,
|
pub desc: String,
|
||||||
pub rows: Vec<RowPB>,
|
rows: Vec<RowPB>,
|
||||||
pub content: String,
|
pub content: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +75,40 @@ impl std::convert::From<Group> for GroupPB {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, T, G, P> GroupController<C, T, G, P>
|
impl Group {
|
||||||
|
pub fn new(id: String, desc: String, content: String) -> Self {
|
||||||
|
Self {
|
||||||
|
id,
|
||||||
|
desc,
|
||||||
|
rows: vec![],
|
||||||
|
content,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn contains_row(&self, row_id: &str) -> bool {
|
||||||
|
self.rows.iter().any(|row| row.id == row_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove_row(&mut self, row_id: &str) {
|
||||||
|
match self.rows.iter().position(|row| row.id == row_id) {
|
||||||
|
None => {}
|
||||||
|
Some(pos) => {
|
||||||
|
self.rows.remove(pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_row(&mut self, row_pb: RowPB) {
|
||||||
|
match self.rows.iter().find(|row| row.id == row_pb.id) {
|
||||||
|
None => {
|
||||||
|
self.rows.push(row_pb);
|
||||||
|
}
|
||||||
|
Some(_) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C, T, G, P> GenericGroupController<C, T, G, P>
|
||||||
where
|
where
|
||||||
C: TryFrom<Bytes, Error = protobuf::ProtobufError>,
|
C: TryFrom<Bytes, Error = protobuf::ProtobufError>,
|
||||||
T: TypeOptionDataDeserializer,
|
T: TypeOptionDataDeserializer,
|
||||||
@ -87,12 +123,11 @@ where
|
|||||||
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(&configuration, &type_option);
|
let groups = G::generate_groups(&configuration, &type_option);
|
||||||
|
|
||||||
let default_group = Group {
|
let default_group = Group::new(
|
||||||
id: DEFAULT_GROUP_ID.to_owned(),
|
DEFAULT_GROUP_ID.to_owned(),
|
||||||
desc: format!("No {}", field_rev.name),
|
format!("No {}", field_rev.name),
|
||||||
rows: vec![],
|
"".to_string(),
|
||||||
content: "".to_string(),
|
);
|
||||||
};
|
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
field_id: field_rev.id.clone(),
|
field_id: field_rev.id.clone(),
|
||||||
@ -104,8 +139,18 @@ where
|
|||||||
cell_parser_phantom: PhantomData,
|
cell_parser_phantom: PhantomData,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn make_groups(&self) -> Vec<Group> {
|
impl<C, T, G, P> GroupControllerSharedAction for GenericGroupController<C, T, G, P>
|
||||||
|
where
|
||||||
|
P: CellBytesParser,
|
||||||
|
Self: Groupable<CellDataType = P::Object>,
|
||||||
|
{
|
||||||
|
fn field_id(&self) -> &str {
|
||||||
|
&self.field_id
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_groups(&self) -> Vec<Group> {
|
||||||
let default_group = self.default_group.clone();
|
let default_group = self.default_group.clone();
|
||||||
let mut groups: Vec<Group> = self.groups_map.values().cloned().collect();
|
let mut groups: Vec<Group> = self.groups_map.values().cloned().collect();
|
||||||
if !default_group.rows.is_empty() {
|
if !default_group.rows.is_empty() {
|
||||||
@ -113,35 +158,28 @@ where
|
|||||||
}
|
}
|
||||||
groups
|
groups
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<C, T, G, P> GroupController<C, T, G, P>
|
fn group_rows(&mut self, row_revs: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<()> {
|
||||||
where
|
|
||||||
P: CellBytesParser,
|
|
||||||
Self: Groupable<CellDataType = P::Object>,
|
|
||||||
{
|
|
||||||
pub fn handle_rows(&mut self, rows: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<()> {
|
|
||||||
// The field_rev might be None if corresponding field_rev is deleted.
|
|
||||||
if self.configuration.is_none() {
|
if self.configuration.is_none() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
for row in rows {
|
for row_rev in row_revs {
|
||||||
if let Some(cell_rev) = row.cells.get(&self.field_id) {
|
if let Some(cell_rev) = row_rev.cells.get(&self.field_id) {
|
||||||
let mut records: Vec<GroupRecord> = vec![];
|
let mut records: Vec<GroupRecord> = vec![];
|
||||||
let cell_bytes = decode_any_cell_data(cell_rev.data.clone(), field_rev);
|
let cell_bytes = decode_any_cell_data(cell_rev.data.clone(), field_rev);
|
||||||
let cell_data = cell_bytes.parser::<P>()?;
|
let cell_data = cell_bytes.parser::<P>()?;
|
||||||
for group in self.groups_map.values() {
|
for group in self.groups_map.values() {
|
||||||
if self.can_group(&group.content, &cell_data) {
|
if self.can_group(&group.content, &cell_data) {
|
||||||
records.push(GroupRecord {
|
records.push(GroupRecord {
|
||||||
row: row.into(),
|
row: row_rev.into(),
|
||||||
group_id: group.id.clone(),
|
group_id: group.id.clone(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if records.is_empty() {
|
if records.is_empty() {
|
||||||
self.default_group.rows.push(row.into());
|
self.default_group.rows.push(row_rev.into());
|
||||||
} else {
|
} else {
|
||||||
for record in records {
|
for record in records {
|
||||||
if let Some(group) = self.groups_map.get_mut(&record.group_id) {
|
if let Some(group) = self.groups_map.get_mut(&record.group_id) {
|
||||||
@ -150,14 +188,71 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.default_group.rows.push(row.into());
|
self.default_group.rows.push(row_rev.into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn did_update_row(
|
||||||
|
&mut self,
|
||||||
|
row_rev: &RowRevision,
|
||||||
|
field_rev: &FieldRevision,
|
||||||
|
) -> FlowyResult<Vec<GroupRowsChangesetPB>> {
|
||||||
|
if let Some(cell_rev) = row_rev.cells.get(&self.field_id) {
|
||||||
|
let cell_bytes = decode_any_cell_data(cell_rev.data.clone(), field_rev);
|
||||||
|
let cell_data = cell_bytes.parser::<P>()?;
|
||||||
|
Ok(self.group_row(row_rev, &cell_data))
|
||||||
|
} else {
|
||||||
|
Ok(vec![])
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// impl<C, T, G, P> GroupController<C, T, G, P>
|
||||||
|
// where
|
||||||
|
// P: CellBytesParser,
|
||||||
|
// Self: Groupable<CellDataType = P::Object>,
|
||||||
|
// {
|
||||||
|
// pub fn handle_rows(&mut self, rows: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<()> {
|
||||||
|
// // The field_rev might be None if corresponding field_rev is deleted.
|
||||||
|
// if self.configuration.is_none() {
|
||||||
|
// return Ok(());
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// for row in rows {
|
||||||
|
// if let Some(cell_rev) = row.cells.get(&self.field_id) {
|
||||||
|
// let mut records: Vec<GroupRecord> = vec![];
|
||||||
|
// let cell_bytes = decode_any_cell_data(cell_rev.data.clone(), field_rev);
|
||||||
|
// let cell_data = cell_bytes.parser::<P>()?;
|
||||||
|
// for group in self.groups_map.values() {
|
||||||
|
// if self.can_group(&group.content, &cell_data) {
|
||||||
|
// records.push(GroupRecord {
|
||||||
|
// row: row.into(),
|
||||||
|
// group_id: group.id.clone(),
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if records.is_empty() {
|
||||||
|
// self.default_group.rows.push(row.into());
|
||||||
|
// } else {
|
||||||
|
// for record in records {
|
||||||
|
// if let Some(group) = self.groups_map.get_mut(&record.group_id) {
|
||||||
|
// group.rows.push(record.row);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// self.default_group.rows.push(row.into());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Ok(())
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
struct GroupRecord {
|
struct GroupRecord {
|
||||||
row: RowPB,
|
row: RowPB,
|
||||||
group_id: String,
|
group_id: String,
|
||||||
|
@ -1,17 +1,14 @@
|
|||||||
use crate::entities::SelectOptionGroupConfigurationPB;
|
use crate::entities::{GroupRowsChangesetPB, InsertedRowPB, RowPB, SelectOptionGroupConfigurationPB};
|
||||||
use crate::services::cell::insert_select_option_cell;
|
use crate::services::cell::insert_select_option_cell;
|
||||||
use flowy_error::FlowyResult;
|
|
||||||
use flowy_grid_data_model::revision::{FieldRevision, RowRevision};
|
|
||||||
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use crate::services::field::{
|
use crate::services::field::{
|
||||||
MultiSelectTypeOptionPB, SelectOptionCellDataPB, SelectOptionCellDataParser, SingleSelectTypeOptionPB,
|
MultiSelectTypeOptionPB, SelectOptionCellDataPB, SelectOptionCellDataParser, SingleSelectTypeOptionPB,
|
||||||
};
|
};
|
||||||
use crate::services::group::{Group, GroupActionHandler, GroupController, GroupGenerator, Groupable};
|
use crate::services::group::{GenericGroupController, Group, GroupController, GroupGenerator, Groupable};
|
||||||
|
|
||||||
|
use flowy_grid_data_model::revision::{FieldRevision, RowRevision};
|
||||||
|
|
||||||
// SingleSelect
|
// SingleSelect
|
||||||
pub type SingleSelectGroupController = GroupController<
|
pub type SingleSelectGroupController = GenericGroupController<
|
||||||
SelectOptionGroupConfigurationPB,
|
SelectOptionGroupConfigurationPB,
|
||||||
SingleSelectTypeOptionPB,
|
SingleSelectTypeOptionPB,
|
||||||
SingleSelectGroupGenerator,
|
SingleSelectGroupGenerator,
|
||||||
@ -23,21 +20,17 @@ impl Groupable for SingleSelectGroupController {
|
|||||||
fn can_group(&self, content: &str, cell_data: &SelectOptionCellDataPB) -> bool {
|
fn can_group(&self, content: &str, cell_data: &SelectOptionCellDataPB) -> bool {
|
||||||
cell_data.select_options.iter().any(|option| option.id == content)
|
cell_data.select_options.iter().any(|option| option.id == content)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn group_row(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType) -> Vec<GroupRowsChangesetPB> {
|
||||||
|
let mut changesets = vec![];
|
||||||
|
self.groups_map.iter_mut().for_each(|(_, group): (_, &mut Group)| {
|
||||||
|
group_select_option_row(group, &mut changesets, cell_data, row_rev);
|
||||||
|
});
|
||||||
|
changesets
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GroupActionHandler for SingleSelectGroupController {
|
impl GroupController for SingleSelectGroupController {
|
||||||
fn field_id(&self) -> &str {
|
|
||||||
&self.field_id
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_groups(&self) -> Vec<Group> {
|
|
||||||
self.make_groups()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn group_rows(&mut self, row_revs: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<()> {
|
|
||||||
self.handle_rows(row_revs, field_rev)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fill_row(&self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str) {
|
fn fill_row(&self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str) {
|
||||||
let group: Option<&Group> = self.groups_map.get(group_id);
|
let group: Option<&Group> = self.groups_map.get(group_id);
|
||||||
match group {
|
match group {
|
||||||
@ -63,19 +56,14 @@ impl GroupGenerator for SingleSelectGroupGenerator {
|
|||||||
Some(type_option) => type_option
|
Some(type_option) => type_option
|
||||||
.options
|
.options
|
||||||
.iter()
|
.iter()
|
||||||
.map(|option| Group {
|
.map(|option| Group::new(option.id.clone(), option.name.clone(), option.id.clone()))
|
||||||
id: option.id.clone(),
|
|
||||||
desc: option.name.clone(),
|
|
||||||
rows: vec![],
|
|
||||||
content: option.id.clone(),
|
|
||||||
})
|
|
||||||
.collect(),
|
.collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MultiSelect
|
// MultiSelect
|
||||||
pub type MultiSelectGroupController = GroupController<
|
pub type MultiSelectGroupController = GenericGroupController<
|
||||||
SelectOptionGroupConfigurationPB,
|
SelectOptionGroupConfigurationPB,
|
||||||
MultiSelectTypeOptionPB,
|
MultiSelectTypeOptionPB,
|
||||||
MultiSelectGroupGenerator,
|
MultiSelectGroupGenerator,
|
||||||
@ -84,24 +72,22 @@ pub type MultiSelectGroupController = GroupController<
|
|||||||
|
|
||||||
impl Groupable for MultiSelectGroupController {
|
impl Groupable for MultiSelectGroupController {
|
||||||
type CellDataType = SelectOptionCellDataPB;
|
type CellDataType = SelectOptionCellDataPB;
|
||||||
|
|
||||||
fn can_group(&self, content: &str, cell_data: &SelectOptionCellDataPB) -> bool {
|
fn can_group(&self, content: &str, cell_data: &SelectOptionCellDataPB) -> bool {
|
||||||
cell_data.select_options.iter().any(|option| option.id == content)
|
cell_data.select_options.iter().any(|option| option.id == content)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn group_row(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType) -> Vec<GroupRowsChangesetPB> {
|
||||||
|
let mut changesets = vec![];
|
||||||
|
|
||||||
|
self.groups_map.iter_mut().for_each(|(_, group): (_, &mut Group)| {
|
||||||
|
group_select_option_row(group, &mut changesets, cell_data, row_rev);
|
||||||
|
});
|
||||||
|
changesets
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GroupActionHandler for MultiSelectGroupController {
|
impl GroupController for MultiSelectGroupController {
|
||||||
fn field_id(&self) -> &str {
|
|
||||||
&self.field_id
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_groups(&self) -> Vec<Group> {
|
|
||||||
self.make_groups()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn group_rows(&mut self, row_revs: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<()> {
|
|
||||||
self.handle_rows(row_revs, field_rev)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fill_row(&self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str) {
|
fn fill_row(&self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str) {
|
||||||
let group: Option<&Group> = self.groups_map.get(group_id);
|
let group: Option<&Group> = self.groups_map.get(group_id);
|
||||||
match group {
|
match group {
|
||||||
@ -128,13 +114,31 @@ impl GroupGenerator for MultiSelectGroupGenerator {
|
|||||||
Some(type_option) => type_option
|
Some(type_option) => type_option
|
||||||
.options
|
.options
|
||||||
.iter()
|
.iter()
|
||||||
.map(|option| Group {
|
.map(|option| Group::new(option.id.clone(), option.name.clone(), option.id.clone()))
|
||||||
id: option.id.clone(),
|
|
||||||
desc: option.name.clone(),
|
|
||||||
rows: vec![],
|
|
||||||
content: option.id.clone(),
|
|
||||||
})
|
|
||||||
.collect(),
|
.collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn group_select_option_row(
|
||||||
|
group: &mut Group,
|
||||||
|
changesets: &mut Vec<GroupRowsChangesetPB>,
|
||||||
|
cell_data: &SelectOptionCellDataPB,
|
||||||
|
row_rev: &RowRevision,
|
||||||
|
) {
|
||||||
|
cell_data.select_options.iter().for_each(|option| {
|
||||||
|
if option.id == group.id {
|
||||||
|
if !group.contains_row(&row_rev.id) {
|
||||||
|
let row_pb = RowPB::from(row_rev);
|
||||||
|
changesets.push(GroupRowsChangesetPB::insert(
|
||||||
|
group.id.clone(),
|
||||||
|
vec![InsertedRowPB::new(row_pb.clone())],
|
||||||
|
));
|
||||||
|
group.add_row(row_pb);
|
||||||
|
}
|
||||||
|
} else if group.contains_row(&row_rev.id) {
|
||||||
|
group.remove_row(&row_rev.id);
|
||||||
|
changesets.push(GroupRowsChangesetPB::delete(group.id.clone(), vec![row_rev.id.clone()]));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
use crate::entities::{
|
use crate::entities::{
|
||||||
CheckboxGroupConfigurationPB, DateGroupConfigurationPB, FieldType, NumberGroupConfigurationPB,
|
CheckboxGroupConfigurationPB, DateGroupConfigurationPB, FieldType, GroupRowsChangesetPB,
|
||||||
SelectOptionGroupConfigurationPB, TextGroupConfigurationPB, UrlGroupConfigurationPB,
|
NumberGroupConfigurationPB, SelectOptionGroupConfigurationPB, TextGroupConfigurationPB, UrlGroupConfigurationPB,
|
||||||
};
|
};
|
||||||
use crate::services::group::{
|
use crate::services::group::{
|
||||||
CheckboxGroupController, Group, GroupActionHandler, MultiSelectGroupController, SingleSelectGroupController,
|
CheckboxGroupController, Group, GroupController, MultiSelectGroupController, SingleSelectGroupController,
|
||||||
};
|
};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use flowy_error::FlowyResult;
|
use flowy_error::FlowyResult;
|
||||||
@ -20,7 +20,7 @@ pub trait GroupConfigurationDelegate: Send + Sync + 'static {
|
|||||||
pub(crate) struct GroupService {
|
pub(crate) struct GroupService {
|
||||||
pub groups: Vec<Group>,
|
pub groups: Vec<Group>,
|
||||||
delegate: Box<dyn GroupConfigurationDelegate>,
|
delegate: Box<dyn GroupConfigurationDelegate>,
|
||||||
group_action: Option<Arc<RwLock<dyn GroupActionHandler>>>,
|
group_controller: Option<Arc<RwLock<dyn GroupController>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GroupService {
|
impl GroupService {
|
||||||
@ -28,7 +28,7 @@ impl GroupService {
|
|||||||
Self {
|
Self {
|
||||||
groups: vec![],
|
groups: vec![],
|
||||||
delegate,
|
delegate,
|
||||||
group_action: None,
|
group_controller: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,24 +52,43 @@ impl GroupService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn fill_row<F, O>(&self, row_rev: &mut RowRevision, group_id: &str, f: F)
|
pub(crate) async fn fill_row<F, O>(&self, row_rev: &mut RowRevision, group_id: &str, get_field_fn: F)
|
||||||
where
|
where
|
||||||
F: FnOnce(String) -> O,
|
F: FnOnce(String) -> O,
|
||||||
O: Future<Output = Option<Arc<FieldRevision>>> + Send + Sync + 'static,
|
O: Future<Output = Option<Arc<FieldRevision>>> + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
if let Some(group_action) = self.group_action.as_ref() {
|
if let Some(group_controller) = self.group_controller.as_ref() {
|
||||||
let field_id = group_action.read().await.field_id().to_owned();
|
let field_id = group_controller.read().await.field_id().to_owned();
|
||||||
match f(field_id).await {
|
match get_field_fn(field_id).await {
|
||||||
None => {}
|
None => {}
|
||||||
Some(field_rev) => {
|
Some(field_rev) => {
|
||||||
group_action.write().await.fill_row(row_rev, &field_rev, group_id);
|
group_controller.write().await.fill_row(row_rev, &field_rev, group_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn did_update_row(&self, row_rev: Arc<RowRevision>) {
|
#[tracing::instrument(level = "trace", skip_all)]
|
||||||
if let Some(group_action) = self.group_action.as_ref() {}
|
pub(crate) async fn did_update_row<F, O>(
|
||||||
|
&self,
|
||||||
|
row_rev: &RowRevision,
|
||||||
|
get_field_fn: F,
|
||||||
|
) -> Option<Vec<GroupRowsChangesetPB>>
|
||||||
|
where
|
||||||
|
F: FnOnce(String) -> O,
|
||||||
|
O: Future<Output = Option<Arc<FieldRevision>>> + Send + Sync + 'static,
|
||||||
|
{
|
||||||
|
let group_controller = self.group_controller.as_ref()?;
|
||||||
|
let field_id = group_controller.read().await.field_id().to_owned();
|
||||||
|
let field_rev = get_field_fn(field_id).await?;
|
||||||
|
|
||||||
|
match group_controller.write().await.did_update_row(row_rev, &field_rev) {
|
||||||
|
Ok(changeset) => Some(changeset),
|
||||||
|
Err(e) => {
|
||||||
|
tracing::error!("Update group data failed, {:?}", e);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "trace", skip_all, err)]
|
#[tracing::instrument(level = "trace", skip_all, err)]
|
||||||
@ -92,15 +111,15 @@ impl GroupService {
|
|||||||
}
|
}
|
||||||
FieldType::SingleSelect => {
|
FieldType::SingleSelect => {
|
||||||
let controller = SingleSelectGroupController::new(field_rev, configuration)?;
|
let controller = SingleSelectGroupController::new(field_rev, configuration)?;
|
||||||
self.group_action = Some(Arc::new(RwLock::new(controller)));
|
self.group_controller = Some(Arc::new(RwLock::new(controller)));
|
||||||
}
|
}
|
||||||
FieldType::MultiSelect => {
|
FieldType::MultiSelect => {
|
||||||
let controller = MultiSelectGroupController::new(field_rev, configuration)?;
|
let controller = MultiSelectGroupController::new(field_rev, configuration)?;
|
||||||
self.group_action = Some(Arc::new(RwLock::new(controller)));
|
self.group_controller = Some(Arc::new(RwLock::new(controller)));
|
||||||
}
|
}
|
||||||
FieldType::Checkbox => {
|
FieldType::Checkbox => {
|
||||||
let controller = CheckboxGroupController::new(field_rev, configuration)?;
|
let controller = CheckboxGroupController::new(field_rev, configuration)?;
|
||||||
self.group_action = Some(Arc::new(RwLock::new(controller)));
|
self.group_controller = Some(Arc::new(RwLock::new(controller)));
|
||||||
}
|
}
|
||||||
FieldType::URL => {
|
FieldType::URL => {
|
||||||
// let generator = GroupGenerator::<UrlGroupConfigurationPB>::from_configuration(configuration);
|
// let generator = GroupGenerator::<UrlGroupConfigurationPB>::from_configuration(configuration);
|
||||||
@ -108,7 +127,7 @@ impl GroupService {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let mut groups = vec![];
|
let mut groups = vec![];
|
||||||
if let Some(group_action_handler) = self.group_action.as_ref() {
|
if let Some(group_action_handler) = self.group_controller.as_ref() {
|
||||||
let mut write_guard = group_action_handler.write().await;
|
let mut write_guard = group_action_handler.write().await;
|
||||||
let _ = write_guard.group_rows(&row_revs, field_rev)?;
|
let _ = write_guard.group_rows(&row_revs, field_rev)?;
|
||||||
groups = write_guard.build_groups();
|
groups = write_guard.build_groups();
|
||||||
|
@ -75,7 +75,7 @@ fn crate_log_filter(level: String) -> String {
|
|||||||
filters.push(format!("lib_ws={}", level));
|
filters.push(format!("lib_ws={}", level));
|
||||||
filters.push(format!("lib_infra={}", level));
|
filters.push(format!("lib_infra={}", level));
|
||||||
filters.push(format!("flowy_sync={}", level));
|
filters.push(format!("flowy_sync={}", level));
|
||||||
filters.push(format!("flowy_revision={}", level));
|
// filters.push(format!("flowy_revision={}", level));
|
||||||
// filters.push(format!("lib_dispatch={}", level));
|
// filters.push(format!("lib_dispatch={}", level));
|
||||||
|
|
||||||
filters.push(format!("dart_ffi={}", "info"));
|
filters.push(format!("dart_ffi={}", "info"));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user