Skip to content

Commit 93f5b5d

Browse files
committed
fix: save group rev without apply change
1 parent 23efbc0 commit 93f5b5d

File tree

16 files changed

+302
-149
lines changed

16 files changed

+302
-149
lines changed

frontend/rust-lib/flowy-error/src/errors.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ impl FlowyError {
6666
static_flowy_error!(user_not_exist, ErrorCode::UserNotExist);
6767
static_flowy_error!(text_too_long, ErrorCode::TextTooLong);
6868
static_flowy_error!(invalid_data, ErrorCode::InvalidData);
69+
static_flowy_error!(out_of_bounds, ErrorCode::OutOfBounds);
6970
}
7071

7172
impl std::convert::From<ErrorCode> for FlowyError {

frontend/rust-lib/flowy-grid/src/entities/group_entities/group_changeset.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,19 @@ pub struct GroupViewChangesetPB {
109109
pub view_id: String,
110110

111111
#[pb(index = 2)]
112-
pub inserted_groups: Vec<GroupPB>,
112+
pub inserted_groups: Vec<InsertedGroupPB>,
113113

114114
#[pb(index = 3)]
115115
pub deleted_groups: Vec<String>,
116116
}
117117

118118
impl GroupViewChangesetPB {}
119+
120+
#[derive(Debug, Default, ProtoBuf)]
121+
pub struct InsertedGroupPB {
122+
#[pb(index = 1)]
123+
pub group: GroupPB,
124+
125+
#[pb(index = 2)]
126+
pub index: i32,
127+
}

frontend/rust-lib/flowy-grid/src/services/grid_view_editor.rs

Lines changed: 79 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
use crate::dart_notification::{send_dart_notification, GridNotification};
22
use crate::entities::{
33
CreateFilterParams, CreateRowParams, DeleteFilterParams, GridFilterConfiguration, GridLayout, GridLayoutPB,
4-
GridSettingChangesetParams, GridSettingPB, GroupPB, GroupRowsChangesetPB, GroupViewChangesetPB, InsertedRowPB,
4+
GridSettingPB, GroupPB, GroupRowsChangesetPB, GroupViewChangesetPB, InsertedGroupPB, InsertedRowPB,
55
MoveGroupParams, RepeatedGridConfigurationFilterPB, RepeatedGridGroupConfigurationPB, RowPB,
66
};
77
use crate::services::grid_editor_task::GridServiceTaskScheduler;
88
use crate::services::grid_view_manager::{GridViewFieldDelegate, GridViewRowDelegate};
9-
use crate::services::group::{
10-
default_group_configuration, GroupConfigurationReader, GroupConfigurationWriter, GroupService,
11-
};
9+
use crate::services::group::{GroupConfigurationReader, GroupConfigurationWriter, GroupService};
1210
use flowy_error::{FlowyError, FlowyResult};
1311
use flowy_grid_data_model::revision::{
1412
gen_grid_filter_id, FieldRevision, FieldTypeRevision, FilterConfigurationRevision, GroupConfigurationRevision,
@@ -19,6 +17,7 @@ use flowy_sync::client_grid::{GridViewRevisionChangeset, GridViewRevisionPad};
1917
use flowy_sync::entities::revision::Revision;
2018
use lib_infra::future::{wrap_future, AFFuture, FutureResult};
2119
use std::collections::HashMap;
20+
2221
use std::sync::atomic::{AtomicBool, Ordering};
2322
use std::sync::Arc;
2423
use tokio::sync::RwLock;
@@ -37,6 +36,7 @@ pub struct GridViewRevisionEditor {
3736
}
3837

3938
impl GridViewRevisionEditor {
39+
#[tracing::instrument(level = "trace", skip_all, err)]
4040
pub(crate) async fn new(
4141
user_id: &str,
4242
token: &str,
@@ -109,7 +109,7 @@ impl GridViewRevisionEditor {
109109
// Send the group notification if the current view has groups;
110110
if let Some(changesets) = self
111111
.group_service
112-
.write()
112+
.read()
113113
.await
114114
.did_delete_row(row_rev, |field_id| self.field_delegate.get_field_rev(&field_id))
115115
.await
@@ -123,7 +123,7 @@ impl GridViewRevisionEditor {
123123
pub(crate) async fn did_update_row(&self, row_rev: &RowRevision) {
124124
if let Some(changesets) = self
125125
.group_service
126-
.write()
126+
.read()
127127
.await
128128
.did_update_row(row_rev, |field_id| self.field_delegate.get_field_rev(&field_id))
129129
.await
@@ -142,7 +142,7 @@ impl GridViewRevisionEditor {
142142
) {
143143
if let Some(changesets) = self
144144
.group_service
145-
.write()
145+
.read()
146146
.await
147147
.did_move_row(row_rev, row_changeset, upper_row_id, |field_id| {
148148
self.field_delegate.get_field_rev(&field_id)
@@ -156,11 +156,13 @@ impl GridViewRevisionEditor {
156156
}
157157
}
158158

159+
#[tracing::instrument(level = "trace", skip(self))]
159160
pub(crate) async fn load_groups(&self) -> FlowyResult<Vec<GroupPB>> {
160161
let groups = if !self.did_load_group.load(Ordering::SeqCst) {
161162
self.did_load_group.store(true, Ordering::SeqCst);
162163
let field_revs = self.field_delegate.get_field_revs().await;
163164
let row_revs = self.row_delegate.gv_row_revs().await;
165+
164166
match self
165167
.group_service
166168
.write()
@@ -174,11 +176,37 @@ impl GridViewRevisionEditor {
174176
} else {
175177
self.group_service.read().await.groups().await
176178
};
179+
180+
tracing::trace!("Number of groups: {}", groups.len());
177181
Ok(groups.into_iter().map(GroupPB::from).collect())
178182
}
179183

180184
pub(crate) async fn move_group(&self, params: MoveGroupParams) -> FlowyResult<()> {
181-
todo!()
185+
let _ = self
186+
.group_service
187+
.read()
188+
.await
189+
.move_group(&params.from_group_id, &params.to_group_id)
190+
.await?;
191+
192+
match self.group_service.read().await.get_group(&params.from_group_id).await {
193+
None => {}
194+
Some((index, group)) => {
195+
let inserted_group = InsertedGroupPB {
196+
group: GroupPB::from(group),
197+
index: index as i32,
198+
};
199+
200+
let changeset = GroupViewChangesetPB {
201+
view_id: "".to_string(),
202+
inserted_groups: vec![inserted_group],
203+
deleted_groups: vec![params.from_group_id.clone()],
204+
};
205+
206+
self.notify_did_update_view(changeset).await;
207+
}
208+
}
209+
Ok(())
182210
}
183211

184212
pub(crate) async fn get_setting(&self) -> GridSettingPB {
@@ -291,17 +319,19 @@ impl RevisionObjectBuilder for GridViewRevisionPadBuilder {
291319
struct GroupConfigurationReaderImpl(Arc<RwLock<GridViewRevisionPad>>);
292320

293321
impl GroupConfigurationReader for GroupConfigurationReaderImpl {
294-
fn get_group_configuration(&self, field_rev: Arc<FieldRevision>) -> AFFuture<Arc<GroupConfigurationRevision>> {
322+
fn get_group_configuration(
323+
&self,
324+
field_rev: Arc<FieldRevision>,
325+
) -> AFFuture<Option<Arc<GroupConfigurationRevision>>> {
295326
let view_pad = self.0.clone();
296327
wrap_future(async move {
297-
let view_pad = view_pad.read().await;
298-
let configurations = view_pad.get_groups(&field_rev.id, &field_rev.ty);
299-
match configurations {
300-
None => {
301-
let default_configuration = default_group_configuration(&field_rev);
302-
Arc::new(default_configuration)
303-
}
304-
Some(configuration) => configuration,
328+
let mut groups = view_pad.read().await.groups.get_objects(&field_rev.id, &field_rev.ty)?;
329+
330+
if groups.is_empty() {
331+
None
332+
} else {
333+
debug_assert_eq!(groups.len(), 1);
334+
Some(groups.pop().unwrap())
305335
}
306336
})
307337
}
@@ -328,17 +358,25 @@ impl GroupConfigurationWriter for GroupConfigurationWriterImpl {
328358
let field_id = field_id.to_owned();
329359

330360
wrap_future(async move {
331-
match view_pad.write().await.get_mut_group(
332-
&field_id,
333-
&field_type,
334-
&configuration_id,
335-
|group_configuration| {
336-
group_configuration.content = content;
337-
},
338-
)? {
339-
None => Ok(()),
340-
Some(changeset) => apply_change(&user_id, rev_manager, changeset).await,
361+
let is_contained = view_pad.read().await.contains_group(&field_id, &field_type);
362+
let changeset = if is_contained {
363+
view_pad.write().await.with_mut_group(
364+
&field_id,
365+
&field_type,
366+
&configuration_id,
367+
|group_configuration| {
368+
group_configuration.content = content;
369+
},
370+
)?
371+
} else {
372+
let group_rev = GroupConfigurationRevision::new(field_id.clone(), field_type, content)?;
373+
view_pad.write().await.insert_group(&field_id, &field_type, group_rev)?
374+
};
375+
376+
if let Some(changeset) = changeset {
377+
let _ = apply_change(&user_id, rev_manager, changeset).await?;
341378
}
379+
Ok(())
342380
})
343381
}
344382
}
@@ -371,3 +409,17 @@ pub fn make_grid_setting(view_pad: &GridViewRevisionPad, field_revs: &[Arc<Field
371409
group_configuration_by_field_id: groups_by_field_id,
372410
}
373411
}
412+
413+
#[cfg(test)]
414+
mod tests {
415+
use lib_ot::core::TextDelta;
416+
417+
#[test]
418+
fn test() {
419+
let s1 = r#"[{"insert":"{\"view_id\":\"fTURELffPr\",\"grid_id\":\"fTURELffPr\",\"layout\":0,\"filters\":[],\"groups\":[]}"}]"#;
420+
let _delta_1 = TextDelta::from_json(s1).unwrap();
421+
422+
let s2 = r#"[{"retain":195},{"insert":"{\\\"group_id\\\":\\\"wD9i\\\",\\\"visible\\\":true},{\\\"group_id\\\":\\\"xZtv\\\",\\\"visible\\\":true},{\\\"group_id\\\":\\\"tFV2\\\",\\\"visible\\\":true}"},{"retain":10}]"#;
423+
let _delta_2 = TextDelta::from_json(s2).unwrap();
424+
}
425+
}

frontend/rust-lib/flowy-grid/src/services/grid_view_manager.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::entities::{
2-
CreateFilterParams, CreateRowParams, DeleteFilterParams, GridFilterConfiguration, GridSettingChangesetParams,
3-
GridSettingPB, MoveGroupParams, RepeatedGridGroupPB, RowPB,
2+
CreateFilterParams, CreateRowParams, DeleteFilterParams, GridFilterConfiguration, GridSettingPB, MoveGroupParams,
3+
RepeatedGridGroupPB, RowPB,
44
};
55
use crate::manager::GridUser;
66
use crate::services::grid_editor_task::GridServiceTaskScheduler;
@@ -122,7 +122,7 @@ impl GridViewManager {
122122

123123
pub(crate) async fn move_group(&self, params: MoveGroupParams) -> FlowyResult<()> {
124124
let view_editor = self.get_default_view_editor().await?;
125-
let _s = view_editor.move_group(params).await?;
125+
let _ = view_editor.move_group(params).await?;
126126
Ok(())
127127
}
128128

@@ -175,12 +175,11 @@ async fn make_view_editor(
175175
row_delegate: Arc<dyn GridViewRowDelegate>,
176176
scheduler: Arc<dyn GridServiceTaskScheduler>,
177177
) -> FlowyResult<GridViewRevisionEditor> {
178-
tracing::trace!("Open view:{} editor", view_id);
179-
180178
let rev_manager = make_grid_view_rev_manager(user, view_id).await?;
181179
let user_id = user.user_id()?;
182180
let token = user.token()?;
183181
let view_id = view_id.to_owned();
182+
184183
GridViewRevisionEditor::new(
185184
&user_id,
186185
&token,
@@ -194,7 +193,6 @@ async fn make_view_editor(
194193
}
195194

196195
pub async fn make_grid_view_rev_manager(user: &Arc<dyn GridUser>, view_id: &str) -> FlowyResult<RevisionManager> {
197-
tracing::trace!("Open view:{} editor", view_id);
198196
let user_id = user.user_id()?;
199197
let pool = user.db_pool()?;
200198

frontend/rust-lib/flowy-grid/src/services/group/configuration.rs

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use crate::services::group::Group;
2-
use flowy_error::FlowyResult;
1+
use crate::services::group::{default_group_configuration, Group};
2+
use flowy_error::{FlowyError, FlowyResult};
33
use flowy_grid_data_model::revision::{
44
FieldRevision, FieldTypeRevision, GroupConfigurationContent, GroupConfigurationRevision, GroupRecordRevision,
55
};
@@ -9,7 +9,10 @@ use lib_infra::future::AFFuture;
99
use std::sync::Arc;
1010

1111
pub trait GroupConfigurationReader: Send + Sync + 'static {
12-
fn get_group_configuration(&self, field_rev: Arc<FieldRevision>) -> AFFuture<Arc<GroupConfigurationRevision>>;
12+
fn get_group_configuration(
13+
&self,
14+
field_rev: Arc<FieldRevision>,
15+
) -> AFFuture<Option<Arc<GroupConfigurationRevision>>>;
1316
}
1417

1518
pub trait GroupConfigurationWriter: Send + Sync + 'static {
@@ -39,7 +42,22 @@ where
3942
reader: Arc<dyn GroupConfigurationReader>,
4043
writer: Arc<dyn GroupConfigurationWriter>,
4144
) -> FlowyResult<Self> {
42-
let configuration_rev = reader.get_group_configuration(field_rev.clone()).await;
45+
let configuration_rev = match reader.get_group_configuration(field_rev.clone()).await {
46+
None => {
47+
let default_group_configuration = default_group_configuration(&field_rev);
48+
writer
49+
.save_group_configuration(
50+
&field_rev.id,
51+
field_rev.ty,
52+
&default_group_configuration.id,
53+
default_group_configuration.content.clone(),
54+
)
55+
.await?;
56+
Arc::new(default_group_configuration)
57+
}
58+
Some(configuration) => configuration,
59+
};
60+
4361
let configuration_id = configuration_rev.id.clone();
4462
let configuration = C::from_configuration_content(&configuration_rev.content)?;
4563
Ok(Self {
@@ -63,6 +81,8 @@ where
6381
let (group_revs, groups) = merge_groups(self.configuration.get_groups(), groups);
6482
self.configuration.set_groups(group_revs);
6583
let _ = self.save_configuration().await?;
84+
85+
tracing::trace!("merge new groups: {}", groups.len());
6686
groups.into_iter().for_each(|group| {
6787
self.groups_map.insert(group.id.clone(), group);
6888
});
@@ -97,8 +117,25 @@ where
97117
self.groups_map.get_mut(group_id)
98118
}
99119

100-
pub(crate) fn get_group(&mut self, group_id: &str) -> Option<&Group> {
101-
self.groups_map.get(group_id)
120+
pub(crate) fn move_group(&mut self, from_group_id: &str, to_group_id: &str) -> FlowyResult<()> {
121+
let from_group_index = self.groups_map.get_index_of(from_group_id);
122+
let to_group_index = self.groups_map.get_index_of(to_group_id);
123+
match (from_group_index, to_group_index) {
124+
(Some(from_index), Some(to_index)) => {
125+
self.groups_map.swap_indices(from_index, to_index);
126+
self.configuration.swap_group(from_group_id, to_group_id);
127+
Ok(())
128+
}
129+
_ => Err(FlowyError::out_of_bounds()),
130+
}
131+
}
132+
133+
// Returns the index and group specified by the group_id
134+
pub(crate) fn get_group(&self, group_id: &str) -> Option<(usize, &Group)> {
135+
match (self.groups_map.get_index_of(group_id), self.groups_map.get(group_id)) {
136+
(Some(index), Some(group)) => Some((index, group)),
137+
_ => None,
138+
}
102139
}
103140

104141
pub async fn save_configuration(&self) -> FlowyResult<()> {
@@ -111,17 +148,17 @@ where
111148
}
112149
}
113150

114-
impl<T> GroupConfigurationReader for Arc<T>
115-
where
116-
T: GroupConfigurationReader,
117-
{
118-
fn get_group_configuration(&self, field_rev: Arc<FieldRevision>) -> AFFuture<Arc<GroupConfigurationRevision>> {
119-
(**self).get_group_configuration(field_rev)
120-
}
121-
}
151+
// impl<T> GroupConfigurationReader for Arc<T>
152+
// where
153+
// T: GroupConfigurationReader,
154+
// {
155+
// fn get_group_configuration(&self, field_rev: Arc<FieldRevision>) -> AFFuture<Arc<GroupConfigurationRevision>> {
156+
// (**self).get_group_configuration(field_rev)
157+
// }
158+
// }
122159

123160
fn merge_groups(old_group_revs: &[GroupRecordRevision], groups: Vec<Group>) -> (Vec<GroupRecordRevision>, Vec<Group>) {
124-
// tracing::trace!("Merge group: old: {}, new: {}", old_group.len(), groups.len());
161+
tracing::trace!("Merge group: old: {}, new: {}", old_group_revs.len(), groups.len());
125162
if old_group_revs.is_empty() {
126163
let new_groups = groups
127164
.iter()

0 commit comments

Comments
 (0)