mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: add duplicate in context menu (#2921)
This commit is contained in:
parent
ad4c68a353
commit
7c21f61d2e
@ -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));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
@ -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();
|
||||||
|
}
|
@ -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();
|
||||||
|
@ -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,
|
||||||
|
@ -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);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user