chore: support switch to multi select field

This commit is contained in:
appflowy
2022-09-01 09:03:33 +08:00
parent 15ff2efcc2
commit 1931cdd4c0
6 changed files with 164 additions and 25 deletions

View File

@ -207,6 +207,10 @@ impl GridRevisionEditor {
Ok(()) Ok(())
} }
pub async fn group_field(&self, field_id: &str) -> FlowyResult<()> {
todo!()
}
pub async fn switch_to_field_type(&self, field_id: &str, field_type: &FieldType) -> FlowyResult<()> { pub async fn switch_to_field_type(&self, field_id: &str, field_type: &FieldType) -> FlowyResult<()> {
// let block_ids = self // let block_ids = self
// .get_block_metas() // .get_block_metas()

View File

@ -6,7 +6,9 @@ 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::{GroupConfigurationReader, GroupConfigurationWriter, GroupService}; use crate::services::group::{
make_group_controller, GroupConfigurationReader, GroupConfigurationWriter, GroupController, GroupService,
};
use flowy_error::{FlowyError, FlowyResult}; use flowy_error::{FlowyError, FlowyResult};
use flowy_grid_data_model::revision::{ use flowy_grid_data_model::revision::{
gen_grid_filter_id, FieldRevision, FieldTypeRevision, FilterConfigurationRevision, GroupConfigurationRevision, gen_grid_filter_id, FieldRevision, FieldTypeRevision, FilterConfigurationRevision, GroupConfigurationRevision,
@ -17,6 +19,7 @@ use flowy_sync::client_grid::{GridViewRevisionChangeset, GridViewRevisionPad};
use flowy_sync::entities::revision::Revision; use flowy_sync::entities::revision::Revision;
use lib_infra::future::{wrap_future, AFFuture, FutureResult}; use lib_infra::future::{wrap_future, AFFuture, FutureResult};
use std::collections::HashMap; use std::collections::HashMap;
use std::future::Future;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc; use std::sync::Arc;
@ -30,9 +33,8 @@ pub struct GridViewRevisionEditor {
rev_manager: Arc<RevisionManager>, rev_manager: Arc<RevisionManager>,
field_delegate: Arc<dyn GridViewFieldDelegate>, field_delegate: Arc<dyn GridViewFieldDelegate>,
row_delegate: Arc<dyn GridViewRowDelegate>, row_delegate: Arc<dyn GridViewRowDelegate>,
group_service: Arc<RwLock<GroupService>>, group_controller: Arc<RwLock<Box<dyn GroupController>>>,
scheduler: Arc<dyn GridServiceTaskScheduler>, scheduler: Arc<dyn GridServiceTaskScheduler>,
did_load_group: AtomicBool,
} }
impl GridViewRevisionEditor { impl GridViewRevisionEditor {
@ -53,15 +55,25 @@ impl GridViewRevisionEditor {
let pad = Arc::new(RwLock::new(view_revision_pad)); let pad = Arc::new(RwLock::new(view_revision_pad));
let rev_manager = Arc::new(rev_manager); let rev_manager = Arc::new(rev_manager);
// Load group
let configuration_reader = GroupConfigurationReaderImpl(pad.clone()); let configuration_reader = GroupConfigurationReaderImpl(pad.clone());
let configuration_writer = GroupConfigurationWriterImpl { let configuration_writer = GroupConfigurationWriterImpl {
user_id: user_id.to_owned(), user_id: user_id.to_owned(),
rev_manager: rev_manager.clone(), rev_manager: rev_manager.clone(),
view_pad: pad.clone(), view_pad: pad.clone(),
}; };
let group_service = GroupService::new(view_id.clone(), configuration_reader, configuration_writer).await; let field_revs = field_delegate.get_field_revs().await;
let row_revs = row_delegate.gv_row_revs().await;
let group_controller = make_group_controller(
view_id.clone(),
field_revs,
row_revs,
configuration_reader,
configuration_writer,
)
.await?;
let user_id = user_id.to_owned(); let user_id = user_id.to_owned();
let did_load_group = AtomicBool::new(false);
Ok(Self { Ok(Self {
pad, pad,
user_id, user_id,
@ -70,8 +82,7 @@ impl GridViewRevisionEditor {
scheduler, scheduler,
field_delegate, field_delegate,
row_delegate, row_delegate,
group_service: Arc::new(RwLock::new(group_service)), group_controller: Arc::new(RwLock::new(group_controller)),
did_load_group,
}) })
} }
@ -112,33 +123,58 @@ impl GridViewRevisionEditor {
pub(crate) async fn did_delete_row(&self, row_rev: &RowRevision) { pub(crate) async fn did_delete_row(&self, row_rev: &RowRevision) {
// Send the group notification if the current view has groups; // Send the group notification if the current view has groups;
if let Some(changesets) = self let group_field_id = self.group_controller.read().await.field_id().to_owned();
.group_service let field_rev = self.field_delegate.get_field_rev(&group_field_id).await;
.write() field_rev.and_then(|field_rev| {
.await if let Some(changesets) = self
.did_delete_row(row_rev, |field_id| self.field_delegate.get_field_rev(&field_id)) .group_controller
.await .write()
{ .await
.did_delete_row(row_rev, &field_rev)
.await
{
for changeset in changesets {
self.notify_did_update_group(changeset).await;
}
}
None
});
}
pub(crate) async fn did_update_row(&self, row_rev: &RowRevision) {
let changeset = self
.mut_group_controller(|group_controller, field_rev| async {
group_controller.did_update_row(row_rev, &field_rev).await
})
.await?;
if let Some(changeset) = changeset {
for changeset in changesets { for changeset in changesets {
self.notify_did_update_group(changeset).await; self.notify_did_update_group(changeset).await;
} }
} }
} }
pub(crate) async fn did_update_row(&self, row_rev: &RowRevision) { async fn mut_group_controller<F, O, T>(&self, f: F) -> Option<T>
if let Some(changesets) = self where
.group_service F: FnOnce(&mut Box<dyn GroupController>, Arc<FieldRevision>) -> O,
.write() O: Future<Output = Option<T>> + Send + Sync + 'static,
.await {
.did_update_row(row_rev, |field_id| self.field_delegate.get_field_rev(&field_id)) let group_field_id = self.group_controller.read().await.field_id().to_owned();
.await match self.field_delegate.get_field_rev(&group_field_id).await {
{ None => None,
for changeset in changesets { Some(field_rev) => {
self.notify_did_update_group(changeset).await; let mut write_guard = self.group_controller.write().await;
Some(f(&mut write_guard, field_rev).await)
} }
} }
} }
async fn get_group_field_rev(&self) -> Option<Arc<FieldRevision>> {
let group_field_id = self.group_controller.read().await.field_id().to_owned();
self.field_delegate.get_field_rev(&group_field_id).await
}
pub(crate) async fn move_group_row( pub(crate) async fn move_group_row(
&self, &self,
row_rev: &RowRevision, row_rev: &RowRevision,

View File

@ -241,6 +241,74 @@ impl GroupService {
} }
} }
#[tracing::instrument(level = "trace", skip_all, err)]
pub async fn make_group_controller<R, W>(
view_id: String,
field_revs: Vec<Arc<FieldRevision>>,
row_revs: Vec<Arc<RowRevision>>,
configuration_reader: R,
configuration_writer: W,
) -> FlowyResult<Box<dyn GroupController>>
where
R: GroupConfigurationReader,
W: GroupConfigurationWriter,
{
let field_rev = find_group_field(&field_revs)?;
let field_type: FieldType = field_rev.ty.into();
let mut group_controller: Box<dyn GroupController>;
match field_type {
FieldType::RichText => {
// let generator = GroupGenerator::<TextGroupConfigurationPB>::from_configuration(configuration);
panic!()
}
FieldType::Number => {
// let generator = GroupGenerator::<NumberGroupConfigurationPB>::from_configuration(configuration);
panic!()
}
FieldType::DateTime => {
// let generator = GroupGenerator::<DateGroupConfigurationPB>::from_configuration(configuration);
panic!()
}
FieldType::SingleSelect => {
let configuration = SelectOptionGroupConfiguration::new(
view_id,
field_rev.clone(),
configuration_reader,
configuration_writer,
)
.await?;
let controller = SingleSelectGroupController::new(&field_rev, configuration).await?;
group_controller = Box::new(controller);
}
FieldType::MultiSelect => {
let configuration = SelectOptionGroupConfiguration::new(
view_id,
field_rev.clone(),
configuration_reader,
configuration_writer,
)
.await?;
let controller = MultiSelectGroupController::new(&field_rev, configuration).await?;
group_controller = Box::new(controller);
}
FieldType::Checkbox => {
let configuration =
CheckboxGroupConfiguration::new(view_id, field_rev.clone(), configuration_reader, configuration_writer)
.await?;
let controller = CheckboxGroupController::new(&field_rev, configuration).await?;
group_controller = Box::new(controller);
}
FieldType::URL => {
// let generator = GroupGenerator::<UrlGroupConfigurationPB>::from_configuration(configuration);
panic!()
}
}
let _ = group_controller.fill_groups(&row_revs, &field_rev)?;
Ok(group_controller)
}
fn find_group_field(field_revs: &[Arc<FieldRevision>]) -> Option<Arc<FieldRevision>> { fn find_group_field(field_revs: &[Arc<FieldRevision>]) -> Option<Arc<FieldRevision>> {
let field_rev = field_revs let field_rev = field_revs
.iter() .iter()

View File

@ -6,6 +6,7 @@ mod entities;
mod group_service; mod group_service;
pub(crate) use configuration::*; pub(crate) use configuration::*;
pub(crate) use controller::*;
pub(crate) use controller_impls::*; pub(crate) use controller_impls::*;
pub(crate) use entities::*; pub(crate) use entities::*;
pub(crate) use group_service::*; pub(crate) use group_service::*;

View File

@ -3,7 +3,8 @@ use flowy_grid::entities::{
CreateRowParams, FieldChangesetParams, FieldType, GridLayout, GroupPB, MoveGroupParams, MoveGroupRowParams, RowPB, CreateRowParams, FieldChangesetParams, FieldType, GridLayout, GroupPB, MoveGroupParams, MoveGroupRowParams, RowPB,
}; };
use flowy_grid::services::cell::{delete_select_option_cell, insert_select_option_cell}; use flowy_grid::services::cell::{delete_select_option_cell, insert_select_option_cell};
use flowy_grid_data_model::revision::RowChangeset; use flowy_grid_data_model::revision::{FieldRevision, RowChangeset};
use std::sync::Arc;
use std::time::Duration; use std::time::Duration;
use tokio::time::interval; use tokio::time::interval;
@ -47,6 +48,9 @@ pub enum GroupScript {
UpdateField { UpdateField {
changeset: FieldChangesetParams, changeset: FieldChangesetParams,
}, },
GroupField {
field_id: String,
},
} }
pub struct GridGroupTest { pub struct GridGroupTest {
@ -179,6 +183,9 @@ impl GridGroupTest {
let mut interval = interval(Duration::from_millis(130)); let mut interval = interval(Duration::from_millis(130));
interval.tick().await; interval.tick().await;
} }
GroupScript::GroupField { field_id } => {
self.editor.group_field(&field_id).await.unwrap();
}
} }
} }
@ -191,6 +198,20 @@ impl GridGroupTest {
let groups = self.group_at_index(group_index).await; let groups = self.group_at_index(group_index).await;
groups.rows.get(row_index).unwrap().clone() groups.rows.get(row_index).unwrap().clone()
} }
pub async fn get_multi_select_field(&self) -> Arc<FieldRevision> {
let field = self
.inner
.field_revs
.iter()
.find(|field_rev| {
let field_type: FieldType = field_rev.ty.into();
field_type.is_multi_select()
})
.unwrap()
.clone();
return field;
}
} }
impl std::ops::Deref for GridGroupTest { impl std::ops::Deref for GridGroupTest {

View File

@ -390,3 +390,12 @@ async fn group_update_field_test() {
]; ];
test.run_scripts(scripts).await; test.run_scripts(scripts).await;
} }
#[tokio::test]
async fn group_multi_select_field_test() {
let mut test = GridGroupTest::new().await;
let multi_select_field = test.get_multi_select_field().await;
let scripts = vec![];
test.run_scripts(scripts).await;
}