Browse Source

Merge pull request #1142 from AppFlowy-IO/fix/ui_adjust

Fix/UI adjust
Nathan.fooo 2 years ago
parent
commit
f317bae216
17 changed files with 135 additions and 77 deletions
  1. 3 1
      frontend/app_flowy/lib/plugins/board/presentation/card/card.dart
  2. 1 1
      frontend/app_flowy/lib/plugins/doc/document.dart
  3. 74 28
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/date_cell/date_editor.dart
  4. 1 0
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_cell.dart
  5. 9 17
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_editor.dart
  6. 1 0
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/grid_header.dart
  7. 1 0
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/grid_row.dart
  8. 1 0
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/row_detail.dart
  9. 1 0
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/toolbar/grid_toolbar.dart
  10. 5 4
      frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/header.dart
  11. 8 4
      frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/right_click_action.dart
  12. 2 2
      frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/disclosure_action.dart
  13. 4 4
      frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/item.dart
  14. 11 6
      frontend/app_flowy/lib/workspace/presentation/widgets/float_bubble/question_bubble.dart
  15. 4 6
      frontend/app_flowy/lib/workspace/presentation/widgets/pop_up_action.dart
  16. 7 2
      frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart
  17. 2 2
      frontend/rust-lib/flowy-grid/src/services/group/controller_impls/default_controller.rs

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

@@ -85,6 +85,7 @@ class _BoardCardState extends State<BoardCard> {
             controller: popoverController,
             triggerActions: PopoverTriggerFlags.none,
             constraints: BoxConstraints.loose(const Size(140, 200)),
+            margin: const EdgeInsets.all(6),
             direction: PopoverDirection.rightWithCenterAligned,
             popupBuilder: (popoverContext) => _handlePopoverBuilder(
               context,
@@ -133,7 +134,8 @@ class _BoardCardState extends State<BoardCard> {
         throw UnimplementedError();
       case AccessoryType.more:
         return GridRowActionSheet(
-            rowData: context.read<BoardCardBloc>().rowInfo());
+          rowData: context.read<BoardCardBloc>().rowInfo(),
+        );
     }
   }
 

+ 1 - 1
frontend/app_flowy/lib/plugins/doc/document.dart

@@ -233,7 +233,7 @@ class ShareActionWrapper extends ActionItem {
   ShareActionWrapper(this.inner);
 
   @override
-  Widget? get icon => null;
+  Widget? icon(Color iconColor) => null;
 
   @override
   String get name => inner.name;

+ 74 - 28
frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/date_cell/date_editor.dart

@@ -76,7 +76,7 @@ class _DateCellEditor extends State<DateCellEditor> {
   }
 }
 
-class _CellCalendarWidget extends StatelessWidget {
+class _CellCalendarWidget extends StatefulWidget {
   final GridDateCellController cellContext;
   final DateTypeOptionPB dateTypeOptionPB;
 
@@ -86,26 +86,43 @@ class _CellCalendarWidget extends StatelessWidget {
     Key? key,
   }) : super(key: key);
 
+  @override
+  State<_CellCalendarWidget> createState() => _CellCalendarWidgetState();
+}
+
+class _CellCalendarWidgetState extends State<_CellCalendarWidget> {
+  late PopoverMutex popoverMutex;
+  late DateCalBloc bloc;
+
+  @override
+  void initState() {
+    popoverMutex = PopoverMutex();
+
+    bloc = DateCalBloc(
+      dateTypeOptionPB: widget.dateTypeOptionPB,
+      cellData: widget.cellContext.getCellData(),
+      cellController: widget.cellContext,
+    )..add(const DateCalEvent.initial());
+    super.initState();
+  }
+
   @override
   Widget build(BuildContext context) {
     final theme = context.watch<AppTheme>();
-    return BlocProvider(
-      create: (context) {
-        return DateCalBloc(
-          dateTypeOptionPB: dateTypeOptionPB,
-          cellData: cellContext.getCellData(),
-          cellController: cellContext,
-        )..add(const DateCalEvent.initial());
-      },
+    return BlocProvider.value(
+      value: bloc,
       child: BlocBuilder<DateCalBloc, DateCalState>(
         buildWhen: (p, c) => false,
         builder: (context, state) {
           List<Widget> children = [
             _buildCalendar(theme, context),
-            _TimeTextField(bloc: context.read<DateCalBloc>()),
+            _TimeTextField(
+              bloc: context.read<DateCalBloc>(),
+              popoverMutex: popoverMutex,
+            ),
             Divider(height: 1, color: theme.shader5),
             const _IncludeTimeButton(),
-            const _DateTypeOptionButton()
+            _DateTypeOptionButton(popoverMutex: popoverMutex)
           ];
 
           return ListView.separated(
@@ -124,6 +141,13 @@ class _CellCalendarWidget extends StatelessWidget {
     );
   }
 
+  @override
+  void dispose() {
+    bloc.close();
+    popoverMutex.dispose();
+    super.dispose();
+  }
+
   Widget _buildCalendar(AppTheme theme, BuildContext context) {
     return BlocBuilder<DateCalBloc, DateCalState>(
       builder: (context, state) {
@@ -223,8 +247,10 @@ class _IncludeTimeButton extends StatelessWidget {
 
 class _TimeTextField extends StatefulWidget {
   final DateCalBloc bloc;
+  final PopoverMutex popoverMutex;
   const _TimeTextField({
     required this.bloc,
+    required this.popoverMutex,
     Key? key,
   }) : super(key: key);
 
@@ -245,9 +271,18 @@ class _TimeTextFieldState extends State<_TimeTextField> {
         if (mounted) {
           widget.bloc.add(DateCalEvent.setTime(_controller.text));
         }
+
+        if (_focusNode.hasFocus) {
+          widget.popoverMutex.close();
+        }
       });
-    }
 
+      widget.popoverMutex.listenOnPopoverChanged(() {
+        if (_focusNode.hasFocus) {
+          _focusNode.unfocus();
+        }
+      });
+    }
     super.initState();
   }
 
@@ -295,7 +330,11 @@ class _TimeTextFieldState extends State<_TimeTextField> {
 }
 
 class _DateTypeOptionButton extends StatelessWidget {
-  const _DateTypeOptionButton({Key? key}) : super(key: key);
+  final PopoverMutex popoverMutex;
+  const _DateTypeOptionButton({
+    required this.popoverMutex,
+    Key? key,
+  }) : super(key: key);
 
   @override
   Widget build(BuildContext context) {
@@ -306,6 +345,7 @@ class _DateTypeOptionButton extends StatelessWidget {
       selector: (state) => state.dateTypeOptionPB,
       builder: (context, dateTypeOptionPB) {
         return AppFlowyPopover(
+          mutex: popoverMutex,
           triggerActions: PopoverTriggerFlags.hover | PopoverTriggerFlags.click,
           offset: const Offset(20, 0),
           constraints: BoxConstraints.loose(const Size(140, 100)),
@@ -318,7 +358,10 @@ class _DateTypeOptionButton extends StatelessWidget {
           popupBuilder: (BuildContext popContext) {
             return _CalDateTimeSetting(
               dateTypeOptionPB: dateTypeOptionPB,
-              onEvent: (event) => context.read<DateCalBloc>().add(event),
+              onEvent: (event) {
+                context.read<DateCalBloc>().add(event);
+                popoverMutex.close();
+              },
             );
           },
         );
@@ -330,46 +373,49 @@ class _DateTypeOptionButton extends StatelessWidget {
 class _CalDateTimeSetting extends StatefulWidget {
   final DateTypeOptionPB dateTypeOptionPB;
   final Function(DateCalEvent) onEvent;
-  const _CalDateTimeSetting(
-      {required this.dateTypeOptionPB, required this.onEvent, Key? key})
-      : super(key: key);
+  const _CalDateTimeSetting({
+    required this.dateTypeOptionPB,
+    required this.onEvent,
+    Key? key,
+  }) : super(key: key);
 
   @override
   State<_CalDateTimeSetting> createState() => _CalDateTimeSettingState();
 }
 
 class _CalDateTimeSettingState extends State<_CalDateTimeSetting> {
+  final timeSettingPopoverMutex = PopoverMutex();
   String? overlayIdentifier;
-  final _popoverMutex = PopoverMutex();
 
   @override
   Widget build(BuildContext context) {
     List<Widget> children = [
       AppFlowyPopover(
-        mutex: _popoverMutex,
-        asBarrier: true,
+        mutex: timeSettingPopoverMutex,
         triggerActions: PopoverTriggerFlags.hover | PopoverTriggerFlags.click,
         offset: const Offset(20, 0),
         popupBuilder: (BuildContext context) {
           return DateFormatList(
             selectedFormat: widget.dateTypeOptionPB.dateFormat,
-            onSelected: (format) =>
-                widget.onEvent(DateCalEvent.setDateFormat(format)),
+            onSelected: (format) {
+              widget.onEvent(DateCalEvent.setDateFormat(format));
+              timeSettingPopoverMutex.close();
+            },
           );
         },
         child: const DateFormatButton(),
       ),
       AppFlowyPopover(
-        mutex: _popoverMutex,
-        asBarrier: true,
+        mutex: timeSettingPopoverMutex,
         triggerActions: PopoverTriggerFlags.hover | PopoverTriggerFlags.click,
         offset: const Offset(20, 0),
         popupBuilder: (BuildContext context) {
           return TimeFormatList(
-            selectedFormat: widget.dateTypeOptionPB.timeFormat,
-            onSelected: (format) =>
-                widget.onEvent(DateCalEvent.setTimeFormat(format)),
-          );
+              selectedFormat: widget.dateTypeOptionPB.timeFormat,
+              onSelected: (format) {
+                widget.onEvent(DateCalEvent.setTimeFormat(format));
+                timeSettingPopoverMutex.close();
+              });
         },
         child: TimeFormatButton(timeFormat: widget.dateTypeOptionPB.timeFormat),
       ),

+ 1 - 0
frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_cell.dart

@@ -162,6 +162,7 @@ class FieldCellButton extends StatelessWidget {
   Widget build(BuildContext context) {
     final theme = context.watch<AppTheme>();
     return FlowyButton(
+      radius: BorderRadius.zero,
       hoverColor: theme.shader6,
       onTap: onTap,
       leftIcon: svgWidget(field.fieldType.iconName(), color: theme.iconColor),

+ 9 - 17
frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_editor.dart

@@ -139,7 +139,6 @@ class _FieldNameTextField extends StatefulWidget {
 
 class _FieldNameTextFieldState extends State<_FieldNameTextField> {
   FocusNode focusNode = FocusNode();
-  VoidCallback? _popoverCallback;
   late TextEditingController controller;
 
   @override
@@ -151,6 +150,12 @@ class _FieldNameTextFieldState extends State<_FieldNameTextField> {
       }
     });
 
+    widget.popoverMutex.listenOnPopoverChanged(() {
+      if (focusNode.hasFocus) {
+        focusNode.unfocus();
+      }
+    });
+
     super.initState();
   }
 
@@ -176,8 +181,6 @@ class _FieldNameTextFieldState extends State<_FieldNameTextField> {
         buildWhen: (previous, current) =>
             previous.errorText != current.errorText,
         builder: (context, state) {
-          listenOnPopoverChanged(context);
-
           return RoundedInputField(
             height: 36,
             focusNode: focusNode,
@@ -198,18 +201,6 @@ class _FieldNameTextFieldState extends State<_FieldNameTextField> {
       ),
     );
   }
-
-  void listenOnPopoverChanged(BuildContext context) {
-    if (_popoverCallback != null) {
-      widget.popoverMutex.removePopoverListener(_popoverCallback!);
-    }
-    _popoverCallback = widget.popoverMutex.listenOnPopoverChanged(() {
-      if (focusNode.hasFocus) {
-        final node = FocusScope.of(context);
-        node.unfocus();
-      }
-    });
-  }
 }
 
 class _DeleteFieldButton extends StatelessWidget {
@@ -236,9 +227,10 @@ class _DeleteFieldButton extends StatelessWidget {
             color: enable ? null : theme.shader4,
           ),
           onTap: () => onDeleted?.call(),
+          hoverColor: theme.hover,
+          onHover: (_) => popoverMutex.close(),
         );
-        // if (enable) button = button;
-        return button;
+        return SizedBox(height: 36, child: button);
       },
     );
   }

+ 1 - 0
frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/grid_header.dart

@@ -180,6 +180,7 @@ class CreateFieldButton extends StatelessWidget {
       asBarrier: true,
       constraints: BoxConstraints.loose(const Size(240, 600)),
       child: FlowyButton(
+        radius: BorderRadius.zero,
         text: FlowyText.medium(
           LocaleKeys.grid_field_newColumn.tr(),
           fontSize: 12,

+ 1 - 0
frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/grid_row.dart

@@ -109,6 +109,7 @@ class _RowLeadingState extends State<_RowLeading> {
       triggerActions: PopoverTriggerFlags.none,
       constraints: BoxConstraints.loose(const Size(140, 200)),
       direction: PopoverDirection.rightWithCenterAligned,
+      margin: const EdgeInsets.all(6),
       popupBuilder: (BuildContext popoverContext) {
         return GridRowActionSheet(
             rowData: context.read<RowBloc>().state.rowInfo);

+ 1 - 0
frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/row_detail.dart

@@ -280,6 +280,7 @@ class _RowDetailCellState extends State<_RowDetailCell> {
             AppFlowyPopover(
               controller: popover,
               constraints: BoxConstraints.loose(const Size(240, 600)),
+              triggerActions: PopoverTriggerFlags.none,
               popupBuilder: (popoverContext) => buildFieldEditor(),
               child: SizedBox(
                 width: 150,

+ 1 - 0
frontend/app_flowy/lib/plugins/grid/presentation/widgets/toolbar/grid_toolbar.dart

@@ -55,6 +55,7 @@ class _SettingButton extends StatelessWidget {
     return AppFlowyPopover(
       constraints: BoxConstraints.loose(const Size(260, 400)),
       offset: const Offset(0, 10),
+      margin: const EdgeInsets.all(6),
       child: FlowyIconButton(
         width: 22,
         hoverColor: theme.hover,

+ 5 - 4
frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/header.dart

@@ -86,7 +86,8 @@ class MenuAppHeader extends StatelessWidget {
               ?.toggle(),
           onSecondaryTap: () {
             final actionList = AppDisclosureActionSheet(
-                onSelected: (action) => _handleAction(context, action));
+              onSelected: (action) => _handleAction(context, action),
+            );
             actionList.show(
               context,
               anchorDirection: AnchorDirection.bottomWithCenterAligned,
@@ -158,12 +159,12 @@ extension AppDisclosureExtension on AppDisclosureAction {
     }
   }
 
-  Widget get icon {
+  Widget icon(Color iconColor) {
     switch (this) {
       case AppDisclosureAction.rename:
-        return svgWidget('editor/edit', color: const Color(0xffe5e5e5));
+        return svgWidget('editor/edit', color: iconColor);
       case AppDisclosureAction.delete:
-        return svgWidget('editor/delete', color: const Color(0xffe5e5e5));
+        return svgWidget('editor/delete', color: iconColor);
     }
   }
 }

+ 8 - 4
frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/right_click_action.dart

@@ -5,9 +5,12 @@ import 'package:flutter/material.dart';
 
 import 'header.dart';
 
-class AppDisclosureActionSheet with ActionList<DisclosureActionWrapper>, FlowyOverlayDelegate {
+class AppDisclosureActionSheet
+    with ActionList<DisclosureActionWrapper>, FlowyOverlayDelegate {
   final Function(dartz.Option<AppDisclosureAction>) onSelected;
-  final _items = AppDisclosureAction.values.map((action) => DisclosureActionWrapper(action)).toList();
+  final _items = AppDisclosureAction.values
+      .map((action) => DisclosureActionWrapper(action))
+      .toList();
 
   AppDisclosureActionSheet({
     required this.onSelected,
@@ -17,7 +20,8 @@ class AppDisclosureActionSheet with ActionList<DisclosureActionWrapper>, FlowyOv
   List<DisclosureActionWrapper> get items => _items;
 
   @override
-  void Function(dartz.Option<DisclosureActionWrapper> p1) get selectCallback => (result) {
+  void Function(dartz.Option<DisclosureActionWrapper> p1) get selectCallback =>
+      (result) {
         result.fold(
           () => onSelected(dartz.none()),
           (wrapper) => onSelected(
@@ -40,7 +44,7 @@ class DisclosureActionWrapper extends ActionItem {
 
   DisclosureActionWrapper(this.inner);
   @override
-  Widget? get icon => inner.icon;
+  Widget? icon(Color iconColor) => inner.icon(iconColor);
 
   @override
   String get name => inner.name;

+ 2 - 2
frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/disclosure_action.dart

@@ -80,7 +80,7 @@ class ViewDisclosureRegion extends StatelessWidget
   @override
   Widget build(BuildContext context) {
     return Listener(
-      onPointerDown: (event) => {_handleClick(event, context)},
+      onPointerDown: (event) => _handleClick(event, context),
       child: child,
     );
   }
@@ -123,7 +123,7 @@ class ViewDisclosureActionWrapper extends ActionItem {
 
   ViewDisclosureActionWrapper(this.inner);
   @override
-  Widget? get icon => inner.icon;
+  Widget? icon(Color iconColor) => inner.icon(iconColor);
 
   @override
   String get name => inner.name;

+ 4 - 4
frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/item.dart

@@ -147,14 +147,14 @@ extension ViewDisclosureExtension on ViewDisclosureAction {
     }
   }
 
-  Widget get icon {
+  Widget icon(Color iconColor) {
     switch (this) {
       case ViewDisclosureAction.rename:
-        return svgWidget('editor/edit', color: const Color(0xff999999));
+        return svgWidget('editor/edit', color: iconColor);
       case ViewDisclosureAction.delete:
-        return svgWidget('editor/delete', color: const Color(0xff999999));
+        return svgWidget('editor/delete', color: iconColor);
       case ViewDisclosureAction.duplicate:
-        return svgWidget('editor/copy', color: const Color(0xff999999));
+        return svgWidget('editor/copy', color: iconColor);
     }
   }
 }

+ 11 - 6
frontend/app_flowy/lib/workspace/presentation/widgets/float_bubble/question_bubble.dart

@@ -101,9 +101,11 @@ class _DebugToast {
   }
 }
 
-class QuestionBubbleActionSheet with ActionList<BubbleActionWrapper>, FlowyOverlayDelegate {
+class QuestionBubbleActionSheet
+    with ActionList<BubbleActionWrapper>, FlowyOverlayDelegate {
   final Function(dartz.Option<BubbleAction>) onSelected;
-  final _items = BubbleAction.values.map((action) => BubbleActionWrapper(action)).toList();
+  final _items =
+      BubbleAction.values.map((action) => BubbleActionWrapper(action)).toList();
 
   QuestionBubbleActionSheet({
     required this.onSelected,
@@ -119,7 +121,8 @@ class QuestionBubbleActionSheet with ActionList<BubbleActionWrapper>, FlowyOverl
   List<BubbleActionWrapper> get items => _items;
 
   @override
-  void Function(dartz.Option<BubbleActionWrapper> p1) get selectCallback => (result) {
+  void Function(dartz.Option<BubbleActionWrapper> p1) get selectCallback =>
+      (result) {
         result.fold(
           () => onSelected(dartz.none()),
           (wrapper) => onSelected(
@@ -156,7 +159,8 @@ class FlowyVersionDescription extends StatelessWidget {
       builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
         if (snapshot.connectionState == ConnectionState.done) {
           if (snapshot.hasError) {
-            return FlowyText("Error: ${snapshot.error}", fontSize: 12, color: theme.shader4);
+            return FlowyText("Error: ${snapshot.error}",
+                fontSize: 12, color: theme.shader4);
           }
 
           PackageInfo packageInfo = snapshot.data;
@@ -170,7 +174,8 @@ class FlowyVersionDescription extends StatelessWidget {
             children: [
               Divider(height: 1, color: theme.shader6, thickness: 1.0),
               const VSpace(6),
-              FlowyText("$appName $version.$buildNumber", fontSize: 12, color: theme.shader4),
+              FlowyText("$appName $version.$buildNumber",
+                  fontSize: 12, color: theme.shader4),
             ],
           ).padding(
             horizontal: ActionListSizes.itemHPadding + ActionListSizes.padding,
@@ -190,7 +195,7 @@ class BubbleActionWrapper extends ActionItem {
 
   BubbleActionWrapper(this.inner);
   @override
-  Widget? get icon => inner.emoji;
+  Widget? icon(Color iconColor) => inner.emoji;
 
   @override
   String get name => inner.name;

+ 4 - 6
frontend/app_flowy/lib/workspace/presentation/widgets/pop_up_action.dart

@@ -59,7 +59,7 @@ abstract class ActionList<T extends ActionItem> {
 }
 
 abstract class ActionItem {
-  Widget? get icon;
+  Widget? icon(Color iconColor);
   String get name;
 }
 
@@ -83,6 +83,7 @@ class ActionCell<T extends ActionItem> extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
     final theme = context.watch<AppTheme>();
+    final icon = action.icon(theme.iconColor);
 
     return FlowyHover(
       style: HoverStyle(hoverColor: theme.hover),
@@ -94,12 +95,9 @@ class ActionCell<T extends ActionItem> extends StatelessWidget {
           child: Row(
             crossAxisAlignment: CrossAxisAlignment.center,
             children: [
-              if (action.icon != null) action.icon!,
+              if (icon != null) icon,
               HSpace(ActionListSizes.itemHPadding),
-              FlowyText.medium(
-                action.name,
-                fontSize: 12,
-              ),
+              FlowyText.medium(action.name, fontSize: 12),
             ],
           ),
         ).padding(

+ 7 - 2
frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart

@@ -12,6 +12,8 @@ class FlowyButton extends StatelessWidget {
   final Widget? rightIcon;
   final Color hoverColor;
   final bool isSelected;
+  final BorderRadius radius;
+
   const FlowyButton({
     Key? key,
     required this.text,
@@ -22,6 +24,7 @@ class FlowyButton extends StatelessWidget {
     this.rightIcon,
     this.hoverColor = Colors.transparent,
     this.isSelected = false,
+    this.radius = const BorderRadius.all(Radius.circular(6)),
   }) : super(key: key);
 
   @override
@@ -29,8 +32,10 @@ class FlowyButton extends StatelessWidget {
     return InkWell(
       onTap: onTap,
       child: FlowyHover(
-        style:
-            HoverStyle(borderRadius: BorderRadius.zero, hoverColor: hoverColor),
+        style: HoverStyle(
+          borderRadius: radius,
+          hoverColor: hoverColor,
+        ),
         onHover: onHover,
         setSelected: () => isSelected,
         builder: (context, onHover) => _render(),

+ 2 - 2
frontend/rust-lib/flowy-grid/src/services/group/controller_impls/default_controller.rs

@@ -55,7 +55,7 @@ impl GroupControllerSharedOperation for DefaultGroupController {
         _row_rev: &RowRevision,
         _field_rev: &FieldRevision,
     ) -> FlowyResult<Vec<GroupChangesetPB>> {
-        todo!()
+        Ok(vec![])
     }
 
     fn did_delete_row(
@@ -63,7 +63,7 @@ impl GroupControllerSharedOperation for DefaultGroupController {
         _row_rev: &RowRevision,
         _field_rev: &FieldRevision,
     ) -> FlowyResult<Vec<GroupChangesetPB>> {
-        todo!()
+        Ok(vec![])
     }
 
     fn move_group_row(&mut self, _context: MoveGroupRowContext) -> FlowyResult<Vec<GroupChangesetPB>> {