mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
fix: save group rev without apply change
This commit is contained in:
parent
23efbc00c1
commit
93f5b5d754
@ -66,6 +66,7 @@ impl FlowyError {
|
|||||||
static_flowy_error!(user_not_exist, ErrorCode::UserNotExist);
|
static_flowy_error!(user_not_exist, ErrorCode::UserNotExist);
|
||||||
static_flowy_error!(text_too_long, ErrorCode::TextTooLong);
|
static_flowy_error!(text_too_long, ErrorCode::TextTooLong);
|
||||||
static_flowy_error!(invalid_data, ErrorCode::InvalidData);
|
static_flowy_error!(invalid_data, ErrorCode::InvalidData);
|
||||||
|
static_flowy_error!(out_of_bounds, ErrorCode::OutOfBounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::convert::From<ErrorCode> for FlowyError {
|
impl std::convert::From<ErrorCode> for FlowyError {
|
||||||
|
@ -109,10 +109,19 @@ pub struct GroupViewChangesetPB {
|
|||||||
pub view_id: String,
|
pub view_id: String,
|
||||||
|
|
||||||
#[pb(index = 2)]
|
#[pb(index = 2)]
|
||||||
pub inserted_groups: Vec<GroupPB>,
|
pub inserted_groups: Vec<InsertedGroupPB>,
|
||||||
|
|
||||||
#[pb(index = 3)]
|
#[pb(index = 3)]
|
||||||
pub deleted_groups: Vec<String>,
|
pub deleted_groups: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GroupViewChangesetPB {}
|
impl GroupViewChangesetPB {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, ProtoBuf)]
|
||||||
|
pub struct InsertedGroupPB {
|
||||||
|
#[pb(index = 1)]
|
||||||
|
pub group: GroupPB,
|
||||||
|
|
||||||
|
#[pb(index = 2)]
|
||||||
|
pub index: i32,
|
||||||
|
}
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
use crate::dart_notification::{send_dart_notification, GridNotification};
|
use crate::dart_notification::{send_dart_notification, GridNotification};
|
||||||
use crate::entities::{
|
use crate::entities::{
|
||||||
CreateFilterParams, CreateRowParams, DeleteFilterParams, GridFilterConfiguration, GridLayout, GridLayoutPB,
|
CreateFilterParams, CreateRowParams, DeleteFilterParams, GridFilterConfiguration, GridLayout, GridLayoutPB,
|
||||||
GridSettingChangesetParams, GridSettingPB, GroupPB, GroupRowsChangesetPB, GroupViewChangesetPB, InsertedRowPB,
|
GridSettingPB, GroupPB, GroupRowsChangesetPB, GroupViewChangesetPB, InsertedGroupPB, InsertedRowPB,
|
||||||
MoveGroupParams, RepeatedGridConfigurationFilterPB, RepeatedGridGroupConfigurationPB, RowPB,
|
MoveGroupParams, RepeatedGridConfigurationFilterPB, RepeatedGridGroupConfigurationPB, RowPB,
|
||||||
};
|
};
|
||||||
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::{
|
use crate::services::group::{GroupConfigurationReader, GroupConfigurationWriter, GroupService};
|
||||||
default_group_configuration, GroupConfigurationReader, GroupConfigurationWriter, 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,
|
||||||
@ -19,6 +17,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::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tokio::sync::RwLock;
|
use tokio::sync::RwLock;
|
||||||
@ -37,6 +36,7 @@ pub struct GridViewRevisionEditor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl GridViewRevisionEditor {
|
impl GridViewRevisionEditor {
|
||||||
|
#[tracing::instrument(level = "trace", skip_all, err)]
|
||||||
pub(crate) async fn new(
|
pub(crate) async fn new(
|
||||||
user_id: &str,
|
user_id: &str,
|
||||||
token: &str,
|
token: &str,
|
||||||
@ -109,7 +109,7 @@ impl GridViewRevisionEditor {
|
|||||||
// 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
|
if let Some(changesets) = self
|
||||||
.group_service
|
.group_service
|
||||||
.write()
|
.read()
|
||||||
.await
|
.await
|
||||||
.did_delete_row(row_rev, |field_id| self.field_delegate.get_field_rev(&field_id))
|
.did_delete_row(row_rev, |field_id| self.field_delegate.get_field_rev(&field_id))
|
||||||
.await
|
.await
|
||||||
@ -123,7 +123,7 @@ impl GridViewRevisionEditor {
|
|||||||
pub(crate) async fn did_update_row(&self, row_rev: &RowRevision) {
|
pub(crate) async fn did_update_row(&self, row_rev: &RowRevision) {
|
||||||
if let Some(changesets) = self
|
if let Some(changesets) = self
|
||||||
.group_service
|
.group_service
|
||||||
.write()
|
.read()
|
||||||
.await
|
.await
|
||||||
.did_update_row(row_rev, |field_id| self.field_delegate.get_field_rev(&field_id))
|
.did_update_row(row_rev, |field_id| self.field_delegate.get_field_rev(&field_id))
|
||||||
.await
|
.await
|
||||||
@ -142,7 +142,7 @@ impl GridViewRevisionEditor {
|
|||||||
) {
|
) {
|
||||||
if let Some(changesets) = self
|
if let Some(changesets) = self
|
||||||
.group_service
|
.group_service
|
||||||
.write()
|
.read()
|
||||||
.await
|
.await
|
||||||
.did_move_row(row_rev, row_changeset, upper_row_id, |field_id| {
|
.did_move_row(row_rev, row_changeset, upper_row_id, |field_id| {
|
||||||
self.field_delegate.get_field_rev(&field_id)
|
self.field_delegate.get_field_rev(&field_id)
|
||||||
@ -156,11 +156,13 @@ impl GridViewRevisionEditor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(level = "trace", skip(self))]
|
||||||
pub(crate) async fn load_groups(&self) -> FlowyResult<Vec<GroupPB>> {
|
pub(crate) async fn load_groups(&self) -> FlowyResult<Vec<GroupPB>> {
|
||||||
let groups = if !self.did_load_group.load(Ordering::SeqCst) {
|
let groups = if !self.did_load_group.load(Ordering::SeqCst) {
|
||||||
self.did_load_group.store(true, Ordering::SeqCst);
|
self.did_load_group.store(true, Ordering::SeqCst);
|
||||||
let field_revs = self.field_delegate.get_field_revs().await;
|
let field_revs = self.field_delegate.get_field_revs().await;
|
||||||
let row_revs = self.row_delegate.gv_row_revs().await;
|
let row_revs = self.row_delegate.gv_row_revs().await;
|
||||||
|
|
||||||
match self
|
match self
|
||||||
.group_service
|
.group_service
|
||||||
.write()
|
.write()
|
||||||
@ -174,11 +176,37 @@ impl GridViewRevisionEditor {
|
|||||||
} else {
|
} else {
|
||||||
self.group_service.read().await.groups().await
|
self.group_service.read().await.groups().await
|
||||||
};
|
};
|
||||||
|
|
||||||
|
tracing::trace!("Number of groups: {}", groups.len());
|
||||||
Ok(groups.into_iter().map(GroupPB::from).collect())
|
Ok(groups.into_iter().map(GroupPB::from).collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn move_group(&self, params: MoveGroupParams) -> FlowyResult<()> {
|
pub(crate) async fn move_group(&self, params: MoveGroupParams) -> FlowyResult<()> {
|
||||||
todo!()
|
let _ = self
|
||||||
|
.group_service
|
||||||
|
.read()
|
||||||
|
.await
|
||||||
|
.move_group(¶ms.from_group_id, ¶ms.to_group_id)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
match self.group_service.read().await.get_group(¶ms.from_group_id).await {
|
||||||
|
None => {}
|
||||||
|
Some((index, group)) => {
|
||||||
|
let inserted_group = InsertedGroupPB {
|
||||||
|
group: GroupPB::from(group),
|
||||||
|
index: index as i32,
|
||||||
|
};
|
||||||
|
|
||||||
|
let changeset = GroupViewChangesetPB {
|
||||||
|
view_id: "".to_string(),
|
||||||
|
inserted_groups: vec![inserted_group],
|
||||||
|
deleted_groups: vec![params.from_group_id.clone()],
|
||||||
|
};
|
||||||
|
|
||||||
|
self.notify_did_update_view(changeset).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn get_setting(&self) -> GridSettingPB {
|
pub(crate) async fn get_setting(&self) -> GridSettingPB {
|
||||||
@ -291,17 +319,19 @@ impl RevisionObjectBuilder for GridViewRevisionPadBuilder {
|
|||||||
struct GroupConfigurationReaderImpl(Arc<RwLock<GridViewRevisionPad>>);
|
struct GroupConfigurationReaderImpl(Arc<RwLock<GridViewRevisionPad>>);
|
||||||
|
|
||||||
impl GroupConfigurationReader for GroupConfigurationReaderImpl {
|
impl GroupConfigurationReader for GroupConfigurationReaderImpl {
|
||||||
fn get_group_configuration(&self, field_rev: Arc<FieldRevision>) -> AFFuture<Arc<GroupConfigurationRevision>> {
|
fn get_group_configuration(
|
||||||
|
&self,
|
||||||
|
field_rev: Arc<FieldRevision>,
|
||||||
|
) -> AFFuture<Option<Arc<GroupConfigurationRevision>>> {
|
||||||
let view_pad = self.0.clone();
|
let view_pad = self.0.clone();
|
||||||
wrap_future(async move {
|
wrap_future(async move {
|
||||||
let view_pad = view_pad.read().await;
|
let mut groups = view_pad.read().await.groups.get_objects(&field_rev.id, &field_rev.ty)?;
|
||||||
let configurations = view_pad.get_groups(&field_rev.id, &field_rev.ty);
|
|
||||||
match configurations {
|
if groups.is_empty() {
|
||||||
None => {
|
None
|
||||||
let default_configuration = default_group_configuration(&field_rev);
|
} else {
|
||||||
Arc::new(default_configuration)
|
debug_assert_eq!(groups.len(), 1);
|
||||||
}
|
Some(groups.pop().unwrap())
|
||||||
Some(configuration) => configuration,
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -328,17 +358,25 @@ impl GroupConfigurationWriter for GroupConfigurationWriterImpl {
|
|||||||
let field_id = field_id.to_owned();
|
let field_id = field_id.to_owned();
|
||||||
|
|
||||||
wrap_future(async move {
|
wrap_future(async move {
|
||||||
match view_pad.write().await.get_mut_group(
|
let is_contained = view_pad.read().await.contains_group(&field_id, &field_type);
|
||||||
&field_id,
|
let changeset = if is_contained {
|
||||||
&field_type,
|
view_pad.write().await.with_mut_group(
|
||||||
&configuration_id,
|
&field_id,
|
||||||
|group_configuration| {
|
&field_type,
|
||||||
group_configuration.content = content;
|
&configuration_id,
|
||||||
},
|
|group_configuration| {
|
||||||
)? {
|
group_configuration.content = content;
|
||||||
None => Ok(()),
|
},
|
||||||
Some(changeset) => apply_change(&user_id, rev_manager, changeset).await,
|
)?
|
||||||
|
} else {
|
||||||
|
let group_rev = GroupConfigurationRevision::new(field_id.clone(), field_type, content)?;
|
||||||
|
view_pad.write().await.insert_group(&field_id, &field_type, group_rev)?
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(changeset) = changeset {
|
||||||
|
let _ = apply_change(&user_id, rev_manager, changeset).await?;
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -371,3 +409,17 @@ pub fn make_grid_setting(view_pad: &GridViewRevisionPad, field_revs: &[Arc<Field
|
|||||||
group_configuration_by_field_id: groups_by_field_id,
|
group_configuration_by_field_id: groups_by_field_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use lib_ot::core::TextDelta;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test() {
|
||||||
|
let s1 = r#"[{"insert":"{\"view_id\":\"fTURELffPr\",\"grid_id\":\"fTURELffPr\",\"layout\":0,\"filters\":[],\"groups\":[]}"}]"#;
|
||||||
|
let _delta_1 = TextDelta::from_json(s1).unwrap();
|
||||||
|
|
||||||
|
let s2 = r#"[{"retain":195},{"insert":"{\\\"group_id\\\":\\\"wD9i\\\",\\\"visible\\\":true},{\\\"group_id\\\":\\\"xZtv\\\",\\\"visible\\\":true},{\\\"group_id\\\":\\\"tFV2\\\",\\\"visible\\\":true}"},{"retain":10}]"#;
|
||||||
|
let _delta_2 = TextDelta::from_json(s2).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::entities::{
|
use crate::entities::{
|
||||||
CreateFilterParams, CreateRowParams, DeleteFilterParams, GridFilterConfiguration, GridSettingChangesetParams,
|
CreateFilterParams, CreateRowParams, DeleteFilterParams, GridFilterConfiguration, GridSettingPB, MoveGroupParams,
|
||||||
GridSettingPB, MoveGroupParams, RepeatedGridGroupPB, RowPB,
|
RepeatedGridGroupPB, RowPB,
|
||||||
};
|
};
|
||||||
use crate::manager::GridUser;
|
use crate::manager::GridUser;
|
||||||
use crate::services::grid_editor_task::GridServiceTaskScheduler;
|
use crate::services::grid_editor_task::GridServiceTaskScheduler;
|
||||||
@ -122,7 +122,7 @@ impl GridViewManager {
|
|||||||
|
|
||||||
pub(crate) async fn move_group(&self, params: MoveGroupParams) -> FlowyResult<()> {
|
pub(crate) async fn move_group(&self, params: MoveGroupParams) -> FlowyResult<()> {
|
||||||
let view_editor = self.get_default_view_editor().await?;
|
let view_editor = self.get_default_view_editor().await?;
|
||||||
let _s = view_editor.move_group(params).await?;
|
let _ = view_editor.move_group(params).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,12 +175,11 @@ async fn make_view_editor(
|
|||||||
row_delegate: Arc<dyn GridViewRowDelegate>,
|
row_delegate: Arc<dyn GridViewRowDelegate>,
|
||||||
scheduler: Arc<dyn GridServiceTaskScheduler>,
|
scheduler: Arc<dyn GridServiceTaskScheduler>,
|
||||||
) -> FlowyResult<GridViewRevisionEditor> {
|
) -> FlowyResult<GridViewRevisionEditor> {
|
||||||
tracing::trace!("Open view:{} editor", view_id);
|
|
||||||
|
|
||||||
let rev_manager = make_grid_view_rev_manager(user, view_id).await?;
|
let rev_manager = make_grid_view_rev_manager(user, view_id).await?;
|
||||||
let user_id = user.user_id()?;
|
let user_id = user.user_id()?;
|
||||||
let token = user.token()?;
|
let token = user.token()?;
|
||||||
let view_id = view_id.to_owned();
|
let view_id = view_id.to_owned();
|
||||||
|
|
||||||
GridViewRevisionEditor::new(
|
GridViewRevisionEditor::new(
|
||||||
&user_id,
|
&user_id,
|
||||||
&token,
|
&token,
|
||||||
@ -194,7 +193,6 @@ async fn make_view_editor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn make_grid_view_rev_manager(user: &Arc<dyn GridUser>, view_id: &str) -> FlowyResult<RevisionManager> {
|
pub async fn make_grid_view_rev_manager(user: &Arc<dyn GridUser>, view_id: &str) -> FlowyResult<RevisionManager> {
|
||||||
tracing::trace!("Open view:{} editor", view_id);
|
|
||||||
let user_id = user.user_id()?;
|
let user_id = user.user_id()?;
|
||||||
let pool = user.db_pool()?;
|
let pool = user.db_pool()?;
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::services::group::Group;
|
use crate::services::group::{default_group_configuration, Group};
|
||||||
use flowy_error::FlowyResult;
|
use flowy_error::{FlowyError, FlowyResult};
|
||||||
use flowy_grid_data_model::revision::{
|
use flowy_grid_data_model::revision::{
|
||||||
FieldRevision, FieldTypeRevision, GroupConfigurationContent, GroupConfigurationRevision, GroupRecordRevision,
|
FieldRevision, FieldTypeRevision, GroupConfigurationContent, GroupConfigurationRevision, GroupRecordRevision,
|
||||||
};
|
};
|
||||||
@ -9,7 +9,10 @@ use lib_infra::future::AFFuture;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub trait GroupConfigurationReader: Send + Sync + 'static {
|
pub trait GroupConfigurationReader: Send + Sync + 'static {
|
||||||
fn get_group_configuration(&self, field_rev: Arc<FieldRevision>) -> AFFuture<Arc<GroupConfigurationRevision>>;
|
fn get_group_configuration(
|
||||||
|
&self,
|
||||||
|
field_rev: Arc<FieldRevision>,
|
||||||
|
) -> AFFuture<Option<Arc<GroupConfigurationRevision>>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait GroupConfigurationWriter: Send + Sync + 'static {
|
pub trait GroupConfigurationWriter: Send + Sync + 'static {
|
||||||
@ -39,7 +42,22 @@ where
|
|||||||
reader: Arc<dyn GroupConfigurationReader>,
|
reader: Arc<dyn GroupConfigurationReader>,
|
||||||
writer: Arc<dyn GroupConfigurationWriter>,
|
writer: Arc<dyn GroupConfigurationWriter>,
|
||||||
) -> FlowyResult<Self> {
|
) -> FlowyResult<Self> {
|
||||||
let configuration_rev = reader.get_group_configuration(field_rev.clone()).await;
|
let configuration_rev = match reader.get_group_configuration(field_rev.clone()).await {
|
||||||
|
None => {
|
||||||
|
let default_group_configuration = default_group_configuration(&field_rev);
|
||||||
|
writer
|
||||||
|
.save_group_configuration(
|
||||||
|
&field_rev.id,
|
||||||
|
field_rev.ty,
|
||||||
|
&default_group_configuration.id,
|
||||||
|
default_group_configuration.content.clone(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
Arc::new(default_group_configuration)
|
||||||
|
}
|
||||||
|
Some(configuration) => configuration,
|
||||||
|
};
|
||||||
|
|
||||||
let configuration_id = configuration_rev.id.clone();
|
let configuration_id = configuration_rev.id.clone();
|
||||||
let configuration = C::from_configuration_content(&configuration_rev.content)?;
|
let configuration = C::from_configuration_content(&configuration_rev.content)?;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
@ -63,6 +81,8 @@ where
|
|||||||
let (group_revs, groups) = merge_groups(self.configuration.get_groups(), groups);
|
let (group_revs, groups) = merge_groups(self.configuration.get_groups(), groups);
|
||||||
self.configuration.set_groups(group_revs);
|
self.configuration.set_groups(group_revs);
|
||||||
let _ = self.save_configuration().await?;
|
let _ = self.save_configuration().await?;
|
||||||
|
|
||||||
|
tracing::trace!("merge new groups: {}", groups.len());
|
||||||
groups.into_iter().for_each(|group| {
|
groups.into_iter().for_each(|group| {
|
||||||
self.groups_map.insert(group.id.clone(), group);
|
self.groups_map.insert(group.id.clone(), group);
|
||||||
});
|
});
|
||||||
@ -97,8 +117,25 @@ where
|
|||||||
self.groups_map.get_mut(group_id)
|
self.groups_map.get_mut(group_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_group(&mut self, group_id: &str) -> Option<&Group> {
|
pub(crate) fn move_group(&mut self, from_group_id: &str, to_group_id: &str) -> FlowyResult<()> {
|
||||||
self.groups_map.get(group_id)
|
let from_group_index = self.groups_map.get_index_of(from_group_id);
|
||||||
|
let to_group_index = self.groups_map.get_index_of(to_group_id);
|
||||||
|
match (from_group_index, to_group_index) {
|
||||||
|
(Some(from_index), Some(to_index)) => {
|
||||||
|
self.groups_map.swap_indices(from_index, to_index);
|
||||||
|
self.configuration.swap_group(from_group_id, to_group_id);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
_ => Err(FlowyError::out_of_bounds()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the index and group specified by the group_id
|
||||||
|
pub(crate) fn get_group(&self, group_id: &str) -> Option<(usize, &Group)> {
|
||||||
|
match (self.groups_map.get_index_of(group_id), self.groups_map.get(group_id)) {
|
||||||
|
(Some(index), Some(group)) => Some((index, group)),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn save_configuration(&self) -> FlowyResult<()> {
|
pub async fn save_configuration(&self) -> FlowyResult<()> {
|
||||||
@ -111,17 +148,17 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> GroupConfigurationReader for Arc<T>
|
// impl<T> GroupConfigurationReader for Arc<T>
|
||||||
where
|
// where
|
||||||
T: GroupConfigurationReader,
|
// T: GroupConfigurationReader,
|
||||||
{
|
// {
|
||||||
fn get_group_configuration(&self, field_rev: Arc<FieldRevision>) -> AFFuture<Arc<GroupConfigurationRevision>> {
|
// fn get_group_configuration(&self, field_rev: Arc<FieldRevision>) -> AFFuture<Arc<GroupConfigurationRevision>> {
|
||||||
(**self).get_group_configuration(field_rev)
|
// (**self).get_group_configuration(field_rev)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
fn merge_groups(old_group_revs: &[GroupRecordRevision], groups: Vec<Group>) -> (Vec<GroupRecordRevision>, Vec<Group>) {
|
fn merge_groups(old_group_revs: &[GroupRecordRevision], groups: Vec<Group>) -> (Vec<GroupRecordRevision>, Vec<Group>) {
|
||||||
// tracing::trace!("Merge group: old: {}, new: {}", old_group.len(), groups.len());
|
tracing::trace!("Merge group: old: {}, new: {}", old_group_revs.len(), groups.len());
|
||||||
if old_group_revs.is_empty() {
|
if old_group_revs.is_empty() {
|
||||||
let new_groups = groups
|
let new_groups = groups
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -36,7 +36,9 @@ pub trait GroupControllerSharedOperation: 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 groups(&self) -> Vec<Group>;
|
fn groups(&self) -> Vec<Group>;
|
||||||
|
fn get_group(&self, group_id: &str) -> Option<(usize, Group)>;
|
||||||
fn fill_groups(&mut self, row_revs: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<Vec<Group>>;
|
fn fill_groups(&mut self, row_revs: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<Vec<Group>>;
|
||||||
|
fn move_group(&mut self, from_group_id: &str, to_group_id: &str) -> FlowyResult<()>;
|
||||||
fn did_update_row(
|
fn did_update_row(
|
||||||
&mut self,
|
&mut self,
|
||||||
row_rev: &RowRevision,
|
row_rev: &RowRevision,
|
||||||
@ -118,6 +120,11 @@ where
|
|||||||
self.configuration.clone_groups()
|
self.configuration.clone_groups()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_group(&self, group_id: &str) -> Option<(usize, Group)> {
|
||||||
|
let group = self.configuration.get_group(group_id)?;
|
||||||
|
Some((group.0, group.1.clone()))
|
||||||
|
}
|
||||||
|
|
||||||
fn fill_groups(&mut self, row_revs: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<Vec<Group>> {
|
fn fill_groups(&mut self, row_revs: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<Vec<Group>> {
|
||||||
for row_rev in row_revs {
|
for row_rev in row_revs {
|
||||||
if let Some(cell_rev) = row_rev.cells.get(&self.field_id) {
|
if let Some(cell_rev) = row_rev.cells.get(&self.field_id) {
|
||||||
@ -156,6 +163,10 @@ where
|
|||||||
Ok(groups)
|
Ok(groups)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn move_group(&mut self, from_group_id: &str, to_group_id: &str) -> FlowyResult<()> {
|
||||||
|
self.configuration.move_group(from_group_id, to_group_id)
|
||||||
|
}
|
||||||
|
|
||||||
fn did_update_row(
|
fn did_update_row(
|
||||||
&mut self,
|
&mut self,
|
||||||
row_rev: &RowRevision,
|
row_rev: &RowRevision,
|
||||||
|
@ -71,10 +71,9 @@ impl GroupAction for MultiSelectGroupController {
|
|||||||
|
|
||||||
impl GroupController for MultiSelectGroupController {
|
impl GroupController for MultiSelectGroupController {
|
||||||
fn will_create_row(&mut self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str) {
|
fn will_create_row(&mut self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str) {
|
||||||
let group: Option<&Group> = self.configuration.get_group(group_id);
|
match self.configuration.get_group(group_id) {
|
||||||
match group {
|
|
||||||
None => tracing::warn!("Can not find the group: {}", group_id),
|
None => tracing::warn!("Can not find the group: {}", group_id),
|
||||||
Some(group) => {
|
Some((_, group)) => {
|
||||||
let cell_rev = insert_select_option_cell(group.id.clone(), field_rev);
|
let cell_rev = insert_select_option_cell(group.id.clone(), field_rev);
|
||||||
row_rev.cells.insert(field_rev.id.clone(), cell_rev);
|
row_rev.cells.insert(field_rev.id.clone(), cell_rev);
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,14 @@ impl GroupService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn get_group(&self, group_id: &str) -> Option<(usize, Group)> {
|
||||||
|
if let Some(group_controller) = self.group_controller.as_ref() {
|
||||||
|
group_controller.read().await.get_group(group_id)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) async fn load_groups(
|
pub(crate) async fn load_groups(
|
||||||
&mut self,
|
&mut self,
|
||||||
field_revs: &[Arc<FieldRevision>],
|
field_revs: &[Arc<FieldRevision>],
|
||||||
@ -164,9 +172,20 @@ impl GroupService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(level = "trace", skip_all)]
|
||||||
|
pub(crate) async fn move_group(&self, from_group_id: &str, to_group_id: &str) -> FlowyResult<()> {
|
||||||
|
match self.group_controller.as_ref() {
|
||||||
|
None => Ok(()),
|
||||||
|
Some(group_controller) => {
|
||||||
|
let _ = group_controller.write().await.move_group(from_group_id, to_group_id)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "trace", skip_all)]
|
#[tracing::instrument(level = "trace", skip_all)]
|
||||||
async fn make_group_controller(
|
async fn make_group_controller(
|
||||||
&mut self,
|
&self,
|
||||||
field_type: &FieldType,
|
field_type: &FieldType,
|
||||||
field_rev: &Arc<FieldRevision>,
|
field_rev: &Arc<FieldRevision>,
|
||||||
) -> FlowyResult<Option<Arc<RwLock<dyn GroupController>>>> {
|
) -> FlowyResult<Option<Arc<RwLock<dyn GroupController>>>> {
|
||||||
|
@ -4,11 +4,15 @@ use flowy_grid::services::cell::insert_select_option_cell;
|
|||||||
use flowy_grid_data_model::revision::RowChangeset;
|
use flowy_grid_data_model::revision::RowChangeset;
|
||||||
|
|
||||||
pub enum GroupScript {
|
pub enum GroupScript {
|
||||||
AssertGroup {
|
AssertGroupRowCount {
|
||||||
group_index: usize,
|
group_index: usize,
|
||||||
row_count: usize,
|
row_count: usize,
|
||||||
},
|
},
|
||||||
AssertGroupCount(usize),
|
AssertGroupCount(usize),
|
||||||
|
AssertGroup {
|
||||||
|
group_index: usize,
|
||||||
|
expected_group: GroupPB,
|
||||||
|
},
|
||||||
AssertRow {
|
AssertRow {
|
||||||
group_index: usize,
|
group_index: usize,
|
||||||
row_index: usize,
|
row_index: usize,
|
||||||
@ -56,7 +60,7 @@ impl GridGroupTest {
|
|||||||
|
|
||||||
pub async fn run_script(&mut self, script: GroupScript) {
|
pub async fn run_script(&mut self, script: GroupScript) {
|
||||||
match script {
|
match script {
|
||||||
GroupScript::AssertGroup { group_index, row_count } => {
|
GroupScript::AssertGroupRowCount { group_index, row_count } => {
|
||||||
assert_eq!(row_count, self.group_at_index(group_index).await.rows.len());
|
assert_eq!(row_count, self.group_at_index(group_index).await.rows.len());
|
||||||
}
|
}
|
||||||
GroupScript::AssertGroupCount(count) => {
|
GroupScript::AssertGroupCount(count) => {
|
||||||
@ -142,6 +146,13 @@ impl GridGroupTest {
|
|||||||
self.editor.move_group(params).await.unwrap();
|
self.editor.move_group(params).await.unwrap();
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
GroupScript::AssertGroup {
|
||||||
|
group_index,
|
||||||
|
expected_group: group_pb,
|
||||||
|
} => {
|
||||||
|
let group = self.group_at_index(group_index).await;
|
||||||
|
assert_eq!(group.group_id, group_pb.group_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,15 +6,15 @@ async fn board_init_test() {
|
|||||||
let mut test = GridGroupTest::new().await;
|
let mut test = GridGroupTest::new().await;
|
||||||
let scripts = vec![
|
let scripts = vec![
|
||||||
AssertGroupCount(3),
|
AssertGroupCount(3),
|
||||||
AssertGroup {
|
AssertGroupRowCount {
|
||||||
group_index: 0,
|
group_index: 0,
|
||||||
row_count: 2,
|
row_count: 2,
|
||||||
},
|
},
|
||||||
AssertGroup {
|
AssertGroupRowCount {
|
||||||
group_index: 1,
|
group_index: 1,
|
||||||
row_count: 2,
|
row_count: 2,
|
||||||
},
|
},
|
||||||
AssertGroup {
|
AssertGroupRowCount {
|
||||||
group_index: 2,
|
group_index: 2,
|
||||||
row_count: 1,
|
row_count: 1,
|
||||||
},
|
},
|
||||||
@ -34,7 +34,7 @@ async fn board_move_row_test() {
|
|||||||
to_group_index: 0,
|
to_group_index: 0,
|
||||||
to_row_index: 1,
|
to_row_index: 1,
|
||||||
},
|
},
|
||||||
AssertGroup {
|
AssertGroupRowCount {
|
||||||
group_index: 0,
|
group_index: 0,
|
||||||
row_count: 2,
|
row_count: 2,
|
||||||
},
|
},
|
||||||
@ -58,11 +58,11 @@ async fn board_move_row_to_other_group_test() {
|
|||||||
to_group_index: 1,
|
to_group_index: 1,
|
||||||
to_row_index: 1,
|
to_row_index: 1,
|
||||||
},
|
},
|
||||||
AssertGroup {
|
AssertGroupRowCount {
|
||||||
group_index: 0,
|
group_index: 0,
|
||||||
row_count: 1,
|
row_count: 1,
|
||||||
},
|
},
|
||||||
AssertGroup {
|
AssertGroupRowCount {
|
||||||
group_index: 1,
|
group_index: 1,
|
||||||
row_count: 3,
|
row_count: 3,
|
||||||
},
|
},
|
||||||
@ -106,13 +106,13 @@ async fn board_create_row_test() {
|
|||||||
let mut test = GridGroupTest::new().await;
|
let mut test = GridGroupTest::new().await;
|
||||||
let scripts = vec![
|
let scripts = vec![
|
||||||
CreateRow { group_index: 0 },
|
CreateRow { group_index: 0 },
|
||||||
AssertGroup {
|
AssertGroupRowCount {
|
||||||
group_index: 0,
|
group_index: 0,
|
||||||
row_count: 3,
|
row_count: 3,
|
||||||
},
|
},
|
||||||
CreateRow { group_index: 1 },
|
CreateRow { group_index: 1 },
|
||||||
CreateRow { group_index: 1 },
|
CreateRow { group_index: 1 },
|
||||||
AssertGroup {
|
AssertGroupRowCount {
|
||||||
group_index: 1,
|
group_index: 1,
|
||||||
row_count: 4,
|
row_count: 4,
|
||||||
},
|
},
|
||||||
@ -128,7 +128,7 @@ async fn board_delete_row_test() {
|
|||||||
group_index: 0,
|
group_index: 0,
|
||||||
row_index: 0,
|
row_index: 0,
|
||||||
},
|
},
|
||||||
AssertGroup {
|
AssertGroupRowCount {
|
||||||
group_index: 0,
|
group_index: 0,
|
||||||
row_count: 1,
|
row_count: 1,
|
||||||
},
|
},
|
||||||
@ -148,7 +148,7 @@ async fn board_delete_all_row_test() {
|
|||||||
group_index: 0,
|
group_index: 0,
|
||||||
row_index: 0,
|
row_index: 0,
|
||||||
},
|
},
|
||||||
AssertGroup {
|
AssertGroupRowCount {
|
||||||
group_index: 0,
|
group_index: 0,
|
||||||
row_count: 0,
|
row_count: 0,
|
||||||
},
|
},
|
||||||
@ -166,11 +166,11 @@ async fn board_update_row_test() {
|
|||||||
row_index: 0,
|
row_index: 0,
|
||||||
to_group_index: 1,
|
to_group_index: 1,
|
||||||
},
|
},
|
||||||
AssertGroup {
|
AssertGroupRowCount {
|
||||||
group_index: 0,
|
group_index: 0,
|
||||||
row_count: 1,
|
row_count: 1,
|
||||||
},
|
},
|
||||||
AssertGroup {
|
AssertGroupRowCount {
|
||||||
group_index: 1,
|
group_index: 1,
|
||||||
row_count: 3,
|
row_count: 3,
|
||||||
},
|
},
|
||||||
@ -188,14 +188,36 @@ async fn board_reorder_group_test() {
|
|||||||
row_index: 0,
|
row_index: 0,
|
||||||
to_group_index: 1,
|
to_group_index: 1,
|
||||||
},
|
},
|
||||||
AssertGroup {
|
AssertGroupRowCount {
|
||||||
group_index: 0,
|
group_index: 0,
|
||||||
row_count: 1,
|
row_count: 1,
|
||||||
},
|
},
|
||||||
AssertGroup {
|
AssertGroupRowCount {
|
||||||
group_index: 1,
|
group_index: 1,
|
||||||
row_count: 3,
|
row_count: 3,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
test.run_scripts(scripts).await;
|
test.run_scripts(scripts).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn board_move_group_test() {
|
||||||
|
let mut test = GridGroupTest::new().await;
|
||||||
|
let group_0 = test.group_at_index(0).await;
|
||||||
|
let group_1 = test.group_at_index(1).await;
|
||||||
|
let scripts = vec![
|
||||||
|
MoveGroup {
|
||||||
|
from_group_index: 0,
|
||||||
|
to_group_index: 1,
|
||||||
|
},
|
||||||
|
AssertGroup {
|
||||||
|
group_index: 0,
|
||||||
|
expected_group: group_1,
|
||||||
|
},
|
||||||
|
AssertGroup {
|
||||||
|
group_index: 1,
|
||||||
|
expected_group: group_0,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
test.run_scripts(scripts).await;
|
||||||
|
}
|
||||||
|
@ -74,7 +74,7 @@ fn crate_log_filter(level: String) -> String {
|
|||||||
filters.push(format!("lib_ot={}", level));
|
filters.push(format!("lib_ot={}", level));
|
||||||
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));
|
||||||
|
|
||||||
|
@ -125,6 +125,9 @@ pub enum ErrorCode {
|
|||||||
|
|
||||||
#[display(fmt = "Invalid data")]
|
#[display(fmt = "Invalid data")]
|
||||||
InvalidData = 1000,
|
InvalidData = 1000,
|
||||||
|
|
||||||
|
#[display(fmt = "Out of bounds")]
|
||||||
|
OutOfBounds = 10001,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ErrorCode {
|
impl ErrorCode {
|
||||||
|
@ -49,7 +49,7 @@ where
|
|||||||
.get_mut(field_id)
|
.get_mut(field_id)
|
||||||
.and_then(|object_rev_map| object_rev_map.get_mut(field_type));
|
.and_then(|object_rev_map| object_rev_map.get_mut(field_type));
|
||||||
if value.is_none() {
|
if value.is_none() {
|
||||||
tracing::warn!("Can't find the {:?} with", std::any::type_name::<T>());
|
tracing::warn!("[Configuration] Can't find the {:?} with", std::any::type_name::<T>());
|
||||||
}
|
}
|
||||||
value
|
value
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,7 @@
|
|||||||
use crate::revision::{
|
use crate::revision::{FilterConfiguration, GroupConfiguration};
|
||||||
FieldRevision, FieldTypeRevision, FilterConfiguration, FilterConfigurationRevision, FilterConfigurationsByFieldId,
|
|
||||||
GroupConfiguration, GroupConfigurationRevision, GroupConfigurationsByFieldId,
|
|
||||||
};
|
|
||||||
use nanoid::nanoid;
|
use nanoid::nanoid;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_repr::*;
|
use serde_repr::*;
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn gen_grid_view_id() -> String {
|
pub fn gen_grid_view_id() -> String {
|
||||||
@ -40,15 +36,15 @@ pub struct GridViewRevision {
|
|||||||
|
|
||||||
pub layout: LayoutRevision,
|
pub layout: LayoutRevision,
|
||||||
|
|
||||||
|
#[serde(default)]
|
||||||
pub filters: FilterConfiguration,
|
pub filters: FilterConfiguration,
|
||||||
|
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub groups: GroupConfiguration,
|
pub groups: GroupConfiguration,
|
||||||
|
// // For the moment, we just use the order returned from the GridRevision
|
||||||
// For the moment, we just use the order returned from the GridRevision
|
// #[allow(dead_code)]
|
||||||
#[allow(dead_code)]
|
// #[serde(skip, rename = "rows")]
|
||||||
#[serde(skip, rename = "row")]
|
// pub row_orders: Vec<RowOrderRevision>,
|
||||||
pub row_orders: Vec<RowOrderRevision>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GridViewRevision {
|
impl GridViewRevision {
|
||||||
@ -59,78 +55,33 @@ impl GridViewRevision {
|
|||||||
layout: Default::default(),
|
layout: Default::default(),
|
||||||
filters: Default::default(),
|
filters: Default::default(),
|
||||||
groups: Default::default(),
|
groups: Default::default(),
|
||||||
row_orders: vec![],
|
// row_orders: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_all_groups(&self, field_revs: &[Arc<FieldRevision>]) -> Option<GroupConfigurationsByFieldId> {
|
|
||||||
self.groups.get_all_objects(field_revs)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_groups(
|
|
||||||
&self,
|
|
||||||
field_id: &str,
|
|
||||||
field_type_rev: &FieldTypeRevision,
|
|
||||||
) -> Option<Arc<GroupConfigurationRevision>> {
|
|
||||||
let mut groups = self.groups.get_objects(field_id, field_type_rev)?;
|
|
||||||
if groups.is_empty() {
|
|
||||||
debug_assert_eq!(groups.len(), 1);
|
|
||||||
Some(groups.pop().unwrap())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_mut_groups(
|
|
||||||
&mut self,
|
|
||||||
field_id: &str,
|
|
||||||
field_type: &FieldTypeRevision,
|
|
||||||
) -> Option<&mut Vec<Arc<GroupConfigurationRevision>>> {
|
|
||||||
self.groups.get_mut_objects(field_id, field_type)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert_group(
|
|
||||||
&mut self,
|
|
||||||
field_id: &str,
|
|
||||||
field_type: &FieldTypeRevision,
|
|
||||||
group_rev: GroupConfigurationRevision,
|
|
||||||
) {
|
|
||||||
// only one group can be set
|
|
||||||
self.groups.remove_all();
|
|
||||||
self.groups.insert_object(field_id, field_type, group_rev);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_all_filters(&self, field_revs: &[Arc<FieldRevision>]) -> Option<FilterConfigurationsByFieldId> {
|
|
||||||
self.filters.get_all_objects(field_revs)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_filters(
|
|
||||||
&self,
|
|
||||||
field_id: &str,
|
|
||||||
field_type_rev: &FieldTypeRevision,
|
|
||||||
) -> Option<Vec<Arc<FilterConfigurationRevision>>> {
|
|
||||||
self.filters.get_objects(field_id, field_type_rev)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_mut_filters(
|
|
||||||
&mut self,
|
|
||||||
field_id: &str,
|
|
||||||
field_type: &FieldTypeRevision,
|
|
||||||
) -> Option<&mut Vec<Arc<FilterConfigurationRevision>>> {
|
|
||||||
self.filters.get_mut_objects(field_id, field_type)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert_filter(
|
|
||||||
&mut self,
|
|
||||||
field_id: &str,
|
|
||||||
field_type: &FieldTypeRevision,
|
|
||||||
filter_rev: FilterConfigurationRevision,
|
|
||||||
) {
|
|
||||||
self.filters.insert_object(field_id, field_type, filter_rev);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||||
pub struct RowOrderRevision {
|
pub struct RowOrderRevision {
|
||||||
pub row_id: String,
|
pub row_id: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::revision::GridViewRevision;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn grid_view_revision_serde_test() {
|
||||||
|
let grid_view_revision = GridViewRevision {
|
||||||
|
view_id: "1".to_string(),
|
||||||
|
grid_id: "1".to_string(),
|
||||||
|
layout: Default::default(),
|
||||||
|
filters: Default::default(),
|
||||||
|
groups: Default::default(),
|
||||||
|
};
|
||||||
|
let s = serde_json::to_string(&grid_view_revision).unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
s,
|
||||||
|
r#"{"view_id":"1","grid_id":"1","layout":0,"filters":[],"groups":[]}"#
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -12,8 +12,23 @@ pub trait GroupConfigurationContent: Sized {
|
|||||||
&[]
|
&[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mut_groups(&mut self) -> &mut Vec<GroupRecordRevision> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
fn set_groups(&mut self, _new_groups: Vec<GroupRecordRevision>) {}
|
fn set_groups(&mut self, _new_groups: Vec<GroupRecordRevision>) {}
|
||||||
|
|
||||||
|
fn swap_group(&mut self, from_group_id: &str, to_group_id: &str) {
|
||||||
|
let from_index = self
|
||||||
|
.get_groups()
|
||||||
|
.iter()
|
||||||
|
.position(|group| group.group_id == from_group_id);
|
||||||
|
let to_index = self.get_groups().iter().position(|group| group.group_id == to_group_id);
|
||||||
|
if let (Some(from), Some(to)) = (from_index, to_index) {
|
||||||
|
self.mut_groups().swap(from, to);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn with_mut_group<F>(&mut self, _group_id: &str, _f: F)
|
fn with_mut_group<F>(&mut self, _group_id: &str, _f: F)
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut GroupRecordRevision),
|
F: FnOnce(&mut GroupRecordRevision),
|
||||||
@ -120,6 +135,10 @@ impl GroupConfigurationContent for SelectOptionGroupConfigurationRevision {
|
|||||||
&self.groups
|
&self.groups
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mut_groups(&mut self) -> &mut Vec<GroupRecordRevision> {
|
||||||
|
&mut self.groups
|
||||||
|
}
|
||||||
|
|
||||||
fn set_groups(&mut self, new_groups: Vec<GroupRecordRevision>) {
|
fn set_groups(&mut self, new_groups: Vec<GroupRecordRevision>) {
|
||||||
self.groups = new_groups;
|
self.groups = new_groups;
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,26 @@ impl GridViewRevisionPad {
|
|||||||
self.groups.get_all_objects(field_revs)
|
self.groups.get_all_objects(field_revs)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_mut_group<F: FnOnce(&mut GroupConfigurationRevision)>(
|
#[tracing::instrument(level = "trace", skip_all, err)]
|
||||||
|
pub fn insert_group(
|
||||||
|
&mut self,
|
||||||
|
field_id: &str,
|
||||||
|
field_type: &FieldTypeRevision,
|
||||||
|
group_rev: GroupConfigurationRevision,
|
||||||
|
) -> CollaborateResult<Option<GridViewRevisionChangeset>> {
|
||||||
|
self.modify(|view| {
|
||||||
|
view.groups.insert_object(field_id, field_type, group_rev);
|
||||||
|
Ok(Some(()))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(level = "trace", skip_all)]
|
||||||
|
pub fn contains_group(&self, field_id: &str, field_type: &FieldTypeRevision) -> bool {
|
||||||
|
self.view.groups.get_objects(field_id, field_type).is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(level = "trace", skip_all, err)]
|
||||||
|
pub fn with_mut_group<F: FnOnce(&mut GroupConfigurationRevision)>(
|
||||||
&mut self,
|
&mut self,
|
||||||
field_id: &str,
|
field_id: &str,
|
||||||
field_type: &FieldTypeRevision,
|
field_type: &FieldTypeRevision,
|
||||||
@ -147,6 +166,8 @@ impl GridViewRevisionPad {
|
|||||||
None => Ok(None),
|
None => Ok(None),
|
||||||
Some(delta) => {
|
Some(delta) => {
|
||||||
self.delta = self.delta.compose(&delta)?;
|
self.delta = self.delta.compose(&delta)?;
|
||||||
|
tracing::info!("GridView: {:?}", delta);
|
||||||
|
|
||||||
let md5 = md5(&self.delta.json_bytes());
|
let md5 = md5(&self.delta.json_bytes());
|
||||||
Ok(Some(GridViewRevisionChangeset { delta, md5 }))
|
Ok(Some(GridViewRevisionChangeset { delta, md5 }))
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user