Browse Source

feat: add duplicate in context menu (#2921)

Vedant Pandey 1 year ago
parent
commit
7c21f61d2e

+ 50 - 0
frontend/appflowy_flutter/integration_test/board/board_row_test.dart

@@ -0,0 +1,50 @@
+import 'package:appflowy/generated/locale_keys.g.dart';
+import 'package:appflowy/plugins/database_view/widgets/card/card.dart';
+import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
+import 'package:easy_localization/easy_localization.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:integration_test/integration_test.dart';
+
+import '../util/util.dart';
+
+void main() {
+  IntegrationTestWidgetsFlutterBinding.ensureInitialized();
+
+  group('board row test', () {
+    testWidgets('delete item in ToDo card', (tester) async {
+      await tester.initializeAppFlowy();
+      await tester.tapGoButton();
+
+      await tester.createNewPageWithName(layout: ViewLayoutPB.Board);
+      const name = 'Card 1';
+      final card1 = find.findTextInFlowyText(name);
+      await tester.hoverOnWidget(
+        card1,
+        onHover: () async {
+          final moreOption = find.byType(CardMoreOption);
+          await tester.tapButton(moreOption);
+        },
+      );
+      await tester.tapButtonWithName(LocaleKeys.button_delete.tr());
+      expect(find.findTextInFlowyText(name), findsNothing);
+    });
+
+    testWidgets('duplicate item in ToDo card', (tester) async {
+      await tester.initializeAppFlowy();
+      await tester.tapGoButton();
+
+      await tester.createNewPageWithName(layout: ViewLayoutPB.Board);
+      const name = 'Card 1';
+      final card1 = find.findTextInFlowyText(name);
+      await tester.hoverOnWidget(
+        card1,
+        onHover: () async {
+          final moreOption = find.byType(CardMoreOption);
+          await tester.tapButton(moreOption);
+        },
+      );
+      await tester.tapButtonWithName(LocaleKeys.button_duplicate.tr());
+      expect(find.textContaining(name, findRichText: true), findsNWidgets(2));
+    });
+  });
+}

+ 10 - 0
frontend/appflowy_flutter/integration_test/board/board_test_runner.dart

@@ -0,0 +1,10 @@
+import 'package:integration_test/integration_test.dart';
+
+import 'board_row_test.dart' as board_row_test;
+
+void startTesting() {
+  IntegrationTestWidgetsFlutterBinding.ensureInitialized();
+
+  // Board integration tests
+  board_row_test.main();
+}

+ 4 - 0
frontend/appflowy_flutter/integration_test/runner.dart

@@ -15,6 +15,7 @@ import 'import_files_test.dart' as import_files_test;
 import 'share_markdown_test.dart' as share_markdown_test;
 import 'switch_folder_test.dart' as switch_folder_test;
 import 'sidebar/sidebar_test_runner.dart' as sidebar_test_runner;
+import 'board/board_test_runner.dart' as board_test_runner;
 
 /// The main task runner for all integration tests in AppFlowy.
 ///
@@ -35,6 +36,9 @@ void main() {
   // Sidebar integration tests
   sidebar_test_runner.startTesting();
 
+  // Board integration test
+  board_test_runner.startTesting();
+
   // Database integration tests
   database_cell_test.main();
   database_field_test.main();

+ 1 - 0
frontend/appflowy_flutter/lib/plugins/database_view/board/presentation/board_page.dart

@@ -298,6 +298,7 @@ class _BoardContentState extends State<BoardContent> {
         rowCache: rowCache,
         cardData: groupData.group.groupId,
         groupingFieldId: groupItem.fieldInfo.id,
+        groupId: groupData.group.groupId,
         isEditing: isEditing,
         cellBuilder: cellBuilder,
         renderHook: renderHook,

+ 5 - 1
frontend/appflowy_flutter/lib/plugins/database_view/grid/application/row/row_action_sheet_bloc.dart

@@ -15,6 +15,7 @@ class RowActionSheetBloc
   RowActionSheetBloc({
     required String viewId,
     required RowId rowId,
+    String? groupId,
   })  : _rowService = RowBackendService(viewId: viewId),
         super(RowActionSheetState.initial(rowId)) {
     on<RowActionSheetEvent>(
@@ -25,7 +26,10 @@ class RowActionSheetBloc
             logResult(result);
           },
           duplicateRow: () async {
-            final result = await _rowService.duplicateRow(rowId: state.rowId);
+            final result = await _rowService.duplicateRow(
+              rowId: state.rowId,
+              groupId: groupId,
+            );
             logResult(result);
           },
         );

+ 7 - 2
frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/row/action.dart

@@ -16,16 +16,22 @@ import '../../layout/sizes.dart';
 class RowActions extends StatelessWidget {
   final String viewId;
   final RowId rowId;
+  final String? groupId;
   const RowActions({
     required this.viewId,
     required this.rowId,
+    this.groupId,
     Key? key,
   }) : super(key: key);
 
   @override
   Widget build(BuildContext context) {
     return BlocProvider(
-      create: (context) => RowActionSheetBloc(viewId: viewId, rowId: rowId),
+      create: (context) => RowActionSheetBloc(
+        viewId: viewId,
+        rowId: rowId,
+        groupId: groupId,
+      ),
       child: BlocBuilder<RowActionSheetBloc, RowActionSheetState>(
         builder: (context, state) {
           final cells = _RowAction.values
@@ -110,7 +116,6 @@ extension _RowActionExtension on _RowAction {
   bool enable() {
     switch (this) {
       case _RowAction.duplicate:
-        return false;
       case _RowAction.delete:
         return true;
     }

+ 6 - 3
frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/card.dart

@@ -20,6 +20,7 @@ class RowCard<CustomCardData> extends StatefulWidget {
   final RowMetaPB rowMeta;
   final String viewId;
   final String? groupingFieldId;
+  final String? groupId;
 
   /// Allows passing a custom card data object to the card. The card will be
   /// returned in the [CardCellBuilder] and can be used to build the card.
@@ -49,6 +50,7 @@ class RowCard<CustomCardData> extends StatefulWidget {
     required this.rowMeta,
     required this.viewId,
     this.groupingFieldId,
+    this.groupId,
     required this.isEditing,
     required this.rowCache,
     required this.cellBuilder,
@@ -137,7 +139,7 @@ class _RowCardState<T> extends State<RowCard<T>> {
                 } else {
                   return [
                     _CardEditOption(rowNotifier: rowNotifier),
-                    _CardMoreOption(),
+                    CardMoreOption(),
                   ];
                 }
               },
@@ -180,6 +182,7 @@ class _RowCardState<T> extends State<RowCard<T>> {
         return RowActions(
           viewId: context.read<CardBloc>().viewId,
           rowId: context.read<CardBloc>().rowMeta.id,
+          groupId: widget.groupId,
         );
     }
   }
@@ -269,8 +272,8 @@ class _CardContent<CustomCardData> extends StatelessWidget {
   }
 }
 
-class _CardMoreOption extends StatelessWidget with CardAccessory {
-  _CardMoreOption({Key? key}) : super(key: key);
+class CardMoreOption extends StatelessWidget with CardAccessory {
+  CardMoreOption({Key? key}) : super(key: key);
 
   @override
   Widget build(BuildContext context) {