diff --git a/frontend/appflowy_flutter/integration_test/board/board_row_test.dart b/frontend/appflowy_flutter/integration_test/board/board_row_test.dart new file mode 100644 index 0000000000..a576dbe1c2 --- /dev/null +++ b/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)); + }); + }); +} diff --git a/frontend/appflowy_flutter/integration_test/board/board_test_runner.dart b/frontend/appflowy_flutter/integration_test/board/board_test_runner.dart new file mode 100644 index 0000000000..ebed667fb2 --- /dev/null +++ b/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(); +} diff --git a/frontend/appflowy_flutter/integration_test/runner.dart b/frontend/appflowy_flutter/integration_test/runner.dart index 6feeb87705..6969eddb86 100644 --- a/frontend/appflowy_flutter/integration_test/runner.dart +++ b/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(); diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/board/presentation/board_page.dart b/frontend/appflowy_flutter/lib/plugins/database_view/board/presentation/board_page.dart index 33b091d9f5..0294d6ec15 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/board/presentation/board_page.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/board/presentation/board_page.dart @@ -298,6 +298,7 @@ class _BoardContentState extends State { rowCache: rowCache, cardData: groupData.group.groupId, groupingFieldId: groupItem.fieldInfo.id, + groupId: groupData.group.groupId, isEditing: isEditing, cellBuilder: cellBuilder, renderHook: renderHook, diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/grid/application/row/row_action_sheet_bloc.dart b/frontend/appflowy_flutter/lib/plugins/database_view/grid/application/row/row_action_sheet_bloc.dart index a741f0dd09..989cc18e7e 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/grid/application/row/row_action_sheet_bloc.dart +++ b/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( @@ -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); }, ); diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/row/action.dart b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/row/action.dart index 6c1f514371..b40c801b07 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/row/action.dart +++ b/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( 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; } diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/card.dart b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/card.dart index db825e4fc5..8d6998c3d2 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/card.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/card.dart @@ -20,6 +20,7 @@ class RowCard 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 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 extends State> { } else { return [ _CardEditOption(rowNotifier: rowNotifier), - _CardMoreOption(), + CardMoreOption(), ]; } }, @@ -180,6 +182,7 @@ class _RowCardState extends State> { return RowActions( viewId: context.read().viewId, rowId: context.read().rowMeta.id, + groupId: widget.groupId, ); } } @@ -269,8 +272,8 @@ class _CardContent 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) {