Skip to content

Commit

Permalink
feat(flutter_desktop): allow filtering by date end (AppFlowy-IO#6399)
Browse files Browse the repository at this point in the history
  • Loading branch information
richardshiue authored Sep 25, 2024
1 parent a8a8502 commit 9b7d38b
Show file tree
Hide file tree
Showing 16 changed files with 586 additions and 204 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:appflowy/plugins/database/application/field/filter_entities.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_backend/protobuf/flowy-database2/protobuf.dart';
Expand Down Expand Up @@ -151,11 +152,11 @@ void main() {

await tester.tapFilterButtonInGrid('date');
await tester.tapDateFilterButtonInGrid();
await tester.tapDateFilterCondition(DateFilterConditionPB.DateBefore);
await tester.tapDateFilterCondition(DateTimeFilterCondition.before);
tester.assertNumberOfRowsInGridPage(7);

await tester.tapDateFilterButtonInGrid();
await tester.tapDateFilterCondition(DateFilterConditionPB.DateIsEmpty);
await tester.tapDateFilterCondition(DateTimeFilterCondition.isEmpty);
tester.assertNumberOfRowsInGridPage(3);

await tester.pumpAndSettle();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'dart:io';

import 'package:appflowy/plugins/database/application/field/filter_entities.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
Expand Down Expand Up @@ -1135,7 +1136,7 @@ extension AppFlowyDatabaseTest on WidgetTester {
await tapButton(button);
}

Future<void> tapDateFilterCondition(DateFilterConditionPB condition) async {
Future<void> tapDateFilterCondition(DateTimeFilterCondition condition) async {
final button = find.descendant(
of: find.byType(HoverButton),
matching: find.text(condition.filterName),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'dart:typed_data';

import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/plugins/database/application/field/field_info.dart';
import 'package:appflowy/plugins/database/grid/application/filter/select_option_loader.dart';
import 'package:appflowy/plugins/database/grid/presentation/widgets/filter/choicechip/checkbox.dart';
Expand All @@ -10,6 +11,7 @@ import 'package:appflowy/plugins/database/grid/presentation/widgets/filter/choic
import 'package:appflowy/plugins/database/grid/presentation/widgets/filter/choicechip/text.dart';
import 'package:appflowy/util/int64_extension.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:fixnum/fixnum.dart';

abstract class DatabaseFilter {
Expand Down Expand Up @@ -319,6 +321,67 @@ final class SelectOptionFilter extends DatabaseFilter {
}
}

enum DateTimeFilterCondition {
on,
before,
after,
onOrBefore,
onOrAfter,
between,
isEmpty,
isNotEmpty;

DateFilterConditionPB toPB(bool isStart) {
return isStart
? switch (this) {
on => DateFilterConditionPB.DateStartsOn,
before => DateFilterConditionPB.DateStartsBefore,
after => DateFilterConditionPB.DateStartsAfter,
onOrBefore => DateFilterConditionPB.DateStartsOnOrBefore,
onOrAfter => DateFilterConditionPB.DateStartsOnOrAfter,
between => DateFilterConditionPB.DateStartsBetween,
isEmpty => DateFilterConditionPB.DateStartIsEmpty,
isNotEmpty => DateFilterConditionPB.DateStartIsNotEmpty,
}
: switch (this) {
on => DateFilterConditionPB.DateEndsOn,
before => DateFilterConditionPB.DateEndsBefore,
after => DateFilterConditionPB.DateEndsAfter,
onOrBefore => DateFilterConditionPB.DateEndsOnOrBefore,
onOrAfter => DateFilterConditionPB.DateEndsOnOrAfter,
between => DateFilterConditionPB.DateEndsBetween,
isEmpty => DateFilterConditionPB.DateEndIsEmpty,
isNotEmpty => DateFilterConditionPB.DateEndIsNotEmpty,
};
}

String get choiceChipPrefix {
return switch (this) {
on => "",
before => LocaleKeys.grid_dateFilter_choicechipPrefix_before.tr(),
after => LocaleKeys.grid_dateFilter_choicechipPrefix_after.tr(),
onOrBefore => LocaleKeys.grid_dateFilter_choicechipPrefix_onOrBefore.tr(),
onOrAfter => LocaleKeys.grid_dateFilter_choicechipPrefix_onOrAfter.tr(),
between => LocaleKeys.grid_dateFilter_choicechipPrefix_between.tr(),
isEmpty => LocaleKeys.grid_dateFilter_choicechipPrefix_isEmpty.tr(),
isNotEmpty => LocaleKeys.grid_dateFilter_choicechipPrefix_isNotEmpty.tr(),
};
}

String get filterName {
return switch (this) {
on => LocaleKeys.grid_dateFilter_is.tr(),
before => LocaleKeys.grid_dateFilter_before.tr(),
after => LocaleKeys.grid_dateFilter_after.tr(),
onOrBefore => LocaleKeys.grid_dateFilter_onOrBefore.tr(),
onOrAfter => LocaleKeys.grid_dateFilter_onOrAfter.tr(),
between => LocaleKeys.grid_dateFilter_between.tr(),
isEmpty => LocaleKeys.grid_dateFilter_empty.tr(),
isNotEmpty => LocaleKeys.grid_dateFilter_notEmpty.tr(),
};
}
}

final class DateTimeFilter extends DatabaseFilter {
const DateTimeFilter({
required super.filterId,
Expand All @@ -341,12 +404,19 @@ final class DateTimeFilter extends DatabaseFilter {
@override
String getDescription(FieldInfo field) {
return switch (condition) {
DateFilterConditionPB.DateIsEmpty ||
DateFilterConditionPB.DateIsNotEmpty =>
condition.filterName,
DateFilterConditionPB.DateWithIn =>
"${condition.filterName} ${start?.defaultFormat ?? ""} - ${end?.defaultFormat ?? ""}",
_ => "${condition.filterName} ${timestamp?.defaultFormat ?? ""}"
DateFilterConditionPB.DateStartIsEmpty ||
DateFilterConditionPB.DateStartIsNotEmpty ||
DateFilterConditionPB.DateEndIsEmpty ||
DateFilterConditionPB.DateEndIsNotEmpty =>
condition.toCondition().choiceChipPrefix,
DateFilterConditionPB.DateStartsOn ||
DateFilterConditionPB.DateEndsOn =>
timestamp?.defaultFormat ?? "",
DateFilterConditionPB.DateStartsBetween ||
DateFilterConditionPB.DateEndsBetween =>
"${condition.toCondition().choiceChipPrefix} ${start?.defaultFormat ?? ""} - ${end?.defaultFormat ?? ""}",
_ =>
"${condition.toCondition().choiceChipPrefix} ${timestamp?.defaultFormat ?? ""}"
};
}

Expand All @@ -359,41 +429,62 @@ final class DateTimeFilter extends DatabaseFilter {
}

switch (condition) {
case DateFilterConditionPB.DateIs:
case DateFilterConditionPB.DateBefore:
case DateFilterConditionPB.DateOnOrBefore:
case DateFilterConditionPB.DateAfter:
case DateFilterConditionPB.DateOnOrAfter:
case DateFilterConditionPB.DateStartsOn:
case DateFilterConditionPB.DateStartsBefore:
case DateFilterConditionPB.DateStartsOnOrBefore:
case DateFilterConditionPB.DateStartsAfter:
case DateFilterConditionPB.DateStartsOnOrAfter:
case DateFilterConditionPB.DateEndsOn:
case DateFilterConditionPB.DateEndsBefore:
case DateFilterConditionPB.DateEndsOnOrBefore:
case DateFilterConditionPB.DateEndsAfter:
case DateFilterConditionPB.DateEndsOnOrAfter:
if (timestamp != null) {
filterPB.timestamp = dateTimeToInt(timestamp!);
}
break;
case DateFilterConditionPB.DateWithIn:
case DateFilterConditionPB.DateStartsBetween:
case DateFilterConditionPB.DateEndsBetween:
if (start != null) {
filterPB.start = dateTimeToInt(start!);
}
if (end != null) {
filterPB.end = dateTimeToInt(end!);
}
break;
default:
break;
}

return filterPB.writeToBuffer();
}

DateTimeFilter copyWith({
DateFilterConditionPB? condition,
DateTime? timestamp,
DateTimeFilter copyWithCondition({
required bool isStart,
required DateTimeFilterCondition condition,
}) {
return DateTimeFilter(
filterId: filterId,
fieldId: fieldId,
fieldType: fieldType,
condition: condition.toPB(isStart),
start: start,
end: end,
condition: condition ?? this.condition,
timestamp: timestamp ?? this.timestamp,
timestamp: timestamp,
);
}

DateTimeFilter copyWithTimestamp({
required DateTime timestamp,
}) {
return DateTimeFilter(
filterId: filterId,
fieldId: fieldId,
fieldType: fieldType,
condition: condition,
start: start,
end: end,
timestamp: timestamp,
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ class FilterEditorBloc extends Bloc<FilterEditorEvent, FilterEditorState> {
final timestamp = DateTime.now().millisecondsSinceEpoch ~/ 1000;
return _filterBackendSvc.insertDateFilter(
fieldId: fieldId,
condition: DateFilterConditionPB.DateIs,
condition: DateFilterConditionPB.DateStartsOn,
timestamp: timestamp,
);
case FieldType.MultiSelect:
Expand Down
Loading

0 comments on commit 9b7d38b

Please sign in to comment.