feat: advanced filters backend logic (#4688)

* feat: implement advanced filters

* test: adapt tests to changes

* test: add advanced filter tests

* chore: adapt flutter frontend to changes

* chore: adapt tauri frontend to changes

* chore: bump collab

* chore: launch review

---------

Co-authored-by: nathan <nathan@appflowy.io>
This commit is contained in:
Richard Shiue
2024-03-14 09:35:45 +08:00
committed by GitHub
parent 80e210b34a
commit 48cac4c5ac
50 changed files with 1915 additions and 1514 deletions

View File

@ -61,19 +61,11 @@ class FilterListener {
final String viewId;
final String filterId;
PublishNotifier<FilterPB>? _onDeleteNotifier = PublishNotifier();
PublishNotifier<FilterPB>? _onUpdateNotifier = PublishNotifier();
DatabaseNotificationListener? _listener;
void start({
void Function()? onDeleted,
void Function(FilterPB)? onUpdated,
}) {
_onDeleteNotifier?.addPublishListener((_) {
onDeleted?.call();
});
void start({void Function(FilterPB)? onUpdated}) {
_onUpdateNotifier?.addPublishListener((filter) {
onUpdated?.call(filter);
});
@ -85,20 +77,12 @@ class FilterListener {
}
void handleChangeset(FilterChangesetNotificationPB changeset) {
// check the delete filter
final deletedIndex = changeset.deleteFilters.indexWhere(
(element) => element.id == filterId,
);
if (deletedIndex != -1) {
_onDeleteNotifier?.value = changeset.deleteFilters[deletedIndex];
}
// check the updated filter
final updatedIndex = changeset.updateFilters.indexWhere(
(element) => element.filter.id == filterId,
final filters = changeset.filters.items;
final updatedIndex = filters.indexWhere(
(filter) => filter.id == filterId,
);
if (updatedIndex != -1) {
_onUpdateNotifier?.value = changeset.updateFilters[updatedIndex].filter;
_onUpdateNotifier?.value = filters[updatedIndex];
}
}
@ -122,9 +106,6 @@ class FilterListener {
Future<void> stop() async {
await _listener?.stop();
_onDeleteNotifier?.dispose();
_onDeleteNotifier = null;
_onUpdateNotifier?.dispose();
_onUpdateNotifier = null;
}

View File

@ -40,12 +40,18 @@ class FilterBackendService {
..condition = condition
..content = content;
return insertFilter(
fieldId: fieldId,
filterId: filterId,
fieldType: FieldType.RichText,
data: filter.writeToBuffer(),
);
return filterId == null
? insertFilter(
fieldId: fieldId,
fieldType: FieldType.RichText,
data: filter.writeToBuffer(),
)
: updateFilter(
filterId: filterId,
fieldId: fieldId,
fieldType: FieldType.RichText,
data: filter.writeToBuffer(),
);
}
Future<FlowyResult<void, FlowyError>> insertCheckboxFilter({
@ -55,12 +61,18 @@ class FilterBackendService {
}) {
final filter = CheckboxFilterPB()..condition = condition;
return insertFilter(
fieldId: fieldId,
filterId: filterId,
fieldType: FieldType.Checkbox,
data: filter.writeToBuffer(),
);
return filterId == null
? insertFilter(
fieldId: fieldId,
fieldType: FieldType.Checkbox,
data: filter.writeToBuffer(),
)
: updateFilter(
filterId: filterId,
fieldId: fieldId,
fieldType: FieldType.Checkbox,
data: filter.writeToBuffer(),
);
}
Future<FlowyResult<void, FlowyError>> insertNumberFilter({
@ -73,12 +85,18 @@ class FilterBackendService {
..condition = condition
..content = content;
return insertFilter(
fieldId: fieldId,
filterId: filterId,
fieldType: FieldType.Number,
data: filter.writeToBuffer(),
);
return filterId == null
? insertFilter(
fieldId: fieldId,
fieldType: FieldType.Number,
data: filter.writeToBuffer(),
)
: updateFilter(
filterId: filterId,
fieldId: fieldId,
fieldType: FieldType.Number,
data: filter.writeToBuffer(),
);
}
Future<FlowyResult<void, FlowyError>> insertDateFilter({
@ -112,12 +130,18 @@ class FilterBackendService {
}
}
return insertFilter(
fieldId: fieldId,
filterId: filterId,
fieldType: fieldType,
data: filter.writeToBuffer(),
);
return filterId == null
? insertFilter(
fieldId: fieldId,
fieldType: FieldType.DateTime,
data: filter.writeToBuffer(),
)
: updateFilter(
filterId: filterId,
fieldId: fieldId,
fieldType: FieldType.DateTime,
data: filter.writeToBuffer(),
);
}
Future<FlowyResult<void, FlowyError>> insertURLFilter({
@ -130,12 +154,18 @@ class FilterBackendService {
..condition = condition
..content = content;
return insertFilter(
fieldId: fieldId,
filterId: filterId,
fieldType: FieldType.URL,
data: filter.writeToBuffer(),
);
return filterId == null
? insertFilter(
fieldId: fieldId,
fieldType: FieldType.URL,
data: filter.writeToBuffer(),
)
: updateFilter(
filterId: filterId,
fieldId: fieldId,
fieldType: FieldType.URL,
data: filter.writeToBuffer(),
);
}
Future<FlowyResult<void, FlowyError>> insertSelectOptionFilter({
@ -149,12 +179,18 @@ class FilterBackendService {
..condition = condition
..optionIds.addAll(optionIds);
return insertFilter(
fieldId: fieldId,
filterId: filterId,
fieldType: fieldType,
data: filter.writeToBuffer(),
);
return filterId == null
? insertFilter(
fieldId: fieldId,
fieldType: fieldType,
data: filter.writeToBuffer(),
)
: updateFilter(
filterId: filterId,
fieldId: fieldId,
fieldType: fieldType,
data: filter.writeToBuffer(),
);
}
Future<FlowyResult<void, FlowyError>> insertChecklistFilter({
@ -165,67 +201,94 @@ class FilterBackendService {
}) {
final filter = ChecklistFilterPB()..condition = condition;
return insertFilter(
fieldId: fieldId,
filterId: filterId,
fieldType: FieldType.Checklist,
data: filter.writeToBuffer(),
);
return filterId == null
? insertFilter(
fieldId: fieldId,
fieldType: FieldType.Checklist,
data: filter.writeToBuffer(),
)
: updateFilter(
filterId: filterId,
fieldId: fieldId,
fieldType: FieldType.Checklist,
data: filter.writeToBuffer(),
);
}
Future<FlowyResult<void, FlowyError>> insertFilter({
required String fieldId,
String? filterId,
required FieldType fieldType,
required List<int> data,
}) {
final insertFilterPayload = UpdateFilterPayloadPB.create()
}) async {
final filterData = FilterDataPB()
..fieldId = fieldId
..fieldType = fieldType
..viewId = viewId
..data = data;
if (filterId != null) {
insertFilterPayload.filterId = filterId;
}
final insertFilterPayload = InsertFilterPB()..data = filterData;
final payload = DatabaseSettingChangesetPB.create()
final payload = DatabaseSettingChangesetPB()
..viewId = viewId
..updateFilter = insertFilterPayload;
return DatabaseEventUpdateDatabaseSetting(payload).send().then((result) {
return result.fold(
(l) => FlowyResult.success(l),
(err) {
Log.error(err);
return FlowyResult.failure(err);
},
);
});
..insertFilter = insertFilterPayload;
final result = await DatabaseEventUpdateDatabaseSetting(payload).send();
return result.fold(
(l) => FlowyResult.success(l),
(err) {
Log.error(err);
return FlowyResult.failure(err);
},
);
}
Future<FlowyResult<void, FlowyError>> updateFilter({
required String filterId,
required String fieldId,
required FieldType fieldType,
required List<int> data,
}) async {
final filterData = FilterDataPB()
..fieldId = fieldId
..fieldType = fieldType
..data = data;
final updateFilterPayload = UpdateFilterDataPB()
..filterId = filterId
..data = filterData;
final payload = DatabaseSettingChangesetPB()
..viewId = viewId
..updateFilterData = updateFilterPayload;
final result = await DatabaseEventUpdateDatabaseSetting(payload).send();
return result.fold(
(l) => FlowyResult.success(l),
(err) {
Log.error(err);
return FlowyResult.failure(err);
},
);
}
Future<FlowyResult<void, FlowyError>> deleteFilter({
required String fieldId,
required String filterId,
required FieldType fieldType,
}) {
final deleteFilterPayload = DeleteFilterPayloadPB.create()
}) async {
final deleteFilterPayload = DeleteFilterPB()
..fieldId = fieldId
..filterId = filterId
..viewId = viewId
..fieldType = fieldType;
..filterId = filterId;
final payload = DatabaseSettingChangesetPB.create()
final payload = DatabaseSettingChangesetPB()
..viewId = viewId
..deleteFilter = deleteFilterPayload;
return DatabaseEventUpdateDatabaseSetting(payload).send().then((result) {
return result.fold(
(l) => FlowyResult.success(l),
(err) {
Log.error(err);
return FlowyResult.failure(err);
},
);
});
final result = await DatabaseEventUpdateDatabaseSetting(payload).send();
return result.fold(
(l) => FlowyResult.success(l),
(err) {
Log.error(err);
return FlowyResult.failure(err);
},
);
}
}