From 9b7ee4b978c0b6f5c55413694efedf6294ff0f80 Mon Sep 17 00:00:00 2001 From: Mohammad Zolfaghari Date: Mon, 20 May 2024 12:49:58 +0330 Subject: [PATCH] fix: changing field type from text to checkbox causes exception #5360 (#5366) --- .../desktop/board/board_field_test.dart | 37 +++++++++++++++++++ .../shared/database_test_op.dart | 19 +++++++--- .../database/card/mobile_card_content.dart | 8 ++-- .../plugins/database/widgets/card/card.dart | 9 ++--- .../database/widgets/card/card_bloc.dart | 34 ++++++++++++++--- 5 files changed, 87 insertions(+), 20 deletions(-) create mode 100644 frontend/appflowy_flutter/integration_test/desktop/board/board_field_test.dart diff --git a/frontend/appflowy_flutter/integration_test/desktop/board/board_field_test.dart b/frontend/appflowy_flutter/integration_test/desktop/board/board_field_test.dart new file mode 100644 index 0000000000..3fe48b5f6f --- /dev/null +++ b/frontend/appflowy_flutter/integration_test/desktop/board/board_field_test.dart @@ -0,0 +1,37 @@ +import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:integration_test/integration_test.dart'; + +import '../../shared/database_test_op.dart'; +import '../../shared/util.dart'; + +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + group('board field test', () { + testWidgets('change field type whithin card #5360', (tester) async { + await tester.initializeAppFlowy(); + await tester.tapAnonymousSignInButton(); + + await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Board); + const name = 'Card 1'; + final card1 = find.text(name); + await tester.tapButton(card1); + + const fieldName = "test change field"; + await tester.createField( + FieldType.RichText, + fieldName, + layout: ViewLayoutPB.Board, + ); + await tester.tapButton(card1); + await tester.changeFieldTypeOfFieldWithName( + fieldName, + FieldType.Checkbox, + layout: ViewLayoutPB.Board, + ); + await tester.hoverOnWidget(find.text('Card 2')); + }); + }); +} diff --git a/frontend/appflowy_flutter/integration_test/shared/database_test_op.dart b/frontend/appflowy_flutter/integration_test/shared/database_test_op.dart index 8697b832c0..8277b4db97 100644 --- a/frontend/appflowy_flutter/integration_test/shared/database_test_op.dart +++ b/frontend/appflowy_flutter/integration_test/shared/database_test_op.dart @@ -661,10 +661,13 @@ extension AppFlowyDatabaseTest on WidgetTester { Future changeFieldTypeOfFieldWithName( String name, - FieldType type, - ) async { + FieldType type, { + ViewLayoutPB layout = ViewLayoutPB.Grid, + }) async { await tapGridFieldWithName(name); - await tapEditFieldButton(); + if (layout == ViewLayoutPB.Grid) { + await tapEditFieldButton(); + } await tapSwitchFieldTypeButton(); await selectFieldType(type); @@ -881,8 +884,14 @@ extension AppFlowyDatabaseTest on WidgetTester { await tapButtonWithName(LocaleKeys.grid_row_delete.tr()); } - Future createField(FieldType fieldType, String name) async { - await scrollToRight(find.byType(GridPage)); + Future createField( + FieldType fieldType, + String name, { + ViewLayoutPB layout = ViewLayoutPB.Grid, + }) async { + if (layout == ViewLayoutPB.Grid) { + await scrollToRight(find.byType(GridPage)); + } await tapNewPropertyButton(); await renameField(name); await tapSwitchFieldTypeButton(); diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/database/card/mobile_card_content.dart b/frontend/appflowy_flutter/lib/mobile/presentation/database/card/mobile_card_content.dart index 057d3937cb..48d8b2f097 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/database/card/mobile_card_content.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/database/card/mobile_card_content.dart @@ -1,5 +1,5 @@ -import 'package:appflowy/plugins/database/application/cell/cell_controller.dart'; import 'package:appflowy/plugins/database/widgets/card/card.dart'; +import 'package:appflowy/plugins/database/widgets/card/card_bloc.dart'; import 'package:appflowy/plugins/database/widgets/cell/card_cell_builder.dart'; import 'package:appflowy/plugins/database/widgets/cell/card_cell_style_maps/mobile_board_card_cell_style.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; @@ -16,7 +16,7 @@ class MobileCardContent extends StatelessWidget { final RowMetaPB rowMeta; final CardCellBuilder cellBuilder; - final List cells; + final List cells; final RowCardStyleConfiguration styleConfiguration; @override @@ -26,9 +26,9 @@ class MobileCardContent extends StatelessWidget { child: Column( mainAxisSize: MainAxisSize.min, children: cells.map( - (cellContext) { + (cellMeta) { return cellBuilder.build( - cellContext: cellContext, + cellContext: cellMeta.cellContext(), styleMap: mobileBoardCardCellStyleMap(context), hasNotes: !rowMeta.isDocumentEmpty, ); diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/card/card.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/card/card.dart index b2daf625f6..d5c73a1179 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/card/card.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/card/card.dart @@ -1,6 +1,5 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/mobile/presentation/database/card/card.dart'; -import 'package:appflowy/plugins/database/application/cell/cell_controller.dart'; import 'package:appflowy/plugins/database/application/field/field_controller.dart'; import 'package:appflowy/plugins/database/application/row/row_cache.dart'; import 'package:appflowy/plugins/database/grid/presentation/widgets/row/action.dart'; @@ -186,7 +185,7 @@ class _CardContent extends StatelessWidget { final RowMetaPB rowMeta; final CardCellBuilder cellBuilder; - final List cells; + final List cells; final RowCardStyleConfiguration styleConfiguration; @override @@ -210,9 +209,9 @@ class _CardContent extends StatelessWidget { List _makeCells( BuildContext context, RowMetaPB rowMeta, - List cells, + List cells, ) { - return cells.mapIndexed((int index, CellContext cellContext) { + return cells.mapIndexed((int index, CellMeta cellMeta) { EditableCardNotifier? cellNotifier; if (index == 0) { @@ -225,7 +224,7 @@ class _CardContent extends StatelessWidget { } return cellBuilder.build( - cellContext: cellContext, + cellContext: cellMeta.cellContext(), cellNotifier: cellNotifier, styleMap: styleConfiguration.cellStyleMap, hasNotes: !rowMeta.isDocumentEmpty, diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/card/card_bloc.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/card/card_bloc.dart index 3cb47d9f43..5bd4d6f505 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/card/card_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/card/card_bloc.dart @@ -1,5 +1,7 @@ import 'dart:async'; +import 'package:appflowy/plugins/database/application/row/row_service.dart'; +import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; import 'package:flutter/foundation.dart'; import 'package:appflowy/plugins/database/application/cell/cell_controller.dart'; @@ -7,7 +9,6 @@ import 'package:appflowy/plugins/database/application/field/field_controller.dar import 'package:appflowy/plugins/database/application/row/row_cache.dart'; import 'package:appflowy/plugins/database/domain/row_listener.dart'; import 'package:appflowy/plugins/database/widgets/setting/field_visibility_extension.dart'; -import 'package:appflowy_backend/protobuf/flowy-database2/row_entities.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; @@ -104,7 +105,7 @@ class CardBloc extends Bloc { } } -List _makeCells( +List _makeCells( FieldController fieldController, String? groupFieldId, List cellContexts, @@ -116,7 +117,15 @@ List _makeCells( !(fieldInfo.visibility?.isVisibleState() ?? false) || (groupFieldId != null && cellContext.fieldId == groupFieldId); }); - return cellContexts.toList(); + return cellContexts + .map( + (cellCtx) => CellMeta( + fieldId: cellCtx.fieldId, + rowId: cellCtx.rowId, + fieldType: fieldController.getField(cellCtx.fieldId)!.fieldType, + ), + ) + .toList(); } @freezed @@ -124,17 +133,30 @@ class CardEvent with _$CardEvent { const factory CardEvent.initial() = _InitialRow; const factory CardEvent.setIsEditing(bool isEditing) = _IsEditing; const factory CardEvent.didReceiveCells( - List cells, + List cells, ChangedReason reason, ) = _DidReceiveCells; const factory CardEvent.didUpdateRowMeta(RowMetaPB rowMeta) = _DidUpdateRowMeta; } +@freezed +class CellMeta with _$CellMeta { + const CellMeta._(); + + const factory CellMeta({ + required String fieldId, + required RowId rowId, + required FieldType fieldType, + }) = _DatabaseCellMeta; + + CellContext cellContext() => CellContext(fieldId: fieldId, rowId: rowId); +} + @freezed class CardState with _$CardState { const factory CardState({ - required List cells, + required List cells, required RowMetaPB rowMeta, required bool isEditing, ChangedReason? changeReason, @@ -142,7 +164,7 @@ class CardState with _$CardState { factory CardState.initial( RowMetaPB rowMeta, - List cells, + List cells, bool isEditing, ) => CardState(