feat: add duplicate in context menu (#2921)

This commit is contained in:
Vedant Pandey 2023-08-01 08:49:48 +05:30 committed by GitHub
parent ad4c68a353
commit 7c21f61d2e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 83 additions and 6 deletions

View File

@ -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));
});
});
}

View File

@ -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();
}

View File

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

View File

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

View File

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

View File

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

View File

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