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(())
}
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<()> {
// let block_ids = self
// .get_block_metas()

View File

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

View File

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

View File

@ -3,7 +3,8 @@ use flowy_grid::entities::{
CreateRowParams, FieldChangesetParams, FieldType, GridLayout, GroupPB, MoveGroupParams, MoveGroupRowParams, RowPB,
};
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 tokio::time::interval;
@ -47,6 +48,9 @@ pub enum GroupScript {
UpdateField {
changeset: FieldChangesetParams,
},
GroupField {
field_id: String,
},
}
pub struct GridGroupTest {
@ -179,6 +183,9 @@ impl GridGroupTest {
let mut interval = interval(Duration::from_millis(130));
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;
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 {

View File

@ -390,3 +390,12 @@ async fn group_update_field_test() {
];
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;
}