ソースを参照

chore: create board card

appflowy 2 年 前
コミット
bc346dfd67
20 ファイル変更240 行追加98 行削除
  1. 46 11
      frontend/app_flowy/lib/plugins/board/application/board_bloc.dart
  2. 5 5
      frontend/app_flowy/lib/plugins/board/application/board_data_controller.dart
  3. 49 0
      frontend/app_flowy/lib/plugins/board/application/group_controller.dart
  4. 51 0
      frontend/app_flowy/lib/plugins/board/application/group_listener.dart
  5. 1 1
      frontend/app_flowy/lib/plugins/board/presentation/board_page.dart
  6. 2 2
      frontend/app_flowy/lib/plugins/grid/application/grid_service.dart
  7. 2 2
      frontend/app_flowy/lib/plugins/grid/application/row/row_service.dart
  8. 2 2
      frontend/app_flowy/packages/appflowy_board/lib/src/widgets/board.dart
  9. 2 2
      frontend/app_flowy/packages/appflowy_board/lib/src/widgets/board_column/board_column.dart
  10. 1 1
      frontend/app_flowy/packages/appflowy_board/lib/src/widgets/board_data.dart
  11. 5 5
      frontend/app_flowy/packages/appflowy_board/lib/src/widgets/reorder_flex/drag_target.dart
  12. 3 3
      frontend/app_flowy/packages/appflowy_board/lib/src/widgets/reorder_flex/drag_target_interceptor.dart
  13. 8 8
      frontend/app_flowy/packages/appflowy_board/lib/src/widgets/reorder_flex/reorder_flex.dart
  14. 5 4
      frontend/app_flowy/packages/appflowy_board/lib/src/widgets/reorder_phantom/phantom_controller.dart
  15. 1 1
      frontend/rust-lib/flowy-grid/src/dart_notification.rs
  16. 1 41
      frontend/rust-lib/flowy-grid/src/entities/group_entities/board_card.rs
  17. 43 0
      frontend/rust-lib/flowy-grid/src/entities/group_entities/group_changeset.rs
  18. 2 0
      frontend/rust-lib/flowy-grid/src/entities/group_entities/mod.rs
  19. 9 6
      frontend/rust-lib/flowy-grid/src/services/grid_view_editor.rs
  20. 2 4
      frontend/rust-lib/flowy-grid/src/services/group/group_service.rs

+ 46 - 11
frontend/app_flowy/lib/plugins/board/application/board_bloc.dart

@@ -14,12 +14,14 @@ import 'package:freezed_annotation/freezed_annotation.dart';
 import 'dart:collection';
 
 import 'board_data_controller.dart';
+import 'group_controller.dart';
 
 part 'board_bloc.freezed.dart';
 
 class BoardBloc extends Bloc<BoardEvent, BoardState> {
   final BoardDataController _dataController;
-  late final AFBoardDataController boardDataController;
+  late final AFBoardDataController afBoardDataController;
+  List<GroupController> groupControllers = [];
 
   GridFieldCache get fieldCache => _dataController.fieldCache;
   String get gridId => _dataController.gridId;
@@ -27,7 +29,7 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
   BoardBloc({required ViewPB view})
       : _dataController = BoardDataController(view: view),
         super(BoardState.initial(view.id)) {
-    boardDataController = AFBoardDataController(
+    afBoardDataController = AFBoardDataController(
       onMoveColumn: (
         fromIndex,
         toIndex,
@@ -71,9 +73,6 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
           didReceiveGridUpdate: (GridPB grid) {
             emit(state.copyWith(grid: Some(grid)));
           },
-          didReceiveGroups: (List<GroupPB> groups) {
-            emit(state.copyWith(groups: groups));
-          },
           didReceiveRows: (List<RowInfo> rowInfos) {
             emit(state.copyWith(rowInfos: rowInfos));
           },
@@ -85,9 +84,24 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
   @override
   Future<void> close() async {
     await _dataController.dispose();
+    for (final controller in groupControllers) {
+      controller.dispose();
+    }
     return super.close();
   }
 
+  void initializeGroups(List<GroupPB> groups) {
+    for (final group in groups) {
+      final delegate = GroupControllerDelegateImpl(afBoardDataController);
+      final controller = GroupController(
+        group: group,
+        delegate: delegate,
+      );
+      controller.startListening();
+      groupControllers.add(controller);
+    }
+  }
+
   GridRowCache? getRowCache(String blockId) {
     final GridBlockCache? blockCache = _dataController.blocks[blockId];
     return blockCache?.rowCache;
@@ -100,7 +114,7 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
           add(BoardEvent.didReceiveGridUpdate(grid));
         }
       },
-      onGroupChanged: (groups) {
+      didLoadGroups: (groups) {
         List<AFBoardColumnData> columns = groups.map((group) {
           return AFBoardColumnData(
             id: group.groupId,
@@ -110,7 +124,8 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
           );
         }).toList();
 
-        boardDataController.addColumns(columns);
+        afBoardDataController.addColumns(columns);
+        initializeGroups(groups);
       },
       onRowsChanged: (List<RowInfo> rowInfos, RowsChangedReason reason) {
         add(BoardEvent.didReceiveRows(rowInfos));
@@ -155,8 +170,6 @@ class BoardEvent with _$BoardEvent {
   const factory BoardEvent.initial() = InitialGrid;
   const factory BoardEvent.createRow(String groupId) = _CreateRow;
   const factory BoardEvent.endEditRow(String rowId) = _EndEditRow;
-  const factory BoardEvent.didReceiveGroups(List<GroupPB> groups) =
-      _DidReceiveGroup;
   const factory BoardEvent.didReceiveRows(List<RowInfo> rowInfos) =
       _DidReceiveRows;
   const factory BoardEvent.didReceiveGridUpdate(
@@ -169,7 +182,6 @@ class BoardState with _$BoardState {
   const factory BoardState({
     required String gridId,
     required Option<GridPB> grid,
-    required List<GroupPB> groups,
     required Option<RowPB> editingRow,
     required List<RowInfo> rowInfos,
     required GridLoadingState loadingState,
@@ -177,7 +189,6 @@ class BoardState with _$BoardState {
 
   factory BoardState.initial(String gridId) => BoardState(
         rowInfos: [],
-        groups: [],
         grid: none(),
         gridId: gridId,
         editingRow: none(),
@@ -228,3 +239,27 @@ class CreateCardItem extends AFColumnItem {
   @override
   String get id => '$CreateCardItem';
 }
+
+class GroupControllerDelegateImpl extends GroupControllerDelegate {
+  final AFBoardDataController controller;
+
+  GroupControllerDelegateImpl(this.controller);
+
+  @override
+  void insertRow(String groupId, RowPB row, int? index) {
+    final item = BoardColumnItem(row: row);
+    if (index != null) {
+      controller.insertColumnItem(groupId, index, item);
+    } else {
+      controller.addColumnItem(groupId, item);
+    }
+  }
+
+  @override
+  void removeRow(String groupId, String rowId) {
+    controller.removeColumnItem(groupId, rowId);
+  }
+
+  @override
+  void updateRow(String groupId, RowPB row) {}
+}

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

@@ -12,7 +12,7 @@ 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 DidLoadGroups = void Function(List<GroupPB>);
 typedef OnRowsChanged = void Function(
   List<RowInfo>,
   RowsChangedReason,
@@ -30,7 +30,7 @@ class BoardDataController {
 
   OnFieldsChanged? _onFieldsChanged;
   OnGridChanged? _onGridChanged;
-  OnGroupChanged? _onGroupChanged;
+  DidLoadGroups? _didLoadGroup;
   OnRowsChanged? _onRowsChanged;
   OnError? _onError;
 
@@ -51,13 +51,13 @@ class BoardDataController {
   void addListener({
     OnGridChanged? onGridChanged,
     OnFieldsChanged? onFieldsChanged,
-    OnGroupChanged? onGroupChanged,
+    DidLoadGroups? didLoadGroups,
     OnRowsChanged? onRowsChanged,
     OnError? onError,
   }) {
     _onGridChanged = onGridChanged;
     _onFieldsChanged = onFieldsChanged;
-    _onGroupChanged = onGroupChanged;
+    _didLoadGroup = didLoadGroups;
     _onRowsChanged = onRowsChanged;
     _onError = onError;
 
@@ -133,7 +133,7 @@ class BoardDataController {
     return Future(
       () => result.fold(
         (groups) {
-          _onGroupChanged?.call(groups.items);
+          _didLoadGroup?.call(groups.items);
         },
         (err) => _onError?.call(err),
       ),

+ 49 - 0
frontend/app_flowy/lib/plugins/board/application/group_controller.dart

@@ -0,0 +1,49 @@
+import 'package:flowy_sdk/log.dart';
+import 'package:flowy_sdk/protobuf/flowy-grid/protobuf.dart';
+
+import 'group_listener.dart';
+
+abstract class GroupControllerDelegate {
+  void removeRow(String groupId, String rowId);
+  void insertRow(String groupId, RowPB row, int? index);
+  void updateRow(String groupId, RowPB row);
+}
+
+class GroupController {
+  final GroupPB group;
+  final GroupListener _listener;
+  final GroupControllerDelegate delegate;
+
+  GroupController({required this.group, required this.delegate})
+      : _listener = GroupListener(group);
+
+  void startListening() {
+    _listener.start(onGroupChanged: (result) {
+      result.fold(
+        (GroupRowsChangesetPB changeset) {
+          for (final insertedRow in changeset.insertedRows) {
+            final index = insertedRow.hasIndex() ? insertedRow.index : null;
+            delegate.insertRow(
+              group.groupId,
+              insertedRow.row,
+              index,
+            );
+          }
+
+          for (final deletedRow in changeset.deletedRows) {
+            delegate.removeRow(group.groupId, deletedRow);
+          }
+
+          for (final updatedRow in changeset.updatedRows) {
+            delegate.updateRow(group.groupId, updatedRow);
+          }
+        },
+        (err) => Log.error(err),
+      );
+    });
+  }
+
+  Future<void> dispose() async {
+    _listener.stop();
+  }
+}

+ 51 - 0
frontend/app_flowy/lib/plugins/board/application/group_listener.dart

@@ -0,0 +1,51 @@
+import 'dart:typed_data';
+
+import 'package:app_flowy/core/grid_notification.dart';
+import 'package:flowy_infra/notifier.dart';
+import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-grid/group.pb.dart';
+import 'package:dartz/dartz.dart';
+import 'package:flowy_sdk/protobuf/flowy-grid/group_changeset.pb.dart';
+
+typedef UpdateGroupNotifiedValue = Either<GroupRowsChangesetPB, FlowyError>;
+
+class GroupListener {
+  final GroupPB group;
+  PublishNotifier<UpdateGroupNotifiedValue>? _groupNotifier = PublishNotifier();
+  GridNotificationListener? _listener;
+  GroupListener(this.group);
+
+  void start({
+    required void Function(UpdateGroupNotifiedValue) onGroupChanged,
+  }) {
+    _groupNotifier?.addPublishListener(onGroupChanged);
+    _listener = GridNotificationListener(
+      objectId: group.groupId,
+      handler: _handler,
+    );
+  }
+
+  void _handler(
+    GridNotification ty,
+    Either<Uint8List, FlowyError> result,
+  ) {
+    switch (ty) {
+      case GridNotification.DidUpdateGroup:
+        result.fold(
+          (payload) => _groupNotifier?.value =
+              left(GroupRowsChangesetPB.fromBuffer(payload)),
+          (error) => _groupNotifier?.value = right(error),
+        );
+        break;
+      default:
+        break;
+    }
+  }
+
+  Future<void> stop() async {
+    await _listener?.stop();
+    _groupNotifier?.dispose();
+    _groupNotifier = null;
+  }
+}

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

@@ -55,7 +55,7 @@ class BoardContent extends StatelessWidget {
             child: AFBoard(
               // key: UniqueKey(),
               scrollController: ScrollController(),
-              dataController: context.read<BoardBloc>().boardDataController,
+              dataController: context.read<BoardBloc>().afBoardDataController,
               headerBuilder: _buildHeader,
               footBuilder: _buildFooter,
               cardBuilder: (_, data) => _buildCard(context, data),

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

@@ -23,9 +23,9 @@ class GridFFIService {
   }
 
   Future<Either<RowPB, FlowyError>> createRow({Option<String>? startRowId}) {
-    CreateRowPayloadPB payload = CreateRowPayloadPB.create()..gridId = gridId;
+    var payload = CreateTableRowPayloadPB.create()..gridId = gridId;
     startRowId?.fold(() => null, (id) => payload.startRowId = id);
-    return GridEventCreateRow(payload).send();
+    return GridEventCreateTableRow(payload).send();
   }
 
   Future<Either<RowPB, FlowyError>> createBoardCard(String groupId) {

+ 2 - 2
frontend/app_flowy/lib/plugins/grid/application/row/row_service.dart

@@ -15,11 +15,11 @@ class RowFFIService {
       {required this.gridId, required this.blockId, required this.rowId});
 
   Future<Either<RowPB, FlowyError>> createRow() {
-    CreateRowPayloadPB payload = CreateRowPayloadPB.create()
+    final payload = CreateTableRowPayloadPB.create()
       ..gridId = gridId
       ..startRowId = rowId;
 
-    return GridEventCreateRow(payload).send();
+    return GridEventCreateTableRow(payload).send();
   }
 
   Future<Either<Unit, FlowyError>> moveRow({

+ 2 - 2
frontend/app_flowy/packages/appflowy_board/lib/src/widgets/board.dart

@@ -3,7 +3,7 @@ import 'package:provider/provider.dart';
 import 'board_column/board_column.dart';
 import 'board_column/board_column_data.dart';
 import 'board_data.dart';
-import 'reorder_flex/drag_target_inteceptor.dart';
+import 'reorder_flex/drag_target_interceptor.dart';
 import 'reorder_flex/reorder_flex.dart';
 import 'reorder_phantom/phantom_controller.dart';
 import '../rendering/board_overlay.dart';
@@ -143,7 +143,7 @@ class _BoardContentState extends State<BoardContent> {
   void initState() {
     _overlayEntry = BoardOverlayEntry(
       builder: (BuildContext context) {
-        final interceptor = OverlappingDragTargetInteceptor(
+        final interceptor = OverlappingDragTargetInterceptor(
           reorderFlexId: widget.dataController.identifier,
           acceptedReorderFlexId: widget.dataController.columnIds,
           delegate: widget.delegate,

+ 2 - 2
frontend/app_flowy/packages/appflowy_board/lib/src/widgets/board_column/board_column.dart

@@ -5,7 +5,7 @@ import '../../rendering/board_overlay.dart';
 import '../../utils/log.dart';
 import '../reorder_phantom/phantom_controller.dart';
 import '../reorder_flex/reorder_flex.dart';
-import '../reorder_flex/drag_target_inteceptor.dart';
+import '../reorder_flex/drag_target_interceptor.dart';
 import 'board_column_data.dart';
 
 typedef OnColumnDragStarted = void Function(int index);
@@ -37,7 +37,7 @@ typedef AFBoardColumnFooterBuilder = Widget Function(
   AFBoardColumnData columnData,
 );
 
-abstract class AFBoardColumnDataDataSource extends ReoderFlextDataSource {
+abstract class AFBoardColumnDataDataSource extends ReoderFlexDataSource {
   AFBoardColumnData get columnData;
 
   List<String> get acceptedColumnIds;

+ 1 - 1
frontend/app_flowy/packages/appflowy_board/lib/src/widgets/board_data.dart

@@ -24,7 +24,7 @@ typedef OnMoveColumnItemToColumn = void Function(
 );
 
 class AFBoardDataController extends ChangeNotifier
-    with EquatableMixin, BoardPhantomControllerDelegate, ReoderFlextDataSource {
+    with EquatableMixin, BoardPhantomControllerDelegate, ReoderFlexDataSource {
   final List<AFBoardColumnData> _columnDatas = [];
   final OnMoveColumn? onMoveColumn;
   final OnMoveColumnItem? onMoveColumnItem;

+ 5 - 5
frontend/app_flowy/packages/appflowy_board/lib/src/widgets/reorder_flex/drag_target.dart

@@ -13,14 +13,14 @@ abstract class ReorderFlexDraggableTargetBuilder {
     Widget child,
     DragTargetOnStarted onDragStarted,
     DragTargetOnEnded<T> onDragEnded,
-    DragTargetWillAccpet<T> onWillAccept,
+    DragTargetWillAccepted<T> onWillAccept,
     AnimationController insertAnimationController,
     AnimationController deleteAnimationController,
   );
 }
 
 ///
-typedef DragTargetWillAccpet<T extends DragTargetData> = bool Function(
+typedef DragTargetWillAccepted<T extends DragTargetData> = bool Function(
     T dragTargetData);
 
 ///
@@ -51,7 +51,7 @@ class ReorderDragTarget<T extends DragTargetData> extends StatefulWidget {
   ///
   /// [toAccept] represents the dragTarget index, which is the value passed in
   /// when creating the [ReorderDragTarget].
-  final DragTargetWillAccpet<T> onWillAccept;
+  final DragTargetWillAccepted<T> onWillAccept;
 
   /// Called when an acceptable piece of data was dropped over this drag target.
   ///
@@ -228,7 +228,7 @@ class DragTargetAnimation {
         value: 0.0, vsync: vsync, duration: const Duration(milliseconds: 10));
   }
 
-  void startDargging() {
+  void startDragging() {
     entranceController.value = 1.0;
   }
 
@@ -386,7 +386,7 @@ class FakeDragTarget<T extends DragTargetData> extends StatefulWidget {
   final FakeDragTargetEventData eventData;
   final DragTargetOnStarted onDragStarted;
   final DragTargetOnEnded<T> onDragEnded;
-  final DragTargetWillAccpet<T> onWillAccept;
+  final DragTargetWillAccepted<T> onWillAccept;
   final Widget child;
   final AnimationController insertAnimationController;
   final AnimationController deleteAnimationController;

+ 3 - 3
frontend/app_flowy/packages/appflowy_board/lib/src/widgets/reorder_flex/drag_target_inteceptor.dart → frontend/app_flowy/packages/appflowy_board/lib/src/widgets/reorder_flex/drag_target_interceptor.dart

@@ -40,18 +40,18 @@ abstract class OverlapDragTargetDelegate {
   bool canMoveTo(String dragTargetId);
 }
 
-/// [OverlappingDragTargetInteceptor] is used to receive the overlapping
+/// [OverlappingDragTargetInterceptor] is used to receive the overlapping
 /// [DragTarget] event. If a [DragTarget] child is [DragTarget], it will
 /// receive the [DragTarget] event when being dragged.
 ///
 /// Receive the [DragTarget] event if the [acceptedReorderFlexId] contains
 /// the passed in dragTarget' reorderFlexId.
-class OverlappingDragTargetInteceptor extends DragTargetInterceptor {
+class OverlappingDragTargetInterceptor extends DragTargetInterceptor {
   final String reorderFlexId;
   final List<String> acceptedReorderFlexId;
   final OverlapDragTargetDelegate delegate;
 
-  OverlappingDragTargetInteceptor({
+  OverlappingDragTargetInterceptor({
     required this.delegate,
     required this.reorderFlexId,
     required this.acceptedReorderFlexId,

+ 8 - 8
frontend/app_flowy/packages/appflowy_board/lib/src/widgets/reorder_flex/reorder_flex.dart

@@ -7,25 +7,25 @@ import '../../utils/log.dart';
 import 'reorder_mixin.dart';
 import 'drag_target.dart';
 import 'drag_state.dart';
-import 'drag_target_inteceptor.dart';
+import 'drag_target_interceptor.dart';
 
 typedef OnDragStarted = void Function(int index);
 typedef OnDragEnded = void Function();
 typedef OnReorder = void Function(int fromIndex, int toIndex);
 typedef OnDeleted = void Function(int deletedIndex);
 typedef OnInserted = void Function(int insertedIndex);
-typedef OnReveivePassedInPhantom = void Function(
+typedef OnReceivePassedInPhantom = void Function(
     FlexDragTargetData dragTargetData, int phantomIndex);
 
-abstract class ReoderFlextDataSource {
+abstract class ReoderFlexDataSource {
   /// [identifier] represents the id the [ReorderFlex]. It must be unique.
   String get identifier;
 
-  /// The number of [ReoderFlexItem]s will be displaied in the [ReorderFlex].
+  /// The number of [ReoderFlexItem]s will be displayed in the [ReorderFlex].
   UnmodifiableListView<ReoderFlexItem> get items;
 }
 
-/// Each item displaied in the [ReorderFlex] required to implement the [ReoderFlexItem].
+/// Each item displayed in the [ReorderFlex] required to implement the [ReoderFlexItem].
 abstract class ReoderFlexItem {
   /// [id] is used to identify the item. It must be unique.
   String get id;
@@ -70,7 +70,7 @@ class ReorderFlex extends StatefulWidget {
   /// [onDragEnded] is called when dragTarget did end dragging
   final OnDragEnded? onDragEnded;
 
-  final ReoderFlextDataSource dataSource;
+  final ReoderFlexDataSource dataSource;
 
   final DragTargetInterceptor? interceptor;
 
@@ -187,7 +187,7 @@ class ReorderFlexState extends State<ReorderFlex>
   void _requestAnimationToNextIndex({bool isAcceptingNewTarget = false}) {
     /// Update the dragState and animate to the next index if the current
     /// dragging animation is completed. Otherwise, it will get called again
-    /// when the animation finishs.
+    /// when the animation finish.
 
     if (_animation.entranceController.isCompleted) {
       dragState.removePhantom();
@@ -425,7 +425,7 @@ class ReorderFlexState extends State<ReorderFlex>
   ) {
     setState(() {
       dragState.startDragging(draggingWidget, dragIndex, feedbackSize);
-      _animation.startDargging();
+      _animation.startDragging();
     });
   }
 

+ 5 - 4
frontend/app_flowy/packages/appflowy_board/lib/src/widgets/reorder_phantom/phantom_controller.dart

@@ -1,9 +1,10 @@
-import 'package:flutter/material.dart';
+import 'package:flutter/widgets.dart';
+
 import '../../utils/log.dart';
 import '../board_column/board_column_data.dart';
 import '../reorder_flex/drag_state.dart';
 import '../reorder_flex/drag_target.dart';
-import '../reorder_flex/drag_target_inteceptor.dart';
+import '../reorder_flex/drag_target_interceptor.dart';
 import 'phantom_state.dart';
 
 abstract class BoardPhantomControllerDelegate {
@@ -61,7 +62,7 @@ class BoardPhantomController extends OverlapDragTargetDelegate
     columnsState.setColumnIsDragging(columnId, false);
   }
 
-  /// Remove the phanton in the column when the column is end dragging.
+  /// Remove the phantom in the column when the column is end dragging.
   void columnEndDragging(String columnId) {
     columnsState.setColumnIsDragging(columnId, true);
     if (phantomRecord == null) return;
@@ -331,7 +332,7 @@ class PhantomDraggableBuilder extends ReorderFlexDraggableTargetBuilder {
     Widget child,
     DragTargetOnStarted onDragStarted,
     DragTargetOnEnded<T> onDragEnded,
-    DragTargetWillAccpet<T> onWillAccept,
+    DragTargetWillAccepted<T> onWillAccept,
     AnimationController insertAnimationController,
     AnimationController deleteAnimationController,
   ) {

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

@@ -11,7 +11,7 @@ pub enum GridNotification {
     DidUpdateRow = 30,
     DidUpdateCell = 40,
     DidUpdateField = 50,
-    DidUpdateBoard = 60,
+    DidUpdateGroup = 60,
 }
 
 impl std::default::Default for GridNotification {

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

@@ -1,4 +1,4 @@
-use crate::entities::{CreateRowParams, GridLayout, RowPB};
+use crate::entities::{CreateRowParams, GridLayout};
 use flowy_derive::ProtoBuf;
 use flowy_error::ErrorCode;
 use flowy_grid_data_model::parser::NotEmptyStr;
@@ -26,43 +26,3 @@ impl TryInto<CreateRowParams> for CreateBoardCardPayloadPB {
         })
     }
 }
-
-#[derive(Debug, Default, ProtoBuf)]
-pub struct GroupRowsChangesetPB {
-    #[pb(index = 1)]
-    pub group_id: String,
-
-    #[pb(index = 2)]
-    pub inserted_rows: Vec<RowPB>,
-
-    #[pb(index = 3)]
-    pub deleted_rows: Vec<String>,
-
-    #[pb(index = 4)]
-    pub updated_rows: Vec<RowPB>,
-}
-impl GroupRowsChangesetPB {
-    pub fn insert(group_id: String, inserted_rows: Vec<RowPB>) -> Self {
-        Self {
-            group_id,
-            inserted_rows,
-            ..Default::default()
-        }
-    }
-
-    pub fn delete(group_id: String, deleted_rows: Vec<String>) -> Self {
-        Self {
-            group_id,
-            deleted_rows,
-            ..Default::default()
-        }
-    }
-
-    pub fn update(group_id: String, updated_rows: Vec<RowPB>) -> Self {
-        Self {
-            group_id,
-            updated_rows,
-            ..Default::default()
-        }
-    }
-}

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

@@ -0,0 +1,43 @@
+use crate::entities::{InsertedRowPB, RowPB};
+use flowy_derive::ProtoBuf;
+
+#[derive(Debug, Default, ProtoBuf)]
+pub struct GroupRowsChangesetPB {
+    #[pb(index = 1)]
+    pub group_id: String,
+
+    #[pb(index = 2)]
+    pub inserted_rows: Vec<InsertedRowPB>,
+
+    #[pb(index = 3)]
+    pub deleted_rows: Vec<String>,
+
+    #[pb(index = 4)]
+    pub updated_rows: Vec<RowPB>,
+}
+
+impl GroupRowsChangesetPB {
+    pub fn insert(group_id: String, inserted_rows: Vec<InsertedRowPB>) -> Self {
+        Self {
+            group_id,
+            inserted_rows,
+            ..Default::default()
+        }
+    }
+
+    pub fn delete(group_id: String, deleted_rows: Vec<String>) -> Self {
+        Self {
+            group_id,
+            deleted_rows,
+            ..Default::default()
+        }
+    }
+
+    pub fn update(group_id: String, updated_rows: Vec<RowPB>) -> Self {
+        Self {
+            group_id,
+            updated_rows,
+            ..Default::default()
+        }
+    }
+}

+ 2 - 0
frontend/rust-lib/flowy-grid/src/entities/group_entities/mod.rs

@@ -1,7 +1,9 @@
 mod board_card;
 mod configuration;
 mod group;
+mod group_changeset;
 
 pub use board_card::*;
 pub use configuration::*;
 pub use group::*;
+pub use group_changeset::*;

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

@@ -1,7 +1,8 @@
 use flowy_error::{FlowyError, FlowyResult};
 
 use crate::entities::{
-    CreateRowParams, GridFilterConfiguration, GridLayout, GridSettingPB, GroupPB, GroupRowsChangesetPB, RowPB,
+    CreateRowParams, GridFilterConfiguration, GridLayout, GridSettingPB, GroupPB, GroupRowsChangesetPB, InsertedRowPB,
+    RowPB,
 };
 use crate::services::grid_editor_task::GridServiceTaskScheduler;
 use crate::services::group::{default_group_configuration, Group, GroupConfigurationDelegate, GroupService};
@@ -91,8 +92,6 @@ impl GridViewRevisionEditor {
                 }
             },
         }
-
-        todo!()
     }
 
     pub(crate) async fn did_create_row(&self, row_pb: &RowPB, params: &CreateRowParams) {
@@ -100,7 +99,11 @@ impl GridViewRevisionEditor {
         match params.group_id.as_ref() {
             None => {}
             Some(group_id) => {
-                let changeset = GroupRowsChangesetPB::insert(group_id.clone(), vec![row_pb.clone()]);
+                let inserted_row = InsertedRowPB {
+                    row: row_pb.clone(),
+                    index: None,
+                };
+                let changeset = GroupRowsChangesetPB::insert(group_id.clone(), vec![inserted_row]);
                 self.notify_did_update_group(changeset).await;
             }
         }
@@ -120,7 +123,7 @@ impl GridViewRevisionEditor {
     async fn group_id_of_row(&self, row_id: &str) -> Option<String> {
         let read_guard = self.groups.read().await;
         for group in read_guard.iter() {
-            if group.rows.iter().find(|row| row.id == row_id).is_some() {
+            if group.rows.iter().any(|row| row.id == row_id) {
                 return Some(group.id.clone());
             }
         }
@@ -167,7 +170,7 @@ impl GridViewRevisionEditor {
     }
 
     async fn notify_did_update_group(&self, changeset: GroupRowsChangesetPB) {
-        send_dart_notification(&changeset.group_id, GridNotification::DidUpdateBoard)
+        send_dart_notification(&changeset.group_id, GridNotification::DidUpdateGroup)
             .payload(changeset)
             .send();
     }

+ 2 - 4
frontend/rust-lib/flowy-grid/src/services/group/group_service.rs

@@ -1,8 +1,6 @@
-use crate::dart_notification::{send_dart_notification, GridNotification};
 use crate::entities::{
-    CheckboxGroupConfigurationPB, DateGroupConfigurationPB, FieldType, GroupPB, GroupRowsChangesetPB,
-    NumberGroupConfigurationPB, RowPB, SelectOptionGroupConfigurationPB, TextGroupConfigurationPB,
-    UrlGroupConfigurationPB,
+    CheckboxGroupConfigurationPB, DateGroupConfigurationPB, FieldType, NumberGroupConfigurationPB,
+    SelectOptionGroupConfigurationPB, TextGroupConfigurationPB, UrlGroupConfigurationPB,
 };
 use crate::services::group::{
     CheckboxGroupController, Group, GroupActionHandler, MultiSelectGroupController, SingleSelectGroupController,