ソースを参照

chore: reorder field

appflowy 3 年 前
コミット
0c8850503f

+ 11 - 0
frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart

@@ -29,6 +29,17 @@ class FieldService {
     return GridEventGetEditFieldContext(payload).send();
   }
 
+  Future<Either<Unit, FlowyError>> moveField(String fieldId, int fromIndex, int toIndex) {
+    final payload = MoveItemPayload.create()
+      ..gridId = gridId
+      ..itemId = fieldId
+      ..ty = MoveItemType.MoveField
+      ..fromIndex = fromIndex
+      ..toIndex = toIndex;
+
+    return GridEventMoveItem(payload).send();
+  }
+
   Future<Either<Unit, FlowyError>> updateField({
     required String fieldId,
     String? name,

+ 6 - 2
frontend/app_flowy/lib/workspace/application/grid/grid_header_bloc.dart

@@ -1,4 +1,5 @@
 import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
+import 'package:flowy_sdk/log.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
@@ -25,7 +26,10 @@ class GridHeaderBloc extends Bloc<GridHeaderEvent, GridHeaderState> {
           didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) {
             emit(state.copyWith(fields: value.fields));
           },
-          moveField: (_MoveField value) {},
+          moveField: (_MoveField value) async {
+            final result = await _fieldService.moveField(value.field.id, value.fromIndex, value.toIndex);
+            result.fold((l) {}, (err) => Log.error(err));
+          },
         );
       },
     );
@@ -49,7 +53,7 @@ class GridHeaderBloc extends Bloc<GridHeaderEvent, GridHeaderState> {
 class GridHeaderEvent with _$GridHeaderEvent {
   const factory GridHeaderEvent.initial() = _InitialHeader;
   const factory GridHeaderEvent.didReceiveFieldUpdate(List<Field> fields) = _DidReceiveFieldUpdate;
-  const factory GridHeaderEvent.moveField(int fromIndex, int toIndex) = _MoveField;
+  const factory GridHeaderEvent.moveField(Field field, int fromIndex, int toIndex) = _MoveField;
 }
 
 @freezed

+ 16 - 6
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/grid_page.dart

@@ -75,6 +75,13 @@ class FlowyGrid extends StatefulWidget {
 
 class _FlowyGridState extends State<FlowyGrid> {
   final _scrollController = GridScrollController(scrollGroupContorller: LinkedScrollControllerGroup());
+  late ScrollController headerScrollController;
+
+  @override
+  void initState() {
+    headerScrollController = _scrollController.linkHorizontalController();
+    super.initState();
+  }
 
   @override
   void dispose() {
@@ -96,11 +103,14 @@ class _FlowyGridState extends State<FlowyGrid> {
           ],
         );
 
-        return Column(children: [
-          const _GridToolbarAdaptor(),
-          _gridHeader(context, state.gridId, contentWidth),
-          Flexible(child: child),
-        ]);
+        return Column(
+          crossAxisAlignment: CrossAxisAlignment.start,
+          children: [
+            const _GridToolbarAdaptor(),
+            _gridHeader(context, state.gridId, contentWidth),
+            Flexible(child: child),
+          ],
+        );
       },
     );
   }
@@ -145,7 +155,7 @@ class _FlowyGridState extends State<FlowyGrid> {
       child: GridHeaderSliverAdaptor(
         gridId: gridId,
         fieldCache: fieldCache,
-        anchorScrollController: _scrollController.linkHorizontalController(),
+        anchorScrollController: headerScrollController,
       ),
     );
   }

+ 8 - 1
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart

@@ -110,7 +110,7 @@ class _GridHeaderState extends State<_GridHeader> {
               header: const _CellLeading(),
               footer: _CellTrailing(gridId: widget.gridId),
               onReorder: (int oldIndex, int newIndex) {
-                Log.info("from $oldIndex to $newIndex");
+                _onReorder(cells, oldIndex, context, newIndex);
               },
               children: cells,
             ),
@@ -119,6 +119,13 @@ class _GridHeaderState extends State<_GridHeader> {
       },
     );
   }
+
+  void _onReorder(List<GridFieldCell> cells, int oldIndex, BuildContext context, int newIndex) {
+    if (cells.length > oldIndex) {
+      final field = cells[oldIndex].cellContext.field;
+      context.read<GridHeaderBloc>().add(GridHeaderEvent.moveField(field, oldIndex, newIndex));
+    }
+  }
 }
 
 class _CellLeading extends StatelessWidget {

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

@@ -385,16 +385,30 @@ impl ClientGridEditor {
     pub async fn move_item(&self, params: MoveItemParams) -> FlowyResult<()> {
         match params.ty {
             MoveItemType::MoveField => {
-                self.move_field(params.from_index, params.to_index, &params.item_id)
+                self.move_field(&params.item_id, params.from_index, params.to_index)
                     .await
             }
             MoveItemType::MoveRow => self.move_row(params.from_index, params.to_index, &params.item_id).await,
         }
     }
 
-    pub async fn move_field(&self, from: i32, to: i32, field_id: &str) -> FlowyResult<()> {
-        // GridFieldChangeset
-        todo!()
+    pub async fn move_field(&self, field_id: &str, from: i32, to: i32) -> FlowyResult<()> {
+        let _ = self
+            .modify(|grid_pad| Ok(grid_pad.move_field(field_id, from as usize, to as usize)?))
+            .await?;
+        if let Some((index, field_meta)) = self.pad.read().await.get_field_meta(field_id) {
+            let delete_field_order = FieldOrder::from(field_id);
+            let insert_field = IndexField::from_field_meta(field_meta, index);
+            let notified_changeset = GridFieldChangeset {
+                grid_id: self.grid_id.clone(),
+                inserted_fields: vec![insert_field],
+                deleted_fields: vec![delete_field_order],
+                updated_fields: vec![],
+            };
+
+            let _ = self.notify_did_update_grid(notified_changeset).await?;
+        }
+        Ok(())
     }
 
     pub async fn move_row(&self, from: i32, to: i32, row_id: &str) -> FlowyResult<()> {

+ 19 - 0
shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs

@@ -205,6 +205,25 @@ impl GridMetaPad {
         )
     }
 
+    pub fn move_field(
+        &mut self,
+        field_id: &str,
+        from_index: usize,
+        to_index: usize,
+    ) -> CollaborateResult<Option<GridChangeset>> {
+        self.modify_grid(
+            |grid_meta| match grid_meta.fields.iter().position(|field| field.id == field_id) {
+                None => Ok(None),
+                Some(index) => {
+                    debug_assert_eq!(index, from_index);
+                    let field_meta = grid_meta.fields.remove(index);
+                    grid_meta.fields.insert(to_index, field_meta);
+                    Ok(Some(()))
+                }
+            },
+        )
+    }
+
     pub fn contain_field(&self, field_id: &str) -> bool {
         self.grid_meta.fields.iter().any(|field| field.id == field_id)
     }