mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
refactor: move row params
This commit is contained in:
@ -96,28 +96,27 @@ pub struct MoveRowPayloadPB {
|
||||
pub view_id: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub row_id: String,
|
||||
|
||||
#[pb(index = 3)]
|
||||
pub from_index: i32,
|
||||
|
||||
#[pb(index = 4)]
|
||||
pub to_index: i32,
|
||||
pub from_row_id: String,
|
||||
|
||||
// #[pb(index = 3)]
|
||||
// pub from_index: i32,
|
||||
//
|
||||
// #[pb(index = 4)]
|
||||
// pub to_index: i32,
|
||||
#[pb(index = 5)]
|
||||
pub layout: GridLayout,
|
||||
|
||||
#[pb(index = 6, one_of)]
|
||||
pub upper_row_id: Option<String>,
|
||||
#[pb(index = 6)]
|
||||
pub to_row_id: String,
|
||||
}
|
||||
|
||||
pub struct MoveRowParams {
|
||||
pub view_id: String,
|
||||
pub row_id: String,
|
||||
pub from_index: i32,
|
||||
pub to_index: i32,
|
||||
pub from_row_id: String,
|
||||
// pub from_index: i32,
|
||||
// pub to_index: i32,
|
||||
pub layout: GridLayout,
|
||||
pub upper_row_id: Option<String>,
|
||||
pub to_row_id: String,
|
||||
}
|
||||
|
||||
impl TryInto<MoveRowParams> for MoveRowPayloadPB {
|
||||
@ -125,18 +124,19 @@ impl TryInto<MoveRowParams> for MoveRowPayloadPB {
|
||||
|
||||
fn try_into(self) -> Result<MoveRowParams, Self::Error> {
|
||||
let view_id = NotEmptyStr::parse(self.view_id).map_err(|_| ErrorCode::GridViewIdIsEmpty)?;
|
||||
let row_id = NotEmptyStr::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?;
|
||||
let upper_row_id = match self.upper_row_id {
|
||||
let from_row_id = NotEmptyStr::parse(self.from_row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?;
|
||||
let to_row_id = NotEmptyStr::parse(self.to_row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?;
|
||||
let upper_row_id = match self.to_row_id {
|
||||
None => None,
|
||||
Some(upper_row_id) => Some(NotEmptyStr::parse(upper_row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?.0),
|
||||
};
|
||||
Ok(MoveRowParams {
|
||||
view_id: view_id.0,
|
||||
row_id: row_id.0,
|
||||
from_index: self.from_index,
|
||||
to_index: self.to_index,
|
||||
from_row_id: from_row_id.0,
|
||||
// from_index: self.from_index,
|
||||
// to_index: self.to_index,
|
||||
layout: self.layout,
|
||||
upper_row_id,
|
||||
to_row_id: upper_row_id,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
use crate::entities::{InsertedRowPB, RowPB};
|
||||
use flowy_derive::ProtoBuf;
|
||||
use std::fmt::Formatter;
|
||||
|
||||
#[derive(Debug, Default, ProtoBuf)]
|
||||
pub struct GroupRowsChangesetPB {
|
||||
@ -16,6 +17,14 @@ pub struct GroupRowsChangesetPB {
|
||||
pub updated_rows: Vec<RowPB>,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for GroupRowsChangesetPB {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
let _ = f.write_fmt(format_args!("Group:{}", self.group_id))?;
|
||||
let _ = f.write_fmt(format_args!("Insert:{:?}", self.inserted_rows))?;
|
||||
f.write_fmt(format_args!("Delete:{:?}", self.deleted_rows))
|
||||
}
|
||||
}
|
||||
|
||||
impl GroupRowsChangesetPB {
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.inserted_rows.is_empty() && self.deleted_rows.is_empty() && self.updated_rows.is_empty()
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::services::block_manager::GridBlockManager;
|
||||
use crate::services::grid_view_manager::{GridViewRowDelegate, GridViewRowOperation};
|
||||
use crate::services::grid_view_manager::GridViewRowDelegate;
|
||||
use flowy_error::FlowyResult;
|
||||
use flowy_grid_data_model::revision::RowRevision;
|
||||
use lib_infra::future::{wrap_future, AFFuture};
|
||||
@ -36,10 +36,3 @@ impl GridViewRowDelegate for Arc<GridBlockManager> {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl GridViewRowOperation for Arc<GridBlockManager> {
|
||||
fn gv_move_row(&self, row_rev: Arc<RowRevision>, from: usize, to: usize) -> AFFuture<FlowyResult<()>> {
|
||||
let block_manager = self.clone();
|
||||
wrap_future(async move { block_manager.move_row(row_rev, from, to).await })
|
||||
}
|
||||
}
|
||||
|
@ -72,7 +72,6 @@ impl GridRevisionEditor {
|
||||
user.clone(),
|
||||
Arc::new(grid_pad.clone()),
|
||||
Arc::new(block_manager.clone()),
|
||||
Arc::new(block_manager.clone()),
|
||||
Arc::new(task_scheduler.clone()),
|
||||
)
|
||||
.await?,
|
||||
@ -494,7 +493,42 @@ impl GridRevisionEditor {
|
||||
}
|
||||
|
||||
pub async fn move_row(&self, params: MoveRowParams) -> FlowyResult<()> {
|
||||
self.view_manager.move_row(params).await
|
||||
let MoveRowParams {
|
||||
view_id: _,
|
||||
from_row_id: row_id,
|
||||
from_index,
|
||||
to_index,
|
||||
layout: _,
|
||||
to_row_id: upper_row_id,
|
||||
} = params;
|
||||
|
||||
let from_index = from_index as usize;
|
||||
let to_index = to_index as usize;
|
||||
|
||||
match self.block_manager.get_row_rev(&row_id).await? {
|
||||
None => tracing::warn!("Move row failed, can not find the row:{}", row_id),
|
||||
Some(row_rev) => match upper_row_id {
|
||||
None => {
|
||||
tracing::trace!("Move row from {} to {}", from_index, to_index);
|
||||
let _ = self
|
||||
.block_manager
|
||||
.move_row(row_rev.clone(), from_index, to_index)
|
||||
.await?;
|
||||
}
|
||||
Some(to_row_id) => match self.block_manager.index_of_row(&to_row_id).await {
|
||||
None => tracing::error!("Can not find the row: {} when moving the row", to_row_id),
|
||||
Some(to_row_index) => {
|
||||
tracing::trace!("Move row from {} to {}", from_index, to_row_index);
|
||||
let _ = self
|
||||
.block_manager
|
||||
.move_row(row_rev.clone(), from_index, to_row_index)
|
||||
.await?;
|
||||
self.view_manager.move_row(row_rev, to_row_id).await;
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn move_field(&self, params: MoveFieldParams) -> FlowyResult<()> {
|
||||
|
@ -118,17 +118,22 @@ impl GridViewRevisionEditor {
|
||||
}
|
||||
}
|
||||
|
||||
// async fn get_mut_group<F>(&self, group_id: &str, f: F) -> FlowyResult<()>
|
||||
// where
|
||||
// F: Fn(&mut Group) -> FlowyResult<()>,
|
||||
// {
|
||||
// for group in self.groups.write().await.iter_mut() {
|
||||
// if group.id == group_id {
|
||||
// let _ = f(group)?;
|
||||
// }
|
||||
// }
|
||||
// Ok(())
|
||||
// }
|
||||
pub(crate) async fn did_move_row(&self, row_rev: &RowRevision, upper_row_id: &str) {
|
||||
if let Some(changesets) = self
|
||||
.group_service
|
||||
.write()
|
||||
.await
|
||||
.did_move_row(row_rev, upper_row_id, |field_id| {
|
||||
self.field_delegate.get_field_rev(&field_id)
|
||||
})
|
||||
.await
|
||||
{
|
||||
for changeset in changesets {
|
||||
tracing::trace!("Group changeset: {}", changeset);
|
||||
self.notify_did_update_group(changeset).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn load_groups(&self) -> FlowyResult<Vec<GroupPB>> {
|
||||
let field_revs = self.field_delegate.get_field_revs().await;
|
||||
|
@ -31,17 +31,11 @@ pub trait GridViewRowDelegate: Send + Sync + 'static {
|
||||
fn gv_row_revs(&self) -> AFFuture<Vec<Arc<RowRevision>>>;
|
||||
}
|
||||
|
||||
pub trait GridViewRowOperation: Send + Sync + 'static {
|
||||
// Will be removed in the future.
|
||||
fn gv_move_row(&self, row_rev: Arc<RowRevision>, from: usize, to: usize) -> AFFuture<FlowyResult<()>>;
|
||||
}
|
||||
|
||||
pub(crate) struct GridViewManager {
|
||||
grid_id: String,
|
||||
user: Arc<dyn GridUser>,
|
||||
field_delegate: Arc<dyn GridViewFieldDelegate>,
|
||||
row_delegate: Arc<dyn GridViewRowDelegate>,
|
||||
row_operation: Arc<dyn GridViewRowOperation>,
|
||||
view_editors: DashMap<ViewId, Arc<GridViewRevisionEditor>>,
|
||||
scheduler: Arc<dyn GridServiceTaskScheduler>,
|
||||
}
|
||||
@ -52,7 +46,6 @@ impl GridViewManager {
|
||||
user: Arc<dyn GridUser>,
|
||||
field_delegate: Arc<dyn GridViewFieldDelegate>,
|
||||
row_delegate: Arc<dyn GridViewRowDelegate>,
|
||||
row_operation: Arc<dyn GridViewRowOperation>,
|
||||
scheduler: Arc<dyn GridServiceTaskScheduler>,
|
||||
) -> FlowyResult<Self> {
|
||||
Ok(Self {
|
||||
@ -61,7 +54,6 @@ impl GridViewManager {
|
||||
scheduler,
|
||||
field_delegate,
|
||||
row_delegate,
|
||||
row_operation,
|
||||
view_editors: DashMap::default(),
|
||||
})
|
||||
}
|
||||
@ -119,37 +111,10 @@ impl GridViewManager {
|
||||
Ok(RepeatedGridGroupPB { items: groups })
|
||||
}
|
||||
|
||||
pub(crate) async fn move_row(&self, params: MoveRowParams) -> FlowyResult<()> {
|
||||
let MoveRowParams {
|
||||
view_id: _,
|
||||
row_id,
|
||||
from_index,
|
||||
to_index,
|
||||
layout,
|
||||
upper_row_id,
|
||||
} = params;
|
||||
|
||||
let from_index = from_index as usize;
|
||||
|
||||
match self.row_delegate.gv_get_row_rev(&row_id).await {
|
||||
None => tracing::warn!("Move row failed, can not find the row:{}", row_id),
|
||||
Some(row_rev) => match layout {
|
||||
GridLayout::Table => {
|
||||
tracing::trace!("Move row from {} to {}", from_index, to_index);
|
||||
let to_index = to_index as usize;
|
||||
let _ = self.row_operation.gv_move_row(row_rev, from_index, to_index).await?;
|
||||
}
|
||||
GridLayout::Board => {
|
||||
if let Some(upper_row_id) = upper_row_id {
|
||||
if let Some(to_index) = self.row_delegate.gv_index_of_row(&upper_row_id).await {
|
||||
tracing::trace!("Move row from {} to {}", from_index, to_index);
|
||||
let _ = self.row_operation.gv_move_row(row_rev, from_index, to_index).await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
pub(crate) async fn move_row(&self, row_rev: Arc<RowRevision>, to_row_id: String) {
|
||||
for view_editor in self.view_editors.iter() {
|
||||
view_editor.did_move_row(&row_rev, &to_row_id).await;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn get_view_editor(&self, view_id: &str) -> FlowyResult<Arc<GridViewRevisionEditor>> {
|
||||
|
@ -39,6 +39,7 @@ impl Groupable for CheckboxGroupController {
|
||||
&mut self,
|
||||
row_rev: &RowRevision,
|
||||
cell_data: &Self::CellDataType,
|
||||
to_row_id: &str,
|
||||
) -> Vec<GroupRowsChangesetPB> {
|
||||
todo!()
|
||||
}
|
||||
|
@ -29,8 +29,12 @@ pub trait Groupable: Send + Sync {
|
||||
cell_data: &Self::CellDataType,
|
||||
) -> Vec<GroupRowsChangesetPB>;
|
||||
|
||||
fn move_row_if_match(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType)
|
||||
-> Vec<GroupRowsChangesetPB>;
|
||||
fn move_row_if_match(
|
||||
&mut self,
|
||||
row_rev: &RowRevision,
|
||||
cell_data: &Self::CellDataType,
|
||||
to_row_id: &str,
|
||||
) -> Vec<GroupRowsChangesetPB>;
|
||||
}
|
||||
|
||||
pub trait GroupController: GroupControllerSharedAction + Send + Sync {
|
||||
@ -53,6 +57,13 @@ pub trait GroupControllerSharedAction: Send + Sync {
|
||||
row_rev: &RowRevision,
|
||||
field_rev: &FieldRevision,
|
||||
) -> FlowyResult<Vec<GroupRowsChangesetPB>>;
|
||||
|
||||
fn did_move_row(
|
||||
&mut self,
|
||||
row_rev: &RowRevision,
|
||||
field_rev: &FieldRevision,
|
||||
to_row_id: &str,
|
||||
) -> FlowyResult<Vec<GroupRowsChangesetPB>>;
|
||||
}
|
||||
|
||||
const DEFAULT_GROUP_ID: &str = "default_group";
|
||||
@ -120,6 +131,18 @@ impl Group {
|
||||
Some(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert_row(&mut self, index: usize, row_pb: RowPB) {
|
||||
if index < self.rows.len() {
|
||||
self.rows.insert(index, row_pb);
|
||||
} else {
|
||||
tracing::error!("Insert row index:{} beyond the bounds:{},", index, self.rows.len());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn index_of_row(&self, row_id: &str) -> Option<usize> {
|
||||
self.rows.iter().position(|row| row.id == row_id)
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, T, G, P> GenericGroupController<C, T, G, P>
|
||||
@ -236,6 +259,21 @@ where
|
||||
Ok(vec![])
|
||||
}
|
||||
}
|
||||
|
||||
fn did_move_row(
|
||||
&mut self,
|
||||
row_rev: &RowRevision,
|
||||
field_rev: &FieldRevision,
|
||||
to_row_id: &str,
|
||||
) -> 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.move_row_if_match(row_rev, &cell_data, to_row_id))
|
||||
} else {
|
||||
Ok(vec![])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// impl<C, T, G, P> GroupController<C, T, G, P>
|
||||
|
@ -45,8 +45,13 @@ impl Groupable for SingleSelectGroupController {
|
||||
&mut self,
|
||||
row_rev: &RowRevision,
|
||||
cell_data: &Self::CellDataType,
|
||||
to_row_id: &str,
|
||||
) -> Vec<GroupRowsChangesetPB> {
|
||||
todo!()
|
||||
let mut changesets = vec![];
|
||||
self.groups_map.iter_mut().for_each(|(_, group): (_, &mut Group)| {
|
||||
move_row(group, &mut changesets, cell_data, row_rev, to_row_id);
|
||||
});
|
||||
changesets
|
||||
}
|
||||
}
|
||||
|
||||
@ -100,7 +105,6 @@ impl Groupable for MultiSelectGroupController {
|
||||
|
||||
fn add_row_if_match(&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)| {
|
||||
add_row(group, &mut changesets, cell_data, row_rev);
|
||||
});
|
||||
@ -123,8 +127,13 @@ impl Groupable for MultiSelectGroupController {
|
||||
&mut self,
|
||||
row_rev: &RowRevision,
|
||||
cell_data: &Self::CellDataType,
|
||||
to_row_id: &str,
|
||||
) -> Vec<GroupRowsChangesetPB> {
|
||||
todo!()
|
||||
let mut changesets = vec![];
|
||||
self.groups_map.iter_mut().for_each(|(_, group): (_, &mut Group)| {
|
||||
move_row(group, &mut changesets, cell_data, row_rev, to_row_id);
|
||||
});
|
||||
changesets
|
||||
}
|
||||
}
|
||||
|
||||
@ -178,11 +187,6 @@ fn add_row(
|
||||
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()]));
|
||||
// }
|
||||
});
|
||||
}
|
||||
|
||||
@ -201,3 +205,30 @@ fn remove_row(
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn move_row(
|
||||
group: &mut Group,
|
||||
changesets: &mut Vec<GroupRowsChangesetPB>,
|
||||
cell_data: &SelectOptionCellDataPB,
|
||||
row_rev: &RowRevision,
|
||||
upper_row_id: &str,
|
||||
) {
|
||||
cell_data.select_options.iter().for_each(|option| {
|
||||
if option.id == group.id {
|
||||
if group.contains_row(&row_rev.id) {
|
||||
changesets.push(GroupRowsChangesetPB::delete(group.id.clone(), vec![row_rev.id.clone()]));
|
||||
group.remove_row(&row_rev.id);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(index) = group.index_of_row(upper_row_id) {
|
||||
let row_pb = RowPB::from(row_rev);
|
||||
let inserted_row = InsertedRowPB {
|
||||
row: row_pb.clone(),
|
||||
index: Some(index as i32),
|
||||
};
|
||||
changesets.push(GroupRowsChangesetPB::insert(group.id.clone(), vec![inserted_row]));
|
||||
group.insert_row(index, row_pb);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -87,7 +87,34 @@ impl GroupService {
|
||||
match group_controller.write().await.did_delete_row(row_rev, &field_rev) {
|
||||
Ok(changesets) => Some(changesets),
|
||||
Err(e) => {
|
||||
tracing::error!("Update group data failed, {:?}", e);
|
||||
tracing::error!("Delete group data failed, {:?}", e);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn did_move_row<F, O>(
|
||||
&self,
|
||||
row_rev: &RowRevision,
|
||||
upper_row_id: &str,
|
||||
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_move_row(row_rev, &field_rev, upper_row_id)
|
||||
{
|
||||
Ok(changesets) => Some(changesets),
|
||||
Err(e) => {
|
||||
tracing::error!("Move group data failed, {:?}", e);
|
||||
None
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user