mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: support switch to multi select field
This commit is contained in:
parent
15ff2efcc2
commit
1931cdd4c0
@ -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()
|
||||
|
@ -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,
|
||||
|
@ -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()
|
||||
|
@ -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::*;
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user