Skip to content

Commit fe4e28b

Browse files
appflowyvedon
andauthored
Feat/read cell data for field (#1695)
* chore: read cells for field * feat: enable read cells for specific field * ci: fix tests Co-authored-by: vedon <[email protected]> Co-authored-by: nathan <[email protected]>
1 parent b7ba189 commit fe4e28b

File tree

9 files changed

+172
-87
lines changed

9 files changed

+172
-87
lines changed

frontend/app_flowy/pubspec.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ packages:
4242
path: "packages/appflowy_editor"
4343
relative: true
4444
source: path
45-
version: "0.0.7"
45+
version: "0.0.9"
4646
appflowy_editor_plugins:
4747
dependency: "direct main"
4848
description:
Lines changed: 56 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,73 @@
11
import 'package:app_flowy/plugins/document/document.dart';
22
import 'package:app_flowy/workspace/application/app/app_bloc.dart';
33
import 'package:app_flowy/workspace/application/view/view_bloc.dart';
4-
import 'package:bloc_test/bloc_test.dart';
54
import 'package:flutter_test/flutter_test.dart';
65

76
import '../../util.dart';
87

98
void main() {
10-
late AppFlowyUnitTest test;
9+
late AppFlowyUnitTest testContext;
1110
setUpAll(() async {
12-
test = await AppFlowyUnitTest.ensureInitialized();
11+
testContext = await AppFlowyUnitTest.ensureInitialized();
1312
});
1413

15-
group('$ViewBloc', () {
16-
late AppBloc appBloc;
14+
test('rename view test', () async {
15+
final app = await testContext.createTestApp();
16+
final appBloc = AppBloc(app: app)..add(const AppEvent.initial());
17+
appBloc.add(AppEvent.createView(
18+
"Test document",
19+
DocumentPluginBuilder(),
20+
));
21+
await blocResponseFuture();
1722

18-
setUpAll(() async {
19-
final app = await test.createTestApp();
20-
appBloc = AppBloc(app: app)..add(const AppEvent.initial());
21-
appBloc.add(AppEvent.createView(
22-
"Test document",
23-
DocumentPluginBuilder(),
24-
));
25-
await blocResponseFuture();
26-
});
23+
final viewBloc = ViewBloc(view: appBloc.state.views.first)
24+
..add(const ViewEvent.initial());
25+
viewBloc.add(const ViewEvent.rename('Hello world'));
26+
await blocResponseFuture();
2727

28-
blocTest<ViewBloc, ViewState>(
29-
"rename view",
30-
build: () => ViewBloc(view: appBloc.state.views.first)
31-
..add(const ViewEvent.initial()),
32-
act: (bloc) {
33-
bloc.add(const ViewEvent.rename('Hello world'));
34-
},
35-
wait: blocResponseDuration(),
36-
verify: (bloc) {
37-
assert(bloc.state.view.name == "Hello world");
38-
},
39-
);
28+
assert(viewBloc.state.view.name == "Hello world");
29+
});
30+
31+
test('duplicate view test', () async {
32+
final app = await testContext.createTestApp();
33+
final appBloc = AppBloc(app: app)..add(const AppEvent.initial());
34+
await blocResponseFuture();
35+
36+
appBloc.add(AppEvent.createView(
37+
"Test document",
38+
DocumentPluginBuilder(),
39+
));
40+
await blocResponseFuture();
41+
42+
final viewBloc = ViewBloc(view: appBloc.state.views.first)
43+
..add(const ViewEvent.initial());
44+
await blocResponseFuture();
45+
46+
viewBloc.add(const ViewEvent.duplicate());
47+
await blocResponseFuture();
48+
49+
assert(appBloc.state.views.length == 2);
50+
});
51+
52+
test('delete view test', () async {
53+
final app = await testContext.createTestApp();
54+
final appBloc = AppBloc(app: app)..add(const AppEvent.initial());
55+
await blocResponseFuture();
56+
57+
appBloc.add(AppEvent.createView(
58+
"Test document",
59+
DocumentPluginBuilder(),
60+
));
61+
await blocResponseFuture();
62+
assert(appBloc.state.views.length == 1);
63+
64+
final viewBloc = ViewBloc(view: appBloc.state.views.first)
65+
..add(const ViewEvent.initial());
66+
await blocResponseFuture();
4067

41-
blocTest<ViewBloc, ViewState>(
42-
"duplicate view",
43-
build: () => ViewBloc(view: appBloc.state.views.first)
44-
..add(const ViewEvent.initial()),
45-
act: (bloc) {
46-
bloc.add(const ViewEvent.duplicate());
47-
},
48-
wait: blocResponseDuration(),
49-
verify: (bloc) {
50-
assert(appBloc.state.views.length == 2);
51-
},
52-
);
68+
viewBloc.add(const ViewEvent.delete());
69+
await blocResponseFuture();
5370

54-
blocTest<ViewBloc, ViewState>(
55-
"delete view",
56-
build: () => ViewBloc(view: appBloc.state.views.first)
57-
..add(const ViewEvent.initial()),
58-
act: (bloc) {
59-
bloc.add(const ViewEvent.delete());
60-
},
61-
wait: blocResponseDuration(),
62-
verify: (bloc) {
63-
assert(appBloc.state.views.length == 1);
64-
},
65-
);
71+
assert(appBloc.state.views.isEmpty);
6672
});
6773
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ impl GridBlockManager {
228228
editor.get_row_rev(row_id).await
229229
}
230230

231+
#[allow(dead_code)]
231232
pub async fn get_row_revs(&self) -> FlowyResult<Vec<Arc<RowRevision>>> {
232233
let mut row_revs = vec![];
233234
for iter in self.block_editors.iter() {

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

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::services::cell::{
99
};
1010
use crate::services::field::{
1111
default_type_option_builder_from_type, transform_type_option, type_option_builder_from_bytes, FieldBuilder,
12-
RowSingleCellData, TypeOptionCellExt,
12+
RowSingleCellData,
1313
};
1414

1515
use crate::services::filter::FilterType;
@@ -76,6 +76,7 @@ impl GridRevisionEditor {
7676
pad: grid_pad.clone(),
7777
block_manager: block_manager.clone(),
7878
task_scheduler,
79+
cell_data_cache: cell_data_cache.clone(),
7980
});
8081

8182
// View manager
@@ -496,31 +497,10 @@ impl GridRevisionEditor {
496497
}
497498
}
498499

499-
pub async fn get_cell_data_for_field(&self, field_id: &str) -> FlowyResult<Vec<RowSingleCellData>> {
500-
let row_revs = self.block_manager.get_row_revs().await?;
501-
let field_rev = self.get_field_rev(field_id).await.unwrap();
502-
let field_type: FieldType = field_rev.ty.into();
503-
let mut cells = vec![];
504-
if let Some(handler) =
505-
TypeOptionCellExt::new_with_cell_data_cache(&field_rev, Some(self.cell_data_cache.clone()))
506-
.get_type_option_cell_data_handler(&field_type)
507-
{
508-
for row_rev in row_revs {
509-
if let Some(cell_rev) = row_rev.cells.get(field_id) {
510-
if let Ok(type_cell_data) = TypeCellData::try_from(cell_rev) {
511-
if let Ok(cell_data) = handler.get_cell_data(type_cell_data.cell_str, &field_type, &field_rev) {
512-
cells.push(RowSingleCellData {
513-
row_id: row_rev.id.clone(),
514-
field_id: field_rev.id.clone(),
515-
field_type: field_type.clone(),
516-
cell_data,
517-
})
518-
}
519-
}
520-
}
521-
}
522-
}
523-
Ok(cells)
500+
/// Returns the list of cells corresponding to the given field.
501+
pub async fn get_cells_for_field(&self, view_id: &str, field_id: &str) -> FlowyResult<Vec<RowSingleCellData>> {
502+
let view_editor = self.view_manager.get_view_editor(view_id).await?;
503+
view_editor.get_cells_for_field(field_id).await
524504
}
525505

526506
#[tracing::instrument(level = "trace", skip_all, err)]

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

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1+
use crate::entities::FieldType;
12
use crate::services::block_manager::GridBlockManager;
3+
use crate::services::cell::AtomicCellDataCache;
4+
use crate::services::field::{TypeOptionCellDataHandler, TypeOptionCellExt};
25
use crate::services::row::GridBlockRowRevision;
36
use crate::services::view_editor::GridViewEditorDelegate;
7+
48
use flowy_sync::client_grid::GridRevisionPad;
59
use flowy_task::TaskDispatcher;
610
use grid_rev_model::{FieldRevision, RowRevision};
@@ -12,6 +16,7 @@ pub(crate) struct GridViewEditorDelegateImpl {
1216
pub(crate) pad: Arc<RwLock<GridRevisionPad>>,
1317
pub(crate) block_manager: Arc<GridBlockManager>,
1418
pub(crate) task_scheduler: Arc<RwLock<TaskDispatcher>>,
19+
pub(crate) cell_data_cache: AtomicCellDataCache,
1520
}
1621

1722
impl GridViewEditorDelegate for GridViewEditorDelegateImpl {
@@ -27,7 +32,6 @@ impl GridViewEditorDelegate for GridViewEditorDelegateImpl {
2732
}
2833
})
2934
}
30-
3135
fn get_field_rev(&self, field_id: &str) -> Fut<Option<Arc<FieldRevision>>> {
3236
let pad = self.pad.clone();
3337
let field_id = field_id.to_owned();
@@ -63,6 +67,10 @@ impl GridViewEditorDelegate for GridViewEditorDelegateImpl {
6367
})
6468
}
6569

70+
// /// Returns the list of cells corresponding to the given field.
71+
// pub async fn get_cells_for_field(&self, field_id: &str) -> FlowyResult<Vec<RowSingleCellData>> {
72+
// }
73+
6674
fn get_blocks(&self) -> Fut<Vec<GridBlockRowRevision>> {
6775
let block_manager = self.block_manager.clone();
6876
to_fut(async move { block_manager.get_blocks(None).await.unwrap_or_default() })
@@ -71,4 +79,13 @@ impl GridViewEditorDelegate for GridViewEditorDelegateImpl {
7179
fn get_task_scheduler(&self) -> Arc<RwLock<TaskDispatcher>> {
7280
self.task_scheduler.clone()
7381
}
82+
83+
fn get_type_option_cell_handler(
84+
&self,
85+
field_rev: &FieldRevision,
86+
field_type: &FieldType,
87+
) -> Option<Box<dyn TypeOptionCellDataHandler>> {
88+
TypeOptionCellExt::new_with_cell_data_cache(field_rev, Some(self.cell_data_cache.clone()))
89+
.get_type_option_cell_data_handler(field_type)
90+
}
7491
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::entities::{GroupPB, GroupViewChangesetPB};
2+
use crate::services::field::RowSingleCellData;
23
use crate::services::group::{default_group_configuration, GeneratedGroupContext, Group};
34
use flowy_error::{FlowyError, FlowyResult};
45
use grid_rev_model::{
@@ -13,6 +14,7 @@ use std::sync::Arc;
1314

1415
pub trait GroupConfigurationReader: Send + Sync + 'static {
1516
fn get_configuration(&self) -> Fut<Option<Arc<GroupConfigurationRevision>>>;
17+
fn get_configuration_cells(&self, field_id: &str) -> Fut<FlowyResult<Vec<RowSingleCellData>>>;
1618
}
1719

1820
pub trait GroupConfigurationWriter: Send + Sync + 'static {
@@ -53,6 +55,11 @@ pub struct GroupContext<C> {
5355
/// Cache all the groups
5456
groups_map: IndexMap<String, Group>,
5557

58+
/// A reader that implement the [GroupConfigurationReader] trait
59+
///
60+
#[allow(dead_code)]
61+
reader: Arc<dyn GroupConfigurationReader>,
62+
5663
/// A writer that implement the [GroupConfigurationWriter] trait is used to save the
5764
/// configuration to disk
5865
///
@@ -85,6 +92,7 @@ where
8592
view_id,
8693
field_rev,
8794
groups_map: IndexMap::new(),
95+
reader,
8896
writer,
8997
configuration,
9098
configuration_phantom: PhantomData,

0 commit comments

Comments
 (0)