Skip to content

Commit f5b7d39

Browse files
authored
Feat/sort after change (#1607)
* chore: generate task after row was changed * chore: config task * chore: add task test Co-authored-by: nathan <[email protected]>
1 parent 5a30f46 commit f5b7d39

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+967
-572
lines changed

frontend/rust-lib/flowy-grid/src/dart_notification.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ pub enum GridDartNotification {
1717
DidGroupByNewField = 62,
1818
DidUpdateFilter = 63,
1919
DidUpdateSort = 64,
20+
DidReorderRows = 65,
21+
DidReorderSingleRow = 66,
2022
DidUpdateGridSetting = 70,
2123
}
2224

frontend/rust-lib/flowy-grid/src/entities/sort_entities.rs

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::services::sort::SortType;
44

55
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
66
use flowy_error::ErrorCode;
7-
use grid_rev_model::FieldTypeRevision;
7+
use grid_rev_model::{FieldTypeRevision, SortCondition, SortRevision};
88

99
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
1010
pub struct GridSortPB {
@@ -21,6 +21,17 @@ pub struct GridSortPB {
2121
pub condition: GridSortConditionPB,
2222
}
2323

24+
impl std::convert::From<&SortRevision> for GridSortPB {
25+
fn from(sort_rev: &SortRevision) -> Self {
26+
Self {
27+
id: sort_rev.id.clone(),
28+
field_id: sort_rev.field_id.clone(),
29+
field_type: sort_rev.field_type.into(),
30+
condition: sort_rev.condition.clone().into(),
31+
}
32+
}
33+
}
34+
2435
#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum)]
2536
#[repr(u8)]
2637
pub enum GridSortConditionPB {
@@ -32,6 +43,16 @@ impl std::default::Default for GridSortConditionPB {
3243
Self::Ascending
3344
}
3445
}
46+
47+
impl std::convert::From<SortCondition> for GridSortConditionPB {
48+
fn from(condition: SortCondition) -> Self {
49+
match condition {
50+
SortCondition::Ascending => GridSortConditionPB::Ascending,
51+
SortCondition::Descending => GridSortConditionPB::Descending,
52+
}
53+
}
54+
}
55+
3556
#[derive(ProtoBuf, Debug, Default, Clone)]
3657
pub struct AlterSortPayloadPB {
3758
#[pb(index = 1)]
@@ -151,3 +172,30 @@ pub struct SortChangesetNotificationPB {
151172
#[pb(index = 4)]
152173
pub update_sorts: Vec<GridSortPB>,
153174
}
175+
176+
impl SortChangesetNotificationPB {
177+
pub fn extend(&mut self, other: SortChangesetNotificationPB) {
178+
self.insert_sorts.extend(other.insert_sorts);
179+
self.delete_sorts.extend(other.delete_sorts);
180+
self.update_sorts.extend(other.update_sorts);
181+
}
182+
183+
pub fn is_empty(&self) -> bool {
184+
self.insert_sorts.is_empty() && self.delete_sorts.is_empty() && self.update_sorts.is_empty()
185+
}
186+
}
187+
188+
#[derive(Debug, Default, ProtoBuf)]
189+
pub struct ReorderAllRowsPB {
190+
#[pb(index = 1)]
191+
pub row_orders: Vec<String>,
192+
}
193+
194+
#[derive(Debug, Default, ProtoBuf)]
195+
pub struct ReorderSingleRowPB {
196+
#[pb(index = 1)]
197+
pub old_index: i32,
198+
199+
#[pb(index = 2)]
200+
pub new_index: i32,
201+
}

frontend/rust-lib/flowy-grid/src/event_handler.rs

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::entities::*;
22
use crate::manager::GridManager;
3-
use crate::services::cell::{FromCellString, TypeCellData};
3+
use crate::services::cell::{FromCellString, ToCellChangesetString, TypeCellData};
44
use crate::services::field::{
55
default_type_option_builder_from_type, select_type_option_from_field_rev, type_option_builder_from_json_str,
66
DateCellChangeset, DateChangesetPB, SelectOptionCellChangeset, SelectOptionCellChangesetPB,
@@ -317,7 +317,9 @@ pub(crate) async fn update_cell_handler(
317317
) -> Result<(), FlowyError> {
318318
let changeset: CellChangesetPB = data.into_inner();
319319
let editor = manager.get_grid_editor(&changeset.grid_id).await?;
320-
let _ = editor.update_cell_with_changeset(changeset).await?;
320+
let _ = editor
321+
.update_cell_with_changeset(&changeset.row_id, &changeset.field_id, changeset.type_cell_data)
322+
.await?;
321323
Ok(())
322324
}
323325

@@ -344,16 +346,17 @@ pub(crate) async fn update_select_option_handler(
344346
manager: AFPluginState<Arc<GridManager>>,
345347
) -> Result<(), FlowyError> {
346348
let changeset: SelectOptionChangeset = data.into_inner().try_into()?;
347-
let editor = manager.get_grid_editor(&changeset.cell_identifier.view_id).await?;
348-
349+
let editor = manager.get_grid_editor(&changeset.cell_path.view_id).await?;
350+
let field_id = changeset.cell_path.field_id.clone();
349351
let _ = editor
350-
.modify_field_rev(&changeset.cell_identifier.field_id, |field_rev| {
352+
.modify_field_rev(&field_id, |field_rev| {
351353
let mut type_option = select_type_option_from_field_rev(field_rev)?;
352-
let mut cell_content_changeset = None;
354+
let mut cell_changeset_str = None;
353355
let mut is_changed = None;
354356

355357
for option in changeset.insert_options {
356-
cell_content_changeset = Some(SelectOptionCellChangeset::from_insert_option_id(&option.id).to_str());
358+
cell_changeset_str =
359+
Some(SelectOptionCellChangeset::from_insert_option_id(&option.id).to_cell_changeset_str());
357360
type_option.insert_option(option);
358361
is_changed = Some(());
359362
}
@@ -364,7 +367,8 @@ pub(crate) async fn update_select_option_handler(
364367
}
365368

366369
for option in changeset.delete_options {
367-
cell_content_changeset = Some(SelectOptionCellChangeset::from_delete_option_id(&option.id).to_str());
370+
cell_changeset_str =
371+
Some(SelectOptionCellChangeset::from_delete_option_id(&option.id).to_cell_changeset_str());
368372
type_option.delete_option(option);
369373
is_changed = Some(());
370374
}
@@ -373,16 +377,17 @@ pub(crate) async fn update_select_option_handler(
373377
field_rev.insert_type_option(&*type_option);
374378
}
375379

376-
if let Some(cell_content_changeset) = cell_content_changeset {
377-
let changeset = CellChangesetPB {
378-
grid_id: changeset.cell_identifier.view_id,
379-
row_id: changeset.cell_identifier.row_id,
380-
field_id: changeset.cell_identifier.field_id.clone(),
381-
type_cell_data: cell_content_changeset,
382-
};
380+
if let Some(cell_changeset_str) = cell_changeset_str {
383381
let cloned_editor = editor.clone();
384382
tokio::spawn(async move {
385-
match cloned_editor.update_cell_with_changeset(changeset).await {
383+
match cloned_editor
384+
.update_cell_with_changeset(
385+
&changeset.cell_path.row_id,
386+
&changeset.cell_path.field_id,
387+
cell_changeset_str,
388+
)
389+
.await
390+
{
386391
Ok(_) => {}
387392
Err(e) => tracing::error!("{}", e),
388393
}
@@ -432,7 +437,18 @@ pub(crate) async fn update_select_option_cell_handler(
432437
) -> Result<(), FlowyError> {
433438
let params: SelectOptionCellChangesetParams = data.into_inner().try_into()?;
434439
let editor = manager.get_grid_editor(&params.cell_identifier.view_id).await?;
435-
let _ = editor.update_cell_with_changeset(params.into()).await?;
440+
let changeset = SelectOptionCellChangeset {
441+
insert_option_ids: params.insert_option_ids,
442+
delete_option_ids: params.delete_option_ids,
443+
};
444+
445+
let _ = editor
446+
.update_cell_with_changeset(
447+
&params.cell_identifier.row_id,
448+
&params.cell_identifier.field_id,
449+
changeset,
450+
)
451+
.await?;
436452
Ok(())
437453
}
438454

@@ -443,15 +459,15 @@ pub(crate) async fn update_date_cell_handler(
443459
) -> Result<(), FlowyError> {
444460
let data = data.into_inner();
445461
let cell_path: CellPathParams = data.cell_path.try_into()?;
446-
let content = DateCellChangeset {
462+
let cell_changeset = DateCellChangeset {
447463
date: data.date,
448464
time: data.time,
449465
is_utc: data.is_utc,
450466
};
451467

452468
let editor = manager.get_grid_editor(&cell_path.view_id).await?;
453469
let _ = editor
454-
.update_cell(cell_path.view_id, cell_path.row_id, cell_path.field_id, content)
470+
.update_cell(cell_path.row_id, cell_path.field_id, cell_changeset)
455471
.await?;
456472
Ok(())
457473
}

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,13 @@ impl GridBlockRevisionEditor {
118118
}
119119

120120
pub async fn get_row_rev(&self, row_id: &str) -> FlowyResult<Option<(usize, Arc<RowRevision>)>> {
121-
let row_rev = self.pad.read().await.get_row_rev(row_id);
122-
Ok(row_rev)
121+
if self.pad.try_read().is_err() {
122+
tracing::error!("Required GridBlockRevisionPad's read lock failed");
123+
Ok(None)
124+
} else {
125+
let row_rev = self.pad.read().await.get_row_rev(row_id);
126+
Ok(row_rev)
127+
}
123128
}
124129

125130
pub async fn get_row_revs<T>(&self, row_ids: Option<Vec<Cow<'_, T>>>) -> FlowyResult<Vec<Arc<RowRevision>>>

frontend/rust-lib/flowy-grid/src/services/cell/cell_operation.rs

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ pub trait CellDataDecoder: TypeOption {
3434

3535
pub trait CellDataChangeset: TypeOption {
3636
/// The changeset is able to parse into the concrete data struct if `TypeOption::CellChangeset`
37-
/// implements the `FromCellChangeset` trait.
37+
/// implements the `FromCellChangesetString` trait.
3838
/// For example,the SelectOptionCellChangeset,DateCellChangeset. etc.
3939
///
4040
fn apply_changeset(
@@ -50,14 +50,14 @@ pub trait CellDataChangeset: TypeOption {
5050
/// FieldType::SingleSelect => SelectOptionChangeset
5151
///
5252
/// cell_rev: It will be None if the cell does not contain any data.
53-
pub fn apply_cell_data_changeset<C: ToString, T: AsRef<FieldRevision>>(
53+
pub fn apply_cell_data_changeset<C: ToCellChangesetString, T: AsRef<FieldRevision>>(
5454
changeset: C,
5555
cell_rev: Option<CellRevision>,
5656
field_rev: T,
5757
cell_data_cache: Option<AtomicCellDataCache>,
5858
) -> Result<String, FlowyError> {
5959
let field_rev = field_rev.as_ref();
60-
let changeset = changeset.to_string();
60+
let changeset = changeset.to_cell_changeset_str();
6161
let field_type: FieldType = field_rev.ty.into();
6262

6363
let type_cell_data = cell_rev.and_then(|cell_rev| match TypeCellData::try_from(cell_rev) {
@@ -108,7 +108,8 @@ pub fn decode_type_cell_data<T: TryInto<TypeCellData, Error = FlowyError> + Debu
108108
///
109109
/// # Arguments
110110
///
111-
/// * `cell_str`: the opaque cell string
111+
/// * `cell_str`: the opaque cell string that can be decoded by corresponding structs that implement the
112+
/// `FromCellString` trait.
112113
/// * `from_field_type`: the original field type of the passed-in cell data. Check the `TypeCellData`
113114
/// that is used to save the origin field type of the cell data.
114115
/// * `to_field_type`: decode the passed-in cell data to this field type. It will use the to_field_type's
@@ -155,7 +156,7 @@ pub fn insert_text_cell(s: String, field_rev: &FieldRevision) -> CellRevision {
155156
}
156157

157158
pub fn insert_number_cell(num: i64, field_rev: &FieldRevision) -> CellRevision {
158-
let data = apply_cell_data_changeset(num, None, field_rev, None).unwrap();
159+
let data = apply_cell_data_changeset(num.to_string(), None, field_rev, None).unwrap();
159160
CellRevision::new(data)
160161
}
161162

@@ -186,14 +187,14 @@ pub fn insert_date_cell(timestamp: i64, field_rev: &FieldRevision) -> CellRevisi
186187
}
187188

188189
pub fn insert_select_option_cell(option_ids: Vec<String>, field_rev: &FieldRevision) -> CellRevision {
189-
let cell_data = SelectOptionCellChangeset::from_insert_options(option_ids).to_str();
190-
let data = apply_cell_data_changeset(cell_data, None, field_rev, None).unwrap();
190+
let changeset = SelectOptionCellChangeset::from_insert_options(option_ids).to_cell_changeset_str();
191+
let data = apply_cell_data_changeset(changeset, None, field_rev, None).unwrap();
191192
CellRevision::new(data)
192193
}
193194

194195
pub fn delete_select_option_cell(option_ids: Vec<String>, field_rev: &FieldRevision) -> CellRevision {
195-
let cell_data = SelectOptionCellChangeset::from_delete_options(option_ids).to_str();
196-
let data = apply_cell_data_changeset(cell_data, None, field_rev, None).unwrap();
196+
let changeset = SelectOptionCellChangeset::from_delete_options(option_ids).to_cell_changeset_str();
197+
let data = apply_cell_data_changeset(changeset, None, field_rev, None).unwrap();
197198
CellRevision::new(data)
198199
}
199200

@@ -252,13 +253,13 @@ impl std::convert::From<IntoCellData<String>> for String {
252253

253254
/// If the changeset applying to the cell is not String type, it should impl this trait.
254255
/// Deserialize the string into cell specific changeset.
255-
pub trait FromCellChangeset {
256+
pub trait FromCellChangesetString {
256257
fn from_changeset(changeset: String) -> FlowyResult<Self>
257258
where
258259
Self: Sized;
259260
}
260261

261-
impl FromCellChangeset for String {
262+
impl FromCellChangesetString for String {
262263
fn from_changeset(changeset: String) -> FlowyResult<Self>
263264
where
264265
Self: Sized,
@@ -267,6 +268,16 @@ impl FromCellChangeset for String {
267268
}
268269
}
269270

271+
pub trait ToCellChangesetString: Debug {
272+
fn to_cell_changeset_str(&self) -> String;
273+
}
274+
275+
impl ToCellChangesetString for String {
276+
fn to_cell_changeset_str(&self) -> String {
277+
self.clone()
278+
}
279+
}
280+
270281
pub struct AnyCellChangeset<T>(pub Option<T>);
271282

272283
impl<T> AnyCellChangeset<T> {
@@ -280,7 +291,7 @@ impl<T> AnyCellChangeset<T> {
280291

281292
impl<T, C: ToString> std::convert::From<C> for AnyCellChangeset<T>
282293
where
283-
T: FromCellChangeset,
294+
T: FromCellChangesetString,
284295
{
285296
fn from(changeset: C) -> Self {
286297
match T::from_changeset(changeset.to_string()) {

frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option/date_filter.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use crate::entities::{DateFilterConditionPB, DateFilterPB};
2-
32
use chrono::NaiveDateTime;
43

54
impl DateFilterPB {

frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option/date_type_option_entities.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use crate::entities::CellPathPB;
2-
use crate::services::cell::{CellProtobufBlobParser, DecodedCellData, FromCellChangeset, FromCellString};
2+
use crate::services::cell::{
3+
CellProtobufBlobParser, DecodedCellData, FromCellChangesetString, FromCellString, ToCellChangesetString,
4+
};
35
use bytes::Bytes;
46
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
57
use flowy_error::{internal_error, FlowyResult};
@@ -33,7 +35,7 @@ pub struct DateChangesetPB {
3335
pub is_utc: bool,
3436
}
3537

36-
#[derive(Clone, Serialize, Deserialize)]
38+
#[derive(Clone, Debug, Serialize, Deserialize)]
3739
pub struct DateCellChangeset {
3840
pub date: Option<String>,
3941
pub time: Option<String>,
@@ -53,7 +55,7 @@ impl DateCellChangeset {
5355
}
5456
}
5557

56-
impl FromCellChangeset for DateCellChangeset {
58+
impl FromCellChangesetString for DateCellChangeset {
5759
fn from_changeset(changeset: String) -> FlowyResult<Self>
5860
where
5961
Self: Sized,
@@ -62,9 +64,9 @@ impl FromCellChangeset for DateCellChangeset {
6264
}
6365
}
6466

65-
impl ToString for DateCellChangeset {
66-
fn to_string(&self) -> String {
67-
serde_json::to_string(self).unwrap_or_else(|_| "".to_string())
67+
impl ToCellChangesetString for DateCellChangeset {
68+
fn to_cell_changeset_str(&self) -> String {
69+
serde_json::to_string(self).unwrap_or_default()
6870
}
6971
}
7072

0 commit comments

Comments
 (0)