Skip to content

Commit

Permalink
feat(flutter_desktop): open created filtered rows (#6522)
Browse files Browse the repository at this point in the history
* fix: revert previous implementation

* feat: open created but hidden rows as page

* fix: cargo clippy

* test: add integration tests

* fix: typo

* fix: flutter analyzer

* chore: clean up code

* chore: code cleanup

* chore: code cleanup
  • Loading branch information
richardshiue authored Oct 11, 2024
1 parent 64d71d0 commit ea61c81
Show file tree
Hide file tree
Showing 28 changed files with 274 additions and 155 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ void main() {
tester.assertNumberOfEventsInCalendar(1);

await tester.tapFilterButtonInGrid('Tags');
await tester.tapSelectFilterCondition(
await tester.changeSelectFilterCondition(
SelectOptionFilterConditionPB.OptionIsEmpty,
);
await tester.dismissCellEditor();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'package:appflowy/plugins/database/application/field/filter_entities.dart';
import 'package:appflowy/plugins/database/grid/presentation/grid_page.dart';
import 'package:appflowy/plugins/database/grid/presentation/widgets/filter/choicechip/checkbox.dart';
import 'package:appflowy/plugins/database/grid/presentation/widgets/filter/choicechip/text.dart';
import 'package:appflowy/plugins/database/widgets/row/row_detail.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
import 'package:flutter_test/flutter_test.dart';
Expand Down Expand Up @@ -154,10 +154,10 @@ void main() {
tester.assertNumberOfRowsInGridPage(0);

await tester.tapFilterButtonInGrid('date');
await tester.tapDateFilterCondition(DateTimeFilterCondition.before);
await tester.changeDateFilterCondition(DateTimeFilterCondition.before);
tester.assertNumberOfRowsInGridPage(7);

await tester.tapDateFilterCondition(DateTimeFilterCondition.isEmpty);
await tester.changeDateFilterCondition(DateTimeFilterCondition.isEmpty);
tester.assertNumberOfRowsInGridPage(3);

await tester.pumpAndSettle();
Expand All @@ -169,8 +169,6 @@ void main() {

await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);

await tester.scrollToRight(find.byType(GridPage));

await tester.createField(
FieldType.CreatedTime,
name: 'Created at',
Expand All @@ -187,8 +185,38 @@ void main() {
tester.assertNumberOfRowsInGridPage(3);

await tester.tapFilterButtonInGrid('Created at');
await tester.tapDateFilterCondition(DateTimeFilterCondition.before);
await tester.changeDateFilterCondition(DateTimeFilterCondition.before);
tester.assertNumberOfRowsInGridPage(0);

await tester.pumpAndSettle();
});

testWidgets('create new row when filters don\'t autofill', (tester) async {
await tester.initializeAppFlowy();
await tester.tapAnonymousSignInButton();

await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);

// create a filter
await tester.tapDatabaseFilterButton();
await tester.tapCreateFilterByFieldType(
FieldType.RichText,
'Name',
);
tester.assertNumberOfRowsInGridPage(3);

await tester.tapCreateRowButtonInGrid();
tester.assertNumberOfRowsInGridPage(4);

await tester.tapFilterButtonInGrid('Name');
await tester
.changeTextFilterCondition(TextFilterConditionPB.TextIsNotEmpty);
await tester.dismissCellEditor();
tester.assertNumberOfRowsInGridPage(0);

await tester.tapCreateRowButtonInGrid();
tester.assertNumberOfRowsInGridPage(0);
expect(find.byType(RowDetailPage), findsOneWidget);

await tester.pumpAndSettle();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1215,7 +1215,21 @@ extension AppFlowyDatabaseTest on WidgetTester {
await tapButton(button);
}

Future<void> tapSelectFilterCondition(
Future<void> changeTextFilterCondition(
TextFilterConditionPB condition,
) async {
await tapButton(find.byType(TextFilterConditionList));
final button = find.descendant(
of: find.byType(HoverButton),
matching: find.text(
condition.filterName,
),
);

await tapButton(button);
}

Future<void> changeSelectFilterCondition(
SelectOptionFilterConditionPB condition,
) async {
await tapButton(find.byType(SelectOptionFilterConditionList));
Expand All @@ -1227,7 +1241,9 @@ extension AppFlowyDatabaseTest on WidgetTester {
await tapButton(button);
}

Future<void> tapDateFilterCondition(DateTimeFilterCondition condition) async {
Future<void> changeDateFilterCondition(
DateTimeFilterCondition condition,
) async {
await tapButton(find.byType(DateFilterConditionList));
final button = find.descendant(
of: find.byType(HoverButton),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'dart:collection';

import 'package:appflowy/plugins/database/application/field/filter_entities.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/database_entities.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
import 'package:appflowy_result/appflowy_result.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
Expand All @@ -18,7 +18,7 @@ typedef OnFiltersChanged = void Function(List<DatabaseFilter>);
typedef OnSortsChanged = void Function(List<DatabaseSort>);
typedef OnDatabaseChanged = void Function(DatabasePB);

typedef OnRowsCreated = void Function(List<RowId> rowIds);
typedef OnRowsCreated = void Function(List<InsertedRowPB> rows);
typedef OnRowsUpdated = void Function(
List<RowId> rowIds,
ChangedReason reason,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,9 @@ class RowCache {
}

void setRowMeta(RowMetaPB rowMeta) {
var rowInfo = _rowList.get(rowMeta.id);
final rowInfo = _rowList.get(rowMeta.id);
if (rowInfo != null) {
rowInfo.updateRowMeta(rowMeta);
} else {
rowInfo = buildGridRow(rowMeta);
_rowList.add(rowInfo);
}

_changedNotifier?.receive(const ChangedReason.didFetchRow());
Expand Down Expand Up @@ -162,13 +159,19 @@ class RowCache {
}

void _insertRows(List<InsertedRowPB> insertRows) {
final InsertedIndexs insertedIndices = [];
for (final insertedRow in insertRows) {
final insertedIndex =
_rowList.insert(insertedRow.index, buildGridRow(insertedRow.rowMeta));
if (insertedIndex != null) {
_changedNotifier?.receive(ChangedReason.insert(insertedIndex));
if (insertedRow.hasIndex()) {
final index = _rowList.insert(
insertedRow.index,
buildGridRow(insertedRow.rowMeta),
);
if (index != null) {
insertedIndices.add(index);
}
}
}
_changedNotifier?.receive(ChangedReason.insert(insertedIndices));
}

void _updateRows(List<UpdatedRowPB> updatedRows) {
Expand Down Expand Up @@ -211,7 +214,7 @@ class RowCache {
final insertedIndex =
_rowList.insert(insertedRow.index, buildGridRow(insertedRow.rowMeta));
if (insertedIndex != null) {
_changedNotifier?.receive(ChangedReason.insert(insertedIndex));
_changedNotifier?.receive(ChangedReason.insert([insertedIndex]));
}
}
}
Expand Down Expand Up @@ -365,7 +368,7 @@ typedef UpdatedIndexMap = LinkedHashMap<RowId, UpdatedIndex>;

@freezed
class ChangedReason with _$ChangedReason {
const factory ChangedReason.insert(InsertedIndex item) = _Insert;
const factory ChangedReason.insert(InsertedIndexs items) = _Insert;
const factory ChangedReason.delete(DeletedIndex item) = _Delete;
const factory ChangedReason.update(UpdatedIndexMap indexs) = _Update;
const factory ChangedReason.fieldDidChange() = _FieldDidChange;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,7 @@ class DatabaseViewCache {

if (changeset.insertedRows.isNotEmpty) {
for (final callback in _callbacks) {
callback.onRowsCreated?.call(
changeset.insertedRows
.map((insertedRow) => insertedRow.rowMeta.id)
.toList(),
);
callback.onRowsCreated?.call(changeset.insertedRows);
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,11 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
);
}
},
openRowDetail: (rowMeta) {
final copyState = state;
emit(BoardState.openRowDetail(rowMeta: rowMeta));
emit(copyState);
},
);
},
);
Expand Down Expand Up @@ -477,8 +482,18 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
add(BoardEvent.didReceiveGroups(groupList));
},
);
final onDatabaseChanged = DatabaseCallbacks(
onRowsCreated: (rows) {
for (final row in rows) {
if (!isClosed && row.isHiddenInView) {
add(BoardEvent.openRowDetail(row.rowMeta));
}
}
},
);

databaseController.addListener(
onDatabaseChanged: onDatabaseChanged,
onLayoutSettingsChanged: onLayoutSettingsChanged,
onGroupChanged: onGroupChanged,
);
Expand Down Expand Up @@ -581,6 +596,7 @@ class BoardEvent with _$BoardEvent {
GroupedRowId groupedRowId,
bool toPrevious,
) = _MoveGroupToAdjacentGroup;
const factory BoardEvent.openRowDetail(RowMetaPB rowMeta) = _OpenRowDetail;
}

@freezed
Expand All @@ -607,6 +623,10 @@ class BoardState with _$BoardState {
required List<GroupedRowId> groupedRowIds,
}) = _BoardSetFocusState;

const factory BoardState.openRowDetail({
required RowMetaPB rowMeta,
}) = _BoardOpenRowDetailState;

factory BoardState.initial(String viewId) => BoardState.ready(
viewId: viewId,
groupIds: [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,14 @@ class _BoardContentState extends State<_BoardContent> {
ready: (value) {
widget.onEditStateChanged?.call();
},
openRowDetail: (value) {
_openCard(
context: context,
databaseController:
context.read<BoardBloc>().databaseController,
rowMeta: value.rowMeta,
);
},
orElse: () {},
);
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,20 @@ class CalendarBloc extends Bloc<CalendarEvent, CalendarState> {
),
);
},
openRowDetail: (row) {
emit(
state.copyWith(
openRow: row,
),
);
},
resetOpenRowDetail: () {
emit(
state.copyWith(
openRow: null,
),
);
},
);
},
);
Expand Down Expand Up @@ -306,14 +320,18 @@ class CalendarBloc extends Bloc<CalendarEvent, CalendarState> {
for (final fieldInfo in fieldInfos) fieldInfo.field.id: fieldInfo,
};
},
onRowsCreated: (rowIds) async {
onRowsCreated: (rows) async {
if (isClosed) {
return;
}
for (final id in rowIds) {
final event = await _loadEvent(id);
if (event != null && !isClosed) {
add(CalendarEvent.didReceiveEvent(event));
for (final row in rows) {
if (row.isHiddenInView) {
add(CalendarEvent.openRowDetail(row.rowMeta));
} else {
final event = await _loadEvent(row.rowMeta.id);
if (event != null) {
add(CalendarEvent.didReceiveEvent(event));
}
}
}
},
Expand Down Expand Up @@ -463,6 +481,10 @@ class CalendarEvent with _$CalendarEvent {

const factory CalendarEvent.deleteEvent(String viewId, String rowId) =
_DeleteEvent;

const factory CalendarEvent.openRowDetail(RowMetaPB row) = _OpenRowDetail;

const factory CalendarEvent.resetOpenRowDetail() = _ResetRowDetail;
}

@freezed
Expand All @@ -477,6 +499,7 @@ class CalendarState with _$CalendarState {
CalendarEventData<CalendarDayEvent>? updateEvent,
required List<String> deleteEventIds,
required CalendarLayoutSettingPB? settings,
required RowMetaPB? openRow,
required LoadingState loadingState,
required FlowyError? noneOrError,
}) = _CalendarState;
Expand All @@ -487,6 +510,7 @@ class CalendarState with _$CalendarState {
initialEvents: [],
deleteEventIds: [],
settings: null,
openRow: null,
noneOrError: null,
loadingState: LoadingState.loading(),
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,12 @@ class UnscheduleEventsBloc

void _startListening() {
final onDatabaseChanged = DatabaseCallbacks(
onRowsCreated: (rowIds) async {
onRowsCreated: (rows) async {
if (isClosed) {
return;
}
for (final id in rowIds) {
final event = await _loadEvent(id);
for (final row in rows) {
final event = await _loadEvent(row.rowMeta.id);
if (event != null && !isClosed) {
add(UnscheduleEventsEvent.didReceiveEvent(event));
}
Expand Down
Loading

0 comments on commit ea61c81

Please sign in to comment.