浏览代码

chore: add board data controller

appflowy 2 年之前
父节点
当前提交
cefd571dd0

+ 14 - 18
frontend/app_flowy/lib/plugins/board/application/board_bloc.dart

@@ -1,6 +1,5 @@
 import 'dart:async';
 import 'package:app_flowy/plugins/grid/application/block/block_cache.dart';
-import 'package:app_flowy/plugins/grid/application/grid_data_controller.dart';
 import 'package:app_flowy/plugins/grid/application/row/row_cache.dart';
 import 'package:app_flowy/plugins/grid/presentation/widgets/header/type_option/builder.dart';
 import 'package:appflowy_board/appflowy_board.dart';
@@ -14,14 +13,16 @@ import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
 import 'dart:collection';
 
+import 'board_data_controller.dart';
+
 part 'board_bloc.freezed.dart';
 
 class BoardBloc extends Bloc<BoardEvent, BoardState> {
-  final GridDataController _gridDataController;
+  final BoardDataController _dataController;
   late final AFBoardDataController boardDataController;
 
   BoardBloc({required ViewPB view})
-      : _gridDataController = GridDataController(view: view),
+      : _dataController = BoardDataController(view: view),
         super(BoardState.initial(view.id)) {
     boardDataController = AFBoardDataController(
       onMoveColumn: (
@@ -51,7 +52,7 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
             await _loadGrid(emit);
           },
           createRow: () {
-            _gridDataController.createRow();
+            _dataController.createRow();
           },
           didReceiveGridUpdate: (GridPB grid) {
             emit(state.copyWith(grid: Some(grid)));
@@ -66,39 +67,34 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
 
   @override
   Future<void> close() async {
-    await _gridDataController.dispose();
+    await _dataController.dispose();
     return super.close();
   }
 
   GridRowCache? getRowCache(String blockId, String rowId) {
-    final GridBlockCache? blockCache = _gridDataController.blocks[blockId];
+    final GridBlockCache? blockCache = _dataController.blocks[blockId];
     return blockCache?.rowCache;
   }
 
   void _startListening() {
-    _gridDataController.addListener(
+    _dataController.addListener(
       onGridChanged: (grid) {
         if (!isClosed) {
           add(BoardEvent.didReceiveGridUpdate(grid));
         }
       },
-      onRowsChanged: (rowInfos, reason) {
-        if (!isClosed) {
-          _buildColumnItems(rowInfos);
-        }
-      },
       onFieldsChanged: (fields) {
         if (!isClosed) {
           _buildColumns(fields);
         }
       },
+      onGroupChanged: (groups) {},
+      onError: (err) {
+        Log.error(err);
+      },
     );
   }
 
-  void _buildColumnItems(List<RowInfo> rowInfos) {
-    for (final rowInfo in rowInfos) {}
-  }
-
   void _buildColumns(UnmodifiableListView<FieldPB> fields) {
     FieldPB? groupField;
     for (final field in fields) {
@@ -114,7 +110,7 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
 
   void _buildColumnsFromSingleSelect(FieldPB field) {
     final typeOptionContext = makeTypeOptionContext<SingleSelectTypeOptionPB>(
-      gridId: _gridDataController.gridId,
+      gridId: _dataController.gridId,
       field: field,
     );
 
@@ -135,7 +131,7 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
   }
 
   Future<void> _loadGrid(Emitter<BoardState> emit) async {
-    final result = await _gridDataController.loadData();
+    final result = await _dataController.loadData();
     result.fold(
       (grid) => emit(
         state.copyWith(loadingState: GridLoadingState.finish(left(unit))),

+ 113 - 121
frontend/app_flowy/lib/plugins/board/application/board_data_controller.dart

@@ -1,121 +1,113 @@
-// import 'dart:collection';
-
-// import 'package:flowy_sdk/log.dart';
-// import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
-// import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
-// import 'package:flowy_sdk/protobuf/flowy-grid/block_entities.pb.dart';
-// import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
-// import 'package:flowy_sdk/protobuf/flowy-grid/grid_entities.pb.dart';
-// import 'dart:async';
-// import 'package:dartz/dartz.dart';
-
-// typedef OnFieldsChanged = void Function(UnmodifiableListView<FieldPB>);
-// typedef OnGridChanged = void Function(GridPB);
-
-
-// class ridDataController {
-//   final String gridId;
-//   final GridService _gridFFIService;
-//   final GridFieldCache fieldCache;
-
-//   // key: the block id
-//   final LinkedHashMap<String, GridBlockCache> _blocks;
-//   UnmodifiableMapView<String, GridBlockCache> get blocks =>
-//       UnmodifiableMapView(_blocks);
-
-//   OnRowsChanged? _onRowChanged;
-//   OnFieldsChanged? _onFieldsChanged;
-//   OnGridChanged? _onGridChanged;
-
-//   List<GridRowInfo> get rowInfos {
-//     final List<GridRowInfo> rows = [];
-//     for (var block in _blocks.values) {
-//       rows.addAll(block.rows);
-//     }
-//     return rows;
-//   }
-
-//   GridDataController({required ViewPB view})
-//       : gridId = view.id,
-//         _blocks = LinkedHashMap.identity(),
-//         _gridFFIService = GridService(gridId: view.id),
-//         fieldCache = GridFieldCache(gridId: view.id);
-
-//   void addListener({
-//     required OnGridChanged onGridChanged,
-//     required OnRowsChanged onRowsChanged,
-//     required OnFieldsChanged onFieldsChanged,
-//   }) {
-//     _onGridChanged = onGridChanged;
-//     _onRowChanged = onRowsChanged;
-//     _onFieldsChanged = onFieldsChanged;
-
-//     fieldCache.addListener(onFields: (fields) {
-//       _onFieldsChanged?.call(UnmodifiableListView(fields));
-//     });
-//   }
-
-//   Future<Either<Unit, FlowyError>> loadData() async {
-//     final result = await _gridFFIService.loadGrid();
-//     return Future(
-//       () => result.fold(
-//         (grid) async {
-//           _initialBlocks(grid.blocks);
-//           _onGridChanged?.call(grid);
-//           return await _loadFields(grid);
-//         },
-//         (err) => right(err),
-//       ),
-//     );
-//   }
-
-//   void createRow() {
-//     _gridFFIService.createRow();
-//   }
-
-//   Future<void> dispose() async {
-//     await _gridFFIService.closeGrid();
-//     await fieldCache.dispose();
-
-//     for (final blockCache in _blocks.values) {
-//       blockCache.dispose();
-//     }
-//   }
-
-//   void _initialBlocks(List<BlockPB> blocks) {
-//     for (final block in blocks) {
-//       if (_blocks[block.id] != null) {
-//         Log.warn("Initial duplicate block's cache: ${block.id}");
-//         return;
-//       }
-
-//       final cache = GridBlockCache(
-//         gridId: gridId,
-//         block: block,
-//         fieldCache: fieldCache,
-//       );
-
-//       cache.addListener(
-//         onChangeReason: (reason) {
-//           _onRowChanged?.call(rowInfos, reason);
-//         },
-//       );
-
-//       _blocks[block.id] = cache;
-//     }
-//   }
-
-//   Future<Either<Unit, FlowyError>> _loadFields(GridPB grid) async {
-//     final result = await _gridFFIService.getFields(fieldIds: grid.fields);
-//     return Future(
-//       () => result.fold(
-//         (fields) {
-//           fieldCache.fields = fields.items;
-//           _onFieldsChanged?.call(UnmodifiableListView(fieldCache.fields));
-//           return left(unit);
-//         },
-//         (err) => right(err),
-//       ),
-//     );
-//   }
-// }
+import 'dart:collection';
+
+import 'package:app_flowy/plugins/grid/application/block/block_cache.dart';
+import 'package:app_flowy/plugins/grid/application/field/field_cache.dart';
+import 'package:app_flowy/plugins/grid/application/grid_service.dart';
+import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
+import 'dart:async';
+import 'package:dartz/dartz.dart';
+import 'package:flowy_sdk/protobuf/flowy-grid/protobuf.dart';
+
+typedef OnFieldsChanged = void Function(UnmodifiableListView<FieldPB>);
+typedef OnGridChanged = void Function(GridPB);
+typedef OnGroupChanged = void Function(List<GroupPB>);
+typedef OnError = void Function(FlowyError);
+
+class BoardDataController {
+  final String gridId;
+  final GridService _gridFFIService;
+  final GridFieldCache fieldCache;
+
+  // key: the block id
+  final LinkedHashMap<String, GridBlockCache> _blocks;
+  UnmodifiableMapView<String, GridBlockCache> get blocks =>
+      UnmodifiableMapView(_blocks);
+
+  OnFieldsChanged? _onFieldsChanged;
+  OnGridChanged? _onGridChanged;
+  OnGroupChanged? _onGroupChanged;
+  OnError? _onError;
+
+  BoardDataController({required ViewPB view})
+      : gridId = view.id,
+        _blocks = LinkedHashMap.identity(),
+        _gridFFIService = GridService(gridId: view.id),
+        fieldCache = GridFieldCache(gridId: view.id);
+
+  void addListener({
+    OnGridChanged? onGridChanged,
+    OnFieldsChanged? onFieldsChanged,
+    OnGroupChanged? onGroupChanged,
+    OnError? onError,
+  }) {
+    _onGridChanged = onGridChanged;
+    _onFieldsChanged = onFieldsChanged;
+    _onGroupChanged = onGroupChanged;
+    _onError = onError;
+
+    fieldCache.addListener(onFields: (fields) {
+      _onFieldsChanged?.call(UnmodifiableListView(fields));
+    });
+  }
+
+  Future<Either<Unit, FlowyError>> loadData() async {
+    final result = await _gridFFIService.loadGrid();
+    return Future(
+      () => result.fold(
+        (grid) async {
+          _onGridChanged?.call(grid);
+          return await _loadFields(grid).then((result) {
+            return result.fold(
+              (l) {
+                _loadGroups();
+                return left(l);
+              },
+              (err) => right(err),
+            );
+          });
+        },
+        (err) => right(err),
+      ),
+    );
+  }
+
+  void createRow() {
+    _gridFFIService.createRow();
+  }
+
+  Future<void> dispose() async {
+    await _gridFFIService.closeGrid();
+    await fieldCache.dispose();
+
+    for (final blockCache in _blocks.values) {
+      blockCache.dispose();
+    }
+  }
+
+  Future<Either<Unit, FlowyError>> _loadFields(GridPB grid) async {
+    final result = await _gridFFIService.getFields(fieldIds: grid.fields);
+    return Future(
+      () => result.fold(
+        (fields) {
+          fieldCache.fields = fields.items;
+          _onFieldsChanged?.call(UnmodifiableListView(fieldCache.fields));
+          return left(unit);
+        },
+        (err) => right(err),
+      ),
+    );
+  }
+
+  Future<void> _loadGroups() async {
+    final result = await _gridFFIService.loadGroups();
+    return Future(
+      () => result.fold(
+        (groups) {
+          _onGroupChanged?.call(groups.items);
+        },
+        (err) => _onError?.call(err),
+      ),
+    );
+  }
+}

+ 1 - 1
frontend/app_flowy/lib/plugins/board/board.dart

@@ -31,7 +31,7 @@ class BoardPluginBuilder implements PluginBuilder {
 
 class BoardPluginConfig implements PluginConfig {
   @override
-  bool get creatable => true;
+  bool get creatable => false;
 }
 
 class BoardPlugin extends Plugin {

+ 1 - 1
frontend/app_flowy/lib/plugins/board/presentation/card.dart

@@ -8,6 +8,6 @@ class BoardCard extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
-    return Container(child: Text('1234'));
+    return const Text('1234');
   }
 }

+ 0 - 3
frontend/app_flowy/lib/plugins/grid/application/field/field_service.dart

@@ -1,13 +1,10 @@
 import 'package:dartz/dartz.dart';
-import 'package:flowy_infra/notifier.dart';
 import 'package:flowy_sdk/dispatch/dispatch.dart';
-import 'package:flowy_sdk/log.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/grid_entities.pb.dart';
 import 'package:flutter/foundation.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
-import 'package:protobuf/protobuf.dart';
 part 'field_service.freezed.dart';
 
 /// FieldService consists of lots of event functions. We define the events in the backend(Rust),

+ 1 - 1
frontend/app_flowy/lib/plugins/grid/application/field/type_option/select_option_type_option_bloc.dart

@@ -75,7 +75,7 @@ class SelectOptionTypeOptionState with _$SelectOptionTypeOptionState {
     required List<SelectOptionPB> options,
     required bool isEditingOption,
     required Option<String> newOptionName,
-  }) = _SelectOptionTyepOptionState;
+  }) = _SelectOptionTypeOptionState;
 
   factory SelectOptionTypeOptionState.initial(List<SelectOptionPB> options) =>
       SelectOptionTypeOptionState(

+ 1 - 1
frontend/app_flowy/lib/plugins/grid/application/grid_data_controller.dart

@@ -20,7 +20,7 @@ typedef OnRowsChanged = void Function(
   List<RowInfo> rowInfos,
   RowChangeReason,
 );
-typedef ListenONRowChangedCondition = bool Function();
+typedef ListenOnRowChangedCondition = bool Function();
 
 class GridDataController {
   final String gridId;

+ 6 - 0
frontend/app_flowy/lib/plugins/grid/application/grid_service.dart

@@ -5,6 +5,7 @@ import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/block_entities.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/grid_entities.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-grid/group.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/row_entities.pb.dart';
 
 class GridService {
@@ -38,4 +39,9 @@ class GridService {
     final request = ViewIdPB(value: gridId);
     return FolderEventCloseView(request).send();
   }
+
+  Future<Either<RepeatedGridGroupPB, FlowyError>> loadGroups() {
+    final payload = GridIdPB(value: gridId);
+    return GridEventGetGroup(payload).send();
+  }
 }

+ 0 - 2
frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/builder.dart

@@ -1,6 +1,5 @@
 import 'dart:typed_data';
 
-import 'package:app_flowy/plugins/grid/application/field/type_option/multi_select_type_option.dart';
 import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart';
 import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_data_controller.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/checkbox_type_option.pb.dart';
@@ -11,7 +10,6 @@ import 'package:flowy_sdk/protobuf/flowy-grid/single_select_type_option.pb.dart'
 import 'package:flowy_sdk/protobuf/flowy-grid/text_type_option.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/url_type_option.pb.dart';
 import 'package:protobuf/protobuf.dart';
-import 'package:app_flowy/plugins/grid/application/prelude.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
 import 'package:flutter/material.dart';
 import 'checkbox.dart';

+ 1 - 1
frontend/rust-lib/flowy-folder/src/services/view/controller.rs

@@ -1,5 +1,5 @@
 pub use crate::entities::view::ViewDataTypePB;
-use crate::entities::{SubViewDataTypePB, ViewInfoPB};
+use crate::entities::ViewInfoPB;
 use crate::manager::{ViewDataProcessor, ViewDataProcessorMap};
 use crate::{
     dart_notification::{send_dart_notification, FolderNotification},

+ 1 - 0
frontend/rust-lib/flowy-folder/tests/workspace/script.rs

@@ -359,6 +359,7 @@ pub async fn create_view(
         desc: desc.to_string(),
         thumbnail: None,
         data_type,
+        sub_data_type: None,
         plugin_type: 0,
         data: vec![],
     };

+ 1 - 1
frontend/rust-lib/flowy-grid/src/entities/group_entities/group.rs

@@ -32,7 +32,7 @@ impl std::convert::From<&GridGroupRevision> for GridGroupConfigurationPB {
 #[derive(ProtoBuf, Debug, Default, Clone)]
 pub struct RepeatedGridGroupPB {
     #[pb(index = 1)]
-    groups: Vec<GroupPB>,
+    items: Vec<GroupPB>,
 }
 
 #[derive(ProtoBuf, Debug, Default, Clone)]

+ 1 - 1
frontend/rust-lib/flowy-grid/src/entities/setting_entities.rs

@@ -6,7 +6,7 @@ use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
 use flowy_error::ErrorCode;
 use flowy_grid_data_model::parser::NotEmptyStr;
 use flowy_grid_data_model::revision::GridLayoutRevision;
-use flowy_sync::entities::grid::{DeleteGroupParams, GridSettingChangesetParams};
+use flowy_sync::entities::grid::GridSettingChangesetParams;
 use std::collections::HashMap;
 use std::convert::TryInto;
 use strum::IntoEnumIterator;

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

@@ -35,6 +35,8 @@ pub struct GridRevisionEditor {
     block_manager: Arc<GridBlockManager>,
     #[allow(dead_code)]
     pub(crate) filter_service: Arc<GridFilterService>,
+
+    #[allow(dead_code)]
     pub(crate) group_service: Arc<GridGroupService>,
 }
 

+ 3 - 0
frontend/rust-lib/flowy-grid/src/services/group/group_service.rs

@@ -5,8 +5,11 @@ use std::sync::Arc;
 use tokio::sync::RwLock;
 
 pub(crate) struct GridGroupService {
+    #[allow(dead_code)]
     scheduler: Arc<dyn GridServiceTaskScheduler>,
+    #[allow(dead_code)]
     grid_pad: Arc<RwLock<GridRevisionPad>>,
+    #[allow(dead_code)]
     block_manager: Arc<GridBlockManager>,
 }
 

+ 1 - 1
frontend/rust-lib/flowy-grid/src/services/group/mod.rs

@@ -1,3 +1,3 @@
 mod group_service;
 
-pub use group_service::*;
+pub(crate) use group_service::*;

+ 1 - 3
frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs

@@ -50,18 +50,16 @@ impl<'a> RowRevisionBuilder<'a> {
         }
     }
 
-    pub fn insert_select_option_cell(mut self, field_id: &str, data: String) -> Self {
+    pub fn insert_select_option_cell(&mut self, field_id: &str, data: String) {
         match self.field_rev_map.get(&field_id.to_owned()) {
             None => {
                 tracing::warn!("Invalid field_id: {}", field_id);
-                self
             }
             Some(field_rev) => {
                 let cell_data = SelectOptionCellChangeset::from_insert(&data).to_str();
                 let data = apply_cell_data_changeset(cell_data, None, field_rev).unwrap();
                 let cell = CellRevision::new(data);
                 self.payload.cell_by_field_id.insert(field_id.to_owned(), cell);
-                self
             }
         }
     }

+ 7 - 8
frontend/rust-lib/flowy-grid/src/util.rs

@@ -48,19 +48,18 @@ pub fn make_default_board() -> BuildGridContext {
     let done_option = SelectOptionPB::new("Done");
     let single_select = SingleSelectTypeOptionBuilder::default()
         .add_option(not_started_option.clone())
-        .add_option(in_progress_option.clone())
-        .add_option(done_option.clone());
+        .add_option(in_progress_option)
+        .add_option(done_option);
     let single_select_field = FieldBuilder::new(single_select).name("Status").visibility(true).build();
     let single_select_field_id = single_select_field.id.clone();
     grid_builder.add_field(single_select_field);
 
-    // rows
+    // Insert rows
     for _ in 0..3 {
-        grid_builder.add_row(
-            RowRevisionBuilder::new(grid_builder.block_id(), grid_builder.field_revs())
-                .insert_select_option_cell(&single_select_field_id, not_started_option.id.clone())
-                .build(),
-        );
+        let mut row_builder = RowRevisionBuilder::new(grid_builder.block_id(), grid_builder.field_revs());
+        row_builder.insert_select_option_cell(&single_select_field_id, not_started_option.id.clone());
+        let row = row_builder.build();
+        grid_builder.add_row(row);
     }
 
     grid_builder.build()

+ 0 - 2
frontend/rust-lib/flowy-grid/tests/grid/block_test/util.rs

@@ -10,7 +10,6 @@ use flowy_grid_data_model::revision::{FieldRevision, RowRevision};
 use strum::EnumCount;
 
 pub struct GridRowTestBuilder<'a> {
-    block_id: String,
     field_revs: &'a [Arc<FieldRevision>],
     inner_builder: RowRevisionBuilder<'a>,
 }
@@ -20,7 +19,6 @@ impl<'a> GridRowTestBuilder<'a> {
         assert_eq!(field_revs.len(), FieldType::COUNT);
         let inner_builder = RowRevisionBuilder::new(block_id, field_revs);
         Self {
-            block_id: block_id.to_owned(),
             field_revs,
             inner_builder,
         }