chore: move database domain code to its own folder (#4556)

This commit is contained in:
Richard Shiue
2024-02-25 18:38:18 +08:00
committed by GitHub
parent d861ce6227
commit 537fa52e77
64 changed files with 78 additions and 94 deletions

View File

@ -0,0 +1,53 @@
import 'dart:async';
import 'dart:typed_data';
import 'package:appflowy/core/notification/grid_notification.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/notification.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
import 'package:appflowy_result/appflowy_result.dart';
import 'package:flowy_infra/notifier.dart';
import '../application/row/row_service.dart';
typedef UpdateFieldNotifiedValue = FlowyResult<void, FlowyError>;
class CellListener {
CellListener({required this.rowId, required this.fieldId});
final RowId rowId;
final String fieldId;
PublishNotifier<UpdateFieldNotifiedValue>? _updateCellNotifier =
PublishNotifier();
DatabaseNotificationListener? _listener;
void start({required void Function(UpdateFieldNotifiedValue) onCellChanged}) {
_updateCellNotifier?.addPublishListener(onCellChanged);
_listener = DatabaseNotificationListener(
objectId: "$rowId:$fieldId",
handler: _handler,
);
}
void _handler(
DatabaseNotification ty,
FlowyResult<Uint8List, FlowyError> result,
) {
switch (ty) {
case DatabaseNotification.DidUpdateCell:
result.fold(
(payload) => _updateCellNotifier?.value = FlowyResult.success(null),
(error) => _updateCellNotifier?.value = FlowyResult.failure(error),
);
break;
default:
break;
}
}
Future<void> stop() async {
await _listener?.stop();
_updateCellNotifier?.dispose();
_updateCellNotifier = null;
}
}

View File

@ -0,0 +1,36 @@
import 'dart:async';
import 'package:appflowy_backend/dispatch/dispatch.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 '../application/cell/cell_controller.dart';
class CellBackendService {
CellBackendService();
static Future<FlowyResult<void, FlowyError>> updateCell({
required String viewId,
required CellContext cellContext,
required String data,
}) {
final payload = CellChangesetPB()
..viewId = viewId
..fieldId = cellContext.fieldId
..rowId = cellContext.rowId
..cellChangeset = data;
return DatabaseEventUpdateCell(payload).send();
}
static Future<FlowyResult<CellPB, FlowyError>> getCell({
required String viewId,
required CellContext cellContext,
}) {
final payload = CellIdPB()
..viewId = viewId
..fieldId = cellContext.fieldId
..rowId = cellContext.rowId;
return DatabaseEventGetCell(payload).send();
}
}

View File

@ -0,0 +1,71 @@
import 'package:appflowy_backend/dispatch/dispatch.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/checklist_entities.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/select_option_entities.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
import 'package:appflowy_result/appflowy_result.dart';
import 'package:protobuf/protobuf.dart';
class ChecklistCellBackendService {
ChecklistCellBackendService({
required this.viewId,
required this.fieldId,
required this.rowId,
});
final String viewId;
final String fieldId;
final String rowId;
Future<FlowyResult<void, FlowyError>> create({
required String name,
}) {
final payload = ChecklistCellDataChangesetPB.create()
..viewId = viewId
..fieldId = fieldId
..rowId = rowId
..insertOptions.add(name);
return DatabaseEventUpdateChecklistCell(payload).send();
}
Future<FlowyResult<void, FlowyError>> delete({
required List<String> optionIds,
}) {
final payload = ChecklistCellDataChangesetPB.create()
..viewId = viewId
..fieldId = fieldId
..rowId = rowId
..deleteOptionIds.addAll(optionIds);
return DatabaseEventUpdateChecklistCell(payload).send();
}
Future<FlowyResult<void, FlowyError>> select({
required String optionId,
}) {
final payload = ChecklistCellDataChangesetPB.create()
..viewId = viewId
..fieldId = fieldId
..rowId = rowId
..selectedOptionIds.add(optionId);
return DatabaseEventUpdateChecklistCell(payload).send();
}
Future<FlowyResult<void, FlowyError>> updateName({
required SelectOptionPB option,
required name,
}) {
option.freeze();
final newOption = option.rebuild((option) {
option.name = name;
});
final payload = ChecklistCellDataChangesetPB.create()
..viewId = viewId
..fieldId = fieldId
..rowId = rowId
..updateOptions.add(newOption);
return DatabaseEventUpdateChecklistCell(payload).send();
}
}

View File

@ -0,0 +1,16 @@
import 'package:appflowy_backend/dispatch/dispatch.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/database_entities.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
import 'package:appflowy_result/appflowy_result.dart';
class DatabaseBackendService {
static Future<FlowyResult<List<DatabaseDescriptionPB>, FlowyError>>
getAllDatabases() {
return DatabaseEventGetDatabases().send().then((result) {
return result.fold(
(l) => FlowyResult.success(l.items),
(r) => FlowyResult.failure(r),
);
});
}
}

View File

@ -0,0 +1,136 @@
import 'package:appflowy/plugins/database/application/row/row_service.dart';
import 'package:appflowy_backend/dispatch/dispatch.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:appflowy_result/appflowy_result.dart';
import 'layout_service.dart';
class DatabaseViewBackendService {
DatabaseViewBackendService({required this.viewId});
final String viewId;
/// Returns the database id associated with the view.
Future<FlowyResult<String, FlowyError>> getDatabaseId() async {
final payload = DatabaseViewIdPB(value: viewId);
return DatabaseEventGetDatabaseId(payload)
.send()
.then((value) => value.map((l) => l.value));
}
static Future<FlowyResult<ViewPB, FlowyError>> updateLayout({
required String viewId,
required DatabaseLayoutPB layout,
}) {
final payload = UpdateViewPayloadPB.create()
..viewId = viewId
..layout = viewLayoutFromDatabaseLayout(layout);
return FolderEventUpdateView(payload).send();
}
Future<FlowyResult<DatabasePB, FlowyError>> openDatabase() async {
final payload = DatabaseViewIdPB(value: viewId);
return DatabaseEventGetDatabase(payload).send();
}
Future<FlowyResult<void, FlowyError>> moveGroupRow({
required RowId fromRowId,
required String fromGroupId,
required String toGroupId,
RowId? toRowId,
}) {
final payload = MoveGroupRowPayloadPB.create()
..viewId = viewId
..fromRowId = fromRowId
..fromGroupId = fromGroupId
..toGroupId = toGroupId;
if (toRowId != null) {
payload.toRowId = toRowId;
}
return DatabaseEventMoveGroupRow(payload).send();
}
Future<FlowyResult<void, FlowyError>> moveRow({
required String fromRowId,
required String toRowId,
}) {
final payload = MoveRowPayloadPB.create()
..viewId = viewId
..fromRowId = fromRowId
..toRowId = toRowId;
return DatabaseEventMoveRow(payload).send();
}
Future<FlowyResult<void, FlowyError>> moveGroup({
required String fromGroupId,
required String toGroupId,
}) {
final payload = MoveGroupPayloadPB.create()
..viewId = viewId
..fromGroupId = fromGroupId
..toGroupId = toGroupId;
return DatabaseEventMoveGroup(payload).send();
}
Future<FlowyResult<List<FieldPB>, FlowyError>> getFields({
List<FieldIdPB>? fieldIds,
}) {
final payload = GetFieldPayloadPB.create()..viewId = viewId;
if (fieldIds != null) {
payload.fieldIds = RepeatedFieldIdPB(items: fieldIds);
}
return DatabaseEventGetFields(payload).send().then((result) {
return result.fold(
(l) => FlowyResult.success(l.items),
(r) => FlowyResult.failure(r),
);
});
}
Future<FlowyResult<DatabaseLayoutSettingPB, FlowyError>> getLayoutSetting(
DatabaseLayoutPB layoutType,
) {
final payload = DatabaseLayoutMetaPB.create()
..viewId = viewId
..layout = layoutType;
return DatabaseEventGetLayoutSetting(payload).send();
}
Future<FlowyResult<void, FlowyError>> updateLayoutSetting({
required DatabaseLayoutPB layoutType,
BoardLayoutSettingPB? boardLayoutSetting,
CalendarLayoutSettingPB? calendarLayoutSetting,
}) {
final payload = LayoutSettingChangesetPB.create()
..viewId = viewId
..layoutType = layoutType;
if (boardLayoutSetting != null) {
payload.board = boardLayoutSetting;
}
if (calendarLayoutSetting != null) {
payload.calendar = calendarLayoutSetting;
}
return DatabaseEventSetLayoutSetting(payload).send();
}
Future<FlowyResult<void, FlowyError>> closeView() {
final request = ViewIdPB(value: viewId);
return FolderEventCloseView(request).send();
}
Future<FlowyResult<RepeatedGroupPB, FlowyError>> loadGroups() {
final payload = DatabaseViewIdPB(value: viewId);
return DatabaseEventGetGroups(payload).send();
}
}

View File

@ -0,0 +1,62 @@
import 'package:appflowy_backend/dispatch/dispatch.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/cell_entities.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/date_entities.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
import 'package:appflowy_result/appflowy_result.dart';
import 'package:fixnum/fixnum.dart';
final class DateCellBackendService {
DateCellBackendService({
required String viewId,
required String fieldId,
required String rowId,
}) : cellId = CellIdPB.create()
..viewId = viewId
..fieldId = fieldId
..rowId = rowId;
final CellIdPB cellId;
Future<FlowyResult<void, FlowyError>> update({
required bool includeTime,
required bool isRange,
DateTime? date,
String? time,
DateTime? endDate,
String? endTime,
String? reminderId,
}) {
final payload = DateCellChangesetPB.create()
..cellId = cellId
..includeTime = includeTime
..isRange = isRange;
if (date != null) {
final dateTimestamp = date.millisecondsSinceEpoch ~/ 1000;
payload.date = Int64(dateTimestamp);
}
if (time != null) {
payload.time = time;
}
if (endDate != null) {
final dateTimestamp = endDate.millisecondsSinceEpoch ~/ 1000;
payload.endDate = Int64(dateTimestamp);
}
if (endTime != null) {
payload.endTime = endTime;
}
if (reminderId != null) {
payload.reminderId = reminderId;
}
return DatabaseEventUpdateDateCell(payload).send();
}
Future<FlowyResult<void, FlowyError>> clear() {
final payload = DateCellChangesetPB.create()
..cellId = cellId
..clearFlag = true;
return DatabaseEventUpdateDateCell(payload).send();
}
}

View File

@ -0,0 +1,79 @@
import 'package:appflowy/plugins/database/domain/field_service.dart';
import 'package:appflowy/plugins/database/domain/field_settings_service.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
// This class is used for combining the
// 1. FieldBackendService
// 2. FieldSettingsBackendService
// 3. TypeOptionBackendService
//
// including,
// hide, delete, duplicated,
// insertLeft, insertRight,
// updateName
class FieldServices {
FieldServices({
required this.viewId,
required this.fieldId,
}) : fieldBackendService = FieldBackendService(
viewId: viewId,
fieldId: fieldId,
),
fieldSettingsService = FieldSettingsBackendService(
viewId: viewId,
);
final String viewId;
final String fieldId;
final FieldBackendService fieldBackendService;
final FieldSettingsBackendService fieldSettingsService;
Future<void> hide() async {
await fieldSettingsService.updateFieldSettings(
fieldId: fieldId,
fieldVisibility: FieldVisibility.AlwaysHidden,
);
}
Future<void> show() async {
await fieldSettingsService.updateFieldSettings(
fieldId: fieldId,
fieldVisibility: FieldVisibility.AlwaysShown,
);
}
Future<void> delete() async {
await fieldBackendService.delete();
}
Future<void> duplicate() async {
await fieldBackendService.duplicate();
}
Future<void> insertLeft() async {
await FieldBackendService.createField(
viewId: viewId,
position: OrderObjectPositionPB(
position: OrderObjectPositionTypePB.Before,
objectId: fieldId,
),
);
}
Future<void> insertRight() async {
await FieldBackendService.createField(
viewId: viewId,
position: OrderObjectPositionPB(
position: OrderObjectPositionTypePB.After,
objectId: fieldId,
),
);
}
Future<void> updateName(String name) async {
await fieldBackendService.updateField(
name: name,
);
}
}

View File

@ -0,0 +1,97 @@
import 'dart:async';
import 'dart:typed_data';
import 'package:appflowy/core/notification/grid_notification.dart';
import 'package:appflowy_backend/log.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:flowy_infra/notifier.dart';
typedef UpdateFieldNotifiedValue = FieldPB;
class SingleFieldListener {
SingleFieldListener({required this.fieldId});
final String fieldId;
void Function(UpdateFieldNotifiedValue)? _updateFieldNotifier;
DatabaseNotificationListener? _listener;
void start({
required void Function(UpdateFieldNotifiedValue) onFieldChanged,
}) {
_updateFieldNotifier = onFieldChanged;
_listener = DatabaseNotificationListener(
objectId: fieldId,
handler: _handler,
);
}
void _handler(
DatabaseNotification ty,
FlowyResult<Uint8List, FlowyError> result,
) {
switch (ty) {
case DatabaseNotification.DidUpdateField:
result.fold(
(payload) => _updateFieldNotifier?.call(FieldPB.fromBuffer(payload)),
(error) => Log.error(error),
);
break;
default:
break;
}
}
Future<void> stop() async {
await _listener?.stop();
_updateFieldNotifier = null;
}
}
typedef UpdateFieldsNotifiedValue
= FlowyResult<DatabaseFieldChangesetPB, FlowyError>;
class FieldsListener {
FieldsListener({required this.viewId});
final String viewId;
PublishNotifier<UpdateFieldsNotifiedValue>? updateFieldsNotifier =
PublishNotifier();
DatabaseNotificationListener? _listener;
void start({
required void Function(UpdateFieldsNotifiedValue) onFieldsChanged,
}) {
updateFieldsNotifier?.addPublishListener(onFieldsChanged);
_listener = DatabaseNotificationListener(
objectId: viewId,
handler: _handler,
);
}
void _handler(
DatabaseNotification ty,
FlowyResult<Uint8List, FlowyError> result,
) {
switch (ty) {
case DatabaseNotification.DidUpdateFields:
result.fold(
(payload) => updateFieldsNotifier?.value =
FlowyResult.success(DatabaseFieldChangesetPB.fromBuffer(payload)),
(error) => updateFieldsNotifier?.value = FlowyResult.failure(error),
);
break;
default:
break;
}
}
Future<void> stop() async {
await _listener?.stop();
updateFieldsNotifier?.dispose();
updateFieldsNotifier = null;
}
}

View File

@ -0,0 +1,182 @@
import 'dart:typed_data';
import 'package:appflowy_backend/dispatch/dispatch.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';
/// FieldService provides many field-related interfaces event functions. Check out
/// `rust-lib/flowy-database/event_map.rs` for a list of events and their
/// implementations.
class FieldBackendService {
FieldBackendService({required this.viewId, required this.fieldId});
final String viewId;
final String fieldId;
/// Create a field in a database view. The position will only be applicable
/// in this view; for other views it will be appended to the end
static Future<FlowyResult<FieldPB, FlowyError>> createField({
required String viewId,
FieldType fieldType = FieldType.RichText,
String? fieldName,
Uint8List? typeOptionData,
OrderObjectPositionPB? position,
}) {
final payload = CreateFieldPayloadPB(
viewId: viewId,
fieldType: fieldType,
fieldName: fieldName,
typeOptionData: typeOptionData,
fieldPosition: position,
);
return DatabaseEventCreateField(payload).send();
}
/// Reorder a field within a database view
static Future<FlowyResult<void, FlowyError>> moveField({
required String viewId,
required String fromFieldId,
required String toFieldId,
}) {
final payload = MoveFieldPayloadPB(
viewId: viewId,
fromFieldId: fromFieldId,
toFieldId: toFieldId,
);
return DatabaseEventMoveField(payload).send();
}
/// Delete a field
static Future<FlowyResult<void, FlowyError>> deleteField({
required String viewId,
required String fieldId,
}) {
final payload = DeleteFieldPayloadPB(
viewId: viewId,
fieldId: fieldId,
);
return DatabaseEventDeleteField(payload).send();
}
/// Duplicate a field
static Future<FlowyResult<void, FlowyError>> duplicateField({
required String viewId,
required String fieldId,
}) {
final payload = DuplicateFieldPayloadPB(
viewId: viewId,
fieldId: fieldId,
);
return DatabaseEventDuplicateField(payload).send();
}
/// Update a field's properties
Future<FlowyResult<void, FlowyError>> updateField({
String? name,
bool? frozen,
}) {
final payload = FieldChangesetPB.create()
..viewId = viewId
..fieldId = fieldId;
if (name != null) {
payload.name = name;
}
if (frozen != null) {
payload.frozen = frozen;
}
return DatabaseEventUpdateField(payload).send();
}
/// Change a field's type
static Future<FlowyResult<void, FlowyError>> updateFieldType({
required String viewId,
required String fieldId,
required FieldType fieldType,
}) {
final payload = UpdateFieldTypePayloadPB()
..viewId = viewId
..fieldId = fieldId
..fieldType = fieldType;
return DatabaseEventUpdateFieldType(payload).send();
}
/// Update a field's type option data
static Future<FlowyResult<void, FlowyError>> updateFieldTypeOption({
required String viewId,
required String fieldId,
required List<int> typeOptionData,
}) {
final payload = TypeOptionChangesetPB.create()
..viewId = viewId
..fieldId = fieldId
..typeOptionData = typeOptionData;
return DatabaseEventUpdateFieldTypeOption(payload).send();
}
/// Returns the primary field of the view.
static Future<FlowyResult<FieldPB, FlowyError>> getPrimaryField({
required String viewId,
}) {
final payload = DatabaseViewIdPB.create()..value = viewId;
return DatabaseEventGetPrimaryField(payload).send();
}
Future<FlowyResult<FieldPB, FlowyError>> createBefore({
FieldType fieldType = FieldType.RichText,
String? fieldName,
Uint8List? typeOptionData,
}) {
return createField(
viewId: viewId,
fieldType: fieldType,
fieldName: fieldName,
typeOptionData: typeOptionData,
position: OrderObjectPositionPB(
position: OrderObjectPositionTypePB.Before,
objectId: fieldId,
),
);
}
Future<FlowyResult<FieldPB, FlowyError>> createAfter({
FieldType fieldType = FieldType.RichText,
String? fieldName,
Uint8List? typeOptionData,
}) {
return createField(
viewId: viewId,
fieldType: fieldType,
fieldName: fieldName,
typeOptionData: typeOptionData,
position: OrderObjectPositionPB(
position: OrderObjectPositionTypePB.After,
objectId: fieldId,
),
);
}
Future<FlowyResult<void, FlowyError>> updateType({
required FieldType fieldType,
}) =>
updateFieldType(
viewId: viewId,
fieldId: fieldId,
fieldType: fieldType,
);
Future<FlowyResult<void, FlowyError>> delete() =>
deleteField(viewId: viewId, fieldId: fieldId);
Future<FlowyResult<void, FlowyError>> duplicate() =>
duplicateField(viewId: viewId, fieldId: fieldId);
}

View File

@ -0,0 +1,52 @@
import 'dart:typed_data';
import 'package:appflowy/core/notification/grid_notification.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:flowy_infra/notifier.dart';
typedef FieldSettingsValue = FlowyResult<FieldSettingsPB, FlowyError>;
class FieldSettingsListener {
FieldSettingsListener({required this.viewId});
final String viewId;
PublishNotifier<FieldSettingsValue>? _fieldSettingsNotifier =
PublishNotifier();
DatabaseNotificationListener? _listener;
void start({
required void Function(FieldSettingsValue) onFieldSettingsChanged,
}) {
_fieldSettingsNotifier?.addPublishListener(onFieldSettingsChanged);
_listener = DatabaseNotificationListener(
objectId: viewId,
handler: _handler,
);
}
void _handler(
DatabaseNotification ty,
FlowyResult<Uint8List, FlowyError> result,
) {
switch (ty) {
case DatabaseNotification.DidUpdateFieldSettings:
result.fold(
(payload) => _fieldSettingsNotifier?.value =
FlowyResult.success(FieldSettingsPB.fromBuffer(payload)),
(error) => _fieldSettingsNotifier?.value = FlowyResult.failure(error),
);
break;
default:
break;
}
}
Future<void> stop() async {
await _listener?.stop();
_fieldSettingsNotifier?.dispose();
_fieldSettingsNotifier = null;
}
}

View File

@ -0,0 +1,76 @@
import 'package:appflowy_backend/dispatch/dispatch.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';
class FieldSettingsBackendService {
FieldSettingsBackendService({required this.viewId});
final String viewId;
Future<FlowyResult<FieldSettingsPB, FlowyError>> getFieldSettings(
String fieldId,
) {
final id = FieldIdPB(fieldId: fieldId);
final ids = RepeatedFieldIdPB()..items.add(id);
final payload = FieldIdsPB()
..viewId = viewId
..fieldIds = ids;
return DatabaseEventGetFieldSettings(payload).send().then((result) {
return result.fold(
(repeatedFieldSettings) {
final fieldSetting = repeatedFieldSettings.items.first;
if (!fieldSetting.hasVisibility()) {
fieldSetting.visibility = FieldVisibility.AlwaysShown;
}
return FlowyResult.success(fieldSetting);
},
(r) => FlowyResult.failure(r),
);
});
}
Future<FlowyResult<List<FieldSettingsPB>, FlowyError>> getAllFieldSettings() {
final payload = DatabaseViewIdPB()..value = viewId;
return DatabaseEventGetAllFieldSettings(payload).send().then((result) {
return result.fold(
(repeatedFieldSettings) {
final fieldSettings = <FieldSettingsPB>[];
for (final fieldSetting in repeatedFieldSettings.items) {
if (!fieldSetting.hasVisibility()) {
fieldSetting.visibility = FieldVisibility.AlwaysShown;
}
fieldSettings.add(fieldSetting);
}
return FlowyResult.success(fieldSettings);
},
(r) => FlowyResult.failure(r),
);
});
}
Future<FlowyResult<void, FlowyError>> updateFieldSettings({
required String fieldId,
FieldVisibility? fieldVisibility,
double? width,
}) {
final FieldSettingsChangesetPB payload = FieldSettingsChangesetPB.create()
..viewId = viewId
..fieldId = fieldId;
if (fieldVisibility != null) {
payload.visibility = fieldVisibility;
}
if (width != null) {
payload.width = width.round();
}
return DatabaseEventUpdateFieldSettings(payload).send();
}
}

View File

@ -0,0 +1,131 @@
import 'dart:typed_data';
import 'package:appflowy/core/notification/grid_notification.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/filter_changeset.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/notification.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/util.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
import 'package:appflowy_result/appflowy_result.dart';
import 'package:flowy_infra/notifier.dart';
typedef UpdateFilterNotifiedValue
= FlowyResult<FilterChangesetNotificationPB, FlowyError>;
class FiltersListener {
FiltersListener({required this.viewId});
final String viewId;
PublishNotifier<UpdateFilterNotifiedValue>? _filterNotifier =
PublishNotifier();
DatabaseNotificationListener? _listener;
void start({
required void Function(UpdateFilterNotifiedValue) onFilterChanged,
}) {
_filterNotifier?.addPublishListener(onFilterChanged);
_listener = DatabaseNotificationListener(
objectId: viewId,
handler: _handler,
);
}
void _handler(
DatabaseNotification ty,
FlowyResult<Uint8List, FlowyError> result,
) {
switch (ty) {
case DatabaseNotification.DidUpdateFilter:
result.fold(
(payload) => _filterNotifier?.value = FlowyResult.success(
FilterChangesetNotificationPB.fromBuffer(payload),
),
(error) => _filterNotifier?.value = FlowyResult.failure(error),
);
break;
default:
break;
}
}
Future<void> stop() async {
await _listener?.stop();
_filterNotifier?.dispose();
_filterNotifier = null;
}
}
class FilterListener {
FilterListener({required this.viewId, required this.filterId});
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();
});
_onUpdateNotifier?.addPublishListener((filter) {
onUpdated?.call(filter);
});
_listener = DatabaseNotificationListener(
objectId: viewId,
handler: _handler,
);
}
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,
);
if (updatedIndex != -1) {
_onUpdateNotifier?.value = changeset.updateFilters[updatedIndex].filter;
}
}
void _handler(
DatabaseNotification ty,
FlowyResult<Uint8List, FlowyError> result,
) {
switch (ty) {
case DatabaseNotification.DidUpdateFilter:
result.fold(
(payload) => handleChangeset(
FilterChangesetNotificationPB.fromBuffer(payload),
),
(error) {},
);
break;
default:
break;
}
}
Future<void> stop() async {
await _listener?.stop();
_onDeleteNotifier?.dispose();
_onDeleteNotifier = null;
_onUpdateNotifier?.dispose();
_onUpdateNotifier = null;
}
}

View File

@ -0,0 +1,231 @@
import 'package:appflowy_backend/dispatch/dispatch.dart';
import 'package:appflowy_backend/log.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/checkbox_filter.pbserver.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/checklist_filter.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/database_entities.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/date_filter.pbserver.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/number_filter.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/select_option_filter.pbserver.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/setting_entities.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/text_filter.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/util.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
import 'package:appflowy_result/appflowy_result.dart';
import 'package:fixnum/fixnum.dart' as $fixnum;
class FilterBackendService {
const FilterBackendService({required this.viewId});
final String viewId;
Future<FlowyResult<List<FilterPB>, FlowyError>> getAllFilters() {
final payload = DatabaseViewIdPB()..value = viewId;
return DatabaseEventGetAllFilters(payload).send().then((result) {
return result.fold(
(repeated) => FlowyResult.success(repeated.items),
(r) => FlowyResult.failure(r),
);
});
}
Future<FlowyResult<void, FlowyError>> insertTextFilter({
required String fieldId,
String? filterId,
required TextFilterConditionPB condition,
required String content,
}) {
final filter = TextFilterPB()
..condition = condition
..content = content;
return insertFilter(
fieldId: fieldId,
filterId: filterId,
fieldType: FieldType.RichText,
data: filter.writeToBuffer(),
);
}
Future<FlowyResult<void, FlowyError>> insertCheckboxFilter({
required String fieldId,
String? filterId,
required CheckboxFilterConditionPB condition,
}) {
final filter = CheckboxFilterPB()..condition = condition;
return insertFilter(
fieldId: fieldId,
filterId: filterId,
fieldType: FieldType.Checkbox,
data: filter.writeToBuffer(),
);
}
Future<FlowyResult<void, FlowyError>> insertNumberFilter({
required String fieldId,
String? filterId,
required NumberFilterConditionPB condition,
String content = "",
}) {
final filter = NumberFilterPB()
..condition = condition
..content = content;
return insertFilter(
fieldId: fieldId,
filterId: filterId,
fieldType: FieldType.Number,
data: filter.writeToBuffer(),
);
}
Future<FlowyResult<void, FlowyError>> insertDateFilter({
required String fieldId,
String? filterId,
required DateFilterConditionPB condition,
required FieldType fieldType,
int? start,
int? end,
int? timestamp,
}) {
assert(
[
FieldType.DateTime,
FieldType.LastEditedTime,
FieldType.CreatedTime,
].contains(fieldType),
);
final filter = DateFilterPB();
if (timestamp != null) {
filter.timestamp = $fixnum.Int64(timestamp);
} else {
if (start != null && end != null) {
filter.start = $fixnum.Int64(start);
filter.end = $fixnum.Int64(end);
} else {
throw Exception(
"Start and end should not be null if the timestamp is null",
);
}
}
return insertFilter(
fieldId: fieldId,
filterId: filterId,
fieldType: fieldType,
data: filter.writeToBuffer(),
);
}
Future<FlowyResult<void, FlowyError>> insertURLFilter({
required String fieldId,
String? filterId,
required TextFilterConditionPB condition,
String content = "",
}) {
final filter = TextFilterPB()
..condition = condition
..content = content;
return insertFilter(
fieldId: fieldId,
filterId: filterId,
fieldType: FieldType.URL,
data: filter.writeToBuffer(),
);
}
Future<FlowyResult<void, FlowyError>> insertSelectOptionFilter({
required String fieldId,
required FieldType fieldType,
required SelectOptionConditionPB condition,
String? filterId,
List<String> optionIds = const [],
}) {
final filter = SelectOptionFilterPB()
..condition = condition
..optionIds.addAll(optionIds);
return insertFilter(
fieldId: fieldId,
filterId: filterId,
fieldType: fieldType,
data: filter.writeToBuffer(),
);
}
Future<FlowyResult<void, FlowyError>> insertChecklistFilter({
required String fieldId,
required ChecklistFilterConditionPB condition,
String? filterId,
List<String> optionIds = const [],
}) {
final filter = ChecklistFilterPB()..condition = condition;
return insertFilter(
fieldId: fieldId,
filterId: filterId,
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()
..fieldId = fieldId
..fieldType = fieldType
..viewId = viewId
..data = data;
if (filterId != null) {
insertFilterPayload.filterId = filterId;
}
final payload = DatabaseSettingChangesetPB.create()
..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);
},
);
});
}
Future<FlowyResult<void, FlowyError>> deleteFilter({
required String fieldId,
required String filterId,
required FieldType fieldType,
}) {
final deleteFilterPayload = DeleteFilterPayloadPB.create()
..fieldId = fieldId
..filterId = filterId
..viewId = viewId
..fieldType = fieldType;
final payload = DatabaseSettingChangesetPB.create()
..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);
},
);
});
}
}

View File

@ -0,0 +1,71 @@
import 'dart:typed_data';
import 'package:appflowy/core/notification/grid_notification.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/group.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/group_changeset.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/notification.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
import 'package:appflowy_result/appflowy_result.dart';
import 'package:flowy_infra/notifier.dart';
typedef GroupConfigurationUpdateValue
= FlowyResult<List<GroupSettingPB>, FlowyError>;
typedef GroupUpdateValue = FlowyResult<GroupChangesPB, FlowyError>;
typedef GroupByNewFieldValue = FlowyResult<List<GroupPB>, FlowyError>;
class DatabaseGroupListener {
DatabaseGroupListener(this.viewId);
final String viewId;
PublishNotifier<GroupUpdateValue>? _numOfGroupsNotifier = PublishNotifier();
PublishNotifier<GroupByNewFieldValue>? _groupByFieldNotifier =
PublishNotifier();
DatabaseNotificationListener? _listener;
void start({
required void Function(GroupUpdateValue) onNumOfGroupsChanged,
required void Function(GroupByNewFieldValue) onGroupByNewField,
}) {
_numOfGroupsNotifier?.addPublishListener(onNumOfGroupsChanged);
_groupByFieldNotifier?.addPublishListener(onGroupByNewField);
_listener = DatabaseNotificationListener(
objectId: viewId,
handler: _handler,
);
}
void _handler(
DatabaseNotification ty,
FlowyResult<Uint8List, FlowyError> result,
) {
switch (ty) {
case DatabaseNotification.DidUpdateNumOfGroups:
result.fold(
(payload) => _numOfGroupsNotifier?.value =
FlowyResult.success(GroupChangesPB.fromBuffer(payload)),
(error) => _numOfGroupsNotifier?.value = FlowyResult.failure(error),
);
break;
case DatabaseNotification.DidGroupByField:
result.fold(
(payload) => _groupByFieldNotifier?.value = FlowyResult.success(
GroupChangesPB.fromBuffer(payload).initialGroups,
),
(error) => _groupByFieldNotifier?.value = FlowyResult.failure(error),
);
break;
default:
break;
}
}
Future<void> stop() async {
await _listener?.stop();
_numOfGroupsNotifier?.dispose();
_numOfGroupsNotifier = null;
_groupByFieldNotifier?.dispose();
_groupByFieldNotifier = null;
}
}

View File

@ -0,0 +1,61 @@
import 'package:appflowy_backend/dispatch/dispatch.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/group.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
import 'package:appflowy_result/appflowy_result.dart';
class GroupBackendService {
GroupBackendService(this.viewId);
final String viewId;
Future<FlowyResult<void, FlowyError>> groupByField({
required String fieldId,
}) {
final payload = GroupByFieldPayloadPB.create()
..viewId = viewId
..fieldId = fieldId;
return DatabaseEventSetGroupByField(payload).send();
}
Future<FlowyResult<void, FlowyError>> updateGroup({
required String groupId,
required String fieldId,
String? name,
bool? visible,
}) {
final payload = UpdateGroupPB.create()
..fieldId = fieldId
..viewId = viewId
..groupId = groupId;
if (name != null) {
payload.name = name;
}
if (visible != null) {
payload.visible = visible;
}
return DatabaseEventUpdateGroup(payload).send();
}
Future<FlowyResult<void, FlowyError>> createGroup({
required String name,
String groupConfigId = "",
}) {
final payload = CreateGroupPayloadPB.create()
..viewId = viewId
..name = name;
return DatabaseEventCreateGroup(payload).send();
}
Future<FlowyResult<void, FlowyError>> deleteGroup({
required String groupId,
}) {
final payload = DeleteGroupPayloadPB.create()
..viewId = viewId
..groupId = groupId;
return DatabaseEventDeleteGroup(payload).send();
}
}

View File

@ -0,0 +1,28 @@
import 'package:appflowy_backend/protobuf/flowy-database2/setting_entities.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
ViewLayoutPB viewLayoutFromDatabaseLayout(DatabaseLayoutPB databaseLayout) {
switch (databaseLayout) {
case DatabaseLayoutPB.Board:
return ViewLayoutPB.Board;
case DatabaseLayoutPB.Calendar:
return ViewLayoutPB.Calendar;
case DatabaseLayoutPB.Grid:
return ViewLayoutPB.Grid;
default:
throw UnimplementedError;
}
}
DatabaseLayoutPB databaseLayoutFromViewLayout(ViewLayoutPB viewLayout) {
switch (viewLayout) {
case ViewLayoutPB.Board:
return DatabaseLayoutPB.Board;
case ViewLayoutPB.Calendar:
return DatabaseLayoutPB.Calendar;
case ViewLayoutPB.Grid:
return DatabaseLayoutPB.Grid;
default:
throw UnimplementedError;
}
}

View File

@ -0,0 +1,53 @@
import 'dart:typed_data';
import 'package:appflowy/core/notification/grid_notification.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
import 'package:appflowy_backend/protobuf/flowy-error/protobuf.dart';
import 'package:appflowy_result/appflowy_result.dart';
import 'package:flowy_infra/notifier.dart';
typedef LayoutSettingsValue<T> = FlowyResult<T, FlowyError>;
class DatabaseLayoutSettingListener {
DatabaseLayoutSettingListener(this.viewId);
final String viewId;
PublishNotifier<LayoutSettingsValue<DatabaseLayoutSettingPB>>?
_settingNotifier = PublishNotifier();
DatabaseNotificationListener? _listener;
void start({
required void Function(LayoutSettingsValue<DatabaseLayoutSettingPB>)
onLayoutChanged,
}) {
_settingNotifier?.addPublishListener(onLayoutChanged);
_listener = DatabaseNotificationListener(
objectId: viewId,
handler: _handler,
);
}
void _handler(
DatabaseNotification ty,
FlowyResult<Uint8List, FlowyError> result,
) {
switch (ty) {
case DatabaseNotification.DidUpdateLayoutSettings:
result.fold(
(payload) => _settingNotifier?.value =
FlowyResult.success(DatabaseLayoutSettingPB.fromBuffer(payload)),
(error) => _settingNotifier?.value = FlowyResult.failure(error),
);
break;
default:
break;
}
}
Future<void> stop() async {
await _listener?.stop();
_settingNotifier?.dispose();
_settingNotifier = null;
}
}

View File

@ -0,0 +1,70 @@
import 'dart:typed_data';
import 'package:appflowy/core/notification/grid_notification.dart';
import 'package:appflowy_backend/log.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
import 'package:appflowy_backend/protobuf/flowy-error/protobuf.dart';
import 'package:appflowy_result/appflowy_result.dart';
typedef DidFetchRowCallback = void Function(DidFetchRowPB);
typedef RowMetaCallback = void Function(RowMetaPB);
class RowListener {
RowListener(this.rowId);
final String rowId;
DidFetchRowCallback? _onRowFetchedCallback;
RowMetaCallback? _onMetaChangedCallback;
DatabaseNotificationListener? _listener;
/// OnMetaChanged will be called when the row meta is changed.
/// OnRowFetched will be called when the row is fetched from remote storage
void start({
RowMetaCallback? onMetaChanged,
DidFetchRowCallback? onRowFetched,
}) {
_onMetaChangedCallback = onMetaChanged;
_onRowFetchedCallback = onRowFetched;
_listener = DatabaseNotificationListener(
objectId: rowId,
handler: _handler,
);
}
void _handler(
DatabaseNotification ty,
FlowyResult<Uint8List, FlowyError> result,
) {
switch (ty) {
case DatabaseNotification.DidUpdateRowMeta:
result.fold(
(payload) {
if (_onMetaChangedCallback != null) {
_onMetaChangedCallback!(RowMetaPB.fromBuffer(payload));
}
},
(error) => Log.error(error),
);
break;
case DatabaseNotification.DidFetchRow:
result.fold(
(payload) {
if (_onRowFetchedCallback != null) {
_onRowFetchedCallback!(DidFetchRowPB.fromBuffer(payload));
}
},
(error) => Log.error(error),
);
break;
default:
break;
}
}
Future<void> stop() async {
await _listener?.stop();
_onMetaChangedCallback = null;
_onRowFetchedCallback = null;
}
}

View File

@ -0,0 +1,51 @@
import 'dart:typed_data';
import 'package:appflowy/core/notification/grid_notification.dart';
import 'package:appflowy_backend/log.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
import 'package:appflowy_backend/protobuf/flowy-error/protobuf.dart';
import 'package:appflowy_result/appflowy_result.dart';
typedef RowMetaCallback = void Function(RowMetaPB);
class RowMetaListener {
RowMetaListener(this.rowId);
final String rowId;
RowMetaCallback? _callback;
DatabaseNotificationListener? _listener;
void start({required RowMetaCallback callback}) {
_callback = callback;
_listener = DatabaseNotificationListener(
objectId: rowId,
handler: _handler,
);
}
void _handler(
DatabaseNotification ty,
FlowyResult<Uint8List, FlowyError> result,
) {
switch (ty) {
case DatabaseNotification.DidUpdateRowMeta:
result.fold(
(payload) {
if (_callback != null) {
_callback!(RowMetaPB.fromBuffer(payload));
}
},
(error) => Log.error(error),
);
break;
default:
break;
}
}
Future<void> stop() async {
await _listener?.stop();
_callback = null;
}
}

View File

@ -0,0 +1,102 @@
import 'package:appflowy_backend/dispatch/dispatch.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 'type_option_service.dart';
class SelectOptionCellBackendService {
SelectOptionCellBackendService({
required this.viewId,
required this.fieldId,
required this.rowId,
});
final String viewId;
final String fieldId;
final String rowId;
Future<FlowyResult<void, FlowyError>> create({
required String name,
bool isSelected = true,
}) {
return TypeOptionBackendService(viewId: viewId, fieldId: fieldId)
.newOption(name: name)
.then(
(result) {
return result.fold(
(option) {
final payload = RepeatedSelectOptionPayload()
..viewId = viewId
..fieldId = fieldId
..rowId = rowId
..items.add(option);
return DatabaseEventInsertOrUpdateSelectOption(payload).send();
},
(r) => FlowyResult.failure(r),
);
},
);
}
Future<FlowyResult<void, FlowyError>> update({
required SelectOptionPB option,
}) {
final payload = RepeatedSelectOptionPayload()
..items.add(option)
..viewId = viewId
..fieldId = fieldId
..rowId = rowId;
return DatabaseEventInsertOrUpdateSelectOption(payload).send();
}
Future<FlowyResult<void, FlowyError>> delete({
required Iterable<SelectOptionPB> options,
}) {
final payload = RepeatedSelectOptionPayload()
..items.addAll(options)
..viewId = viewId
..fieldId = fieldId
..rowId = rowId;
return DatabaseEventDeleteSelectOption(payload).send();
}
Future<FlowyResult<SelectOptionCellDataPB, FlowyError>> getCellData() {
final payload = CellIdPB()
..viewId = viewId
..fieldId = fieldId
..rowId = rowId;
return DatabaseEventGetSelectOptionCellData(payload).send();
}
Future<FlowyResult<void, FlowyError>> select({
required Iterable<String> optionIds,
}) {
final payload = SelectOptionCellChangesetPB()
..cellIdentifier = _cellIdentifier()
..insertOptionIds.addAll(optionIds);
return DatabaseEventUpdateSelectOptionCell(payload).send();
}
Future<FlowyResult<void, FlowyError>> unSelect({
required Iterable<String> optionIds,
}) {
final payload = SelectOptionCellChangesetPB()
..cellIdentifier = _cellIdentifier()
..deleteOptionIds.addAll(optionIds);
return DatabaseEventUpdateSelectOptionCell(payload).send();
}
CellIdPB _cellIdentifier() {
return CellIdPB()
..viewId = viewId
..fieldId = fieldId
..rowId = rowId;
}
}

View File

@ -0,0 +1,54 @@
import 'dart:typed_data';
import 'package:appflowy/core/notification/grid_notification.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/notification.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/sort_entities.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
import 'package:appflowy_result/appflowy_result.dart';
import 'package:flowy_infra/notifier.dart';
typedef SortNotifiedValue
= FlowyResult<SortChangesetNotificationPB, FlowyError>;
class SortsListener {
SortsListener({required this.viewId});
final String viewId;
PublishNotifier<SortNotifiedValue>? _notifier = PublishNotifier();
DatabaseNotificationListener? _listener;
void start({
required void Function(SortNotifiedValue) onSortChanged,
}) {
_notifier?.addPublishListener(onSortChanged);
_listener = DatabaseNotificationListener(
objectId: viewId,
handler: _handler,
);
}
void _handler(
DatabaseNotification ty,
FlowyResult<Uint8List, FlowyError> result,
) {
switch (ty) {
case DatabaseNotification.DidUpdateSort:
result.fold(
(payload) => _notifier?.value = FlowyResult.success(
SortChangesetNotificationPB.fromBuffer(payload),
),
(error) => _notifier?.value = FlowyResult.failure(error),
);
break;
default:
break;
}
}
Future<void> stop() async {
await _listener?.stop();
_notifier?.dispose();
_notifier = null;
}
}

View File

@ -0,0 +1,122 @@
import 'package:appflowy_backend/dispatch/dispatch.dart';
import 'package:appflowy_backend/log.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/database_entities.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/setting_entities.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/sort_entities.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
import 'package:appflowy_result/appflowy_result.dart';
class SortBackendService {
SortBackendService({required this.viewId});
final String viewId;
Future<FlowyResult<List<SortPB>, FlowyError>> getAllSorts() {
final payload = DatabaseViewIdPB()..value = viewId;
return DatabaseEventGetAllSorts(payload).send().then((result) {
return result.fold(
(repeated) => FlowyResult.success(repeated.items),
(r) => FlowyResult.failure(r),
);
});
}
Future<FlowyResult<void, FlowyError>> updateSort({
required String sortId,
required String fieldId,
required SortConditionPB condition,
}) {
final insertSortPayload = UpdateSortPayloadPB.create()
..viewId = viewId
..sortId = sortId
..fieldId = fieldId
..condition = condition;
final payload = DatabaseSettingChangesetPB.create()
..viewId = viewId
..updateSort = insertSortPayload;
return DatabaseEventUpdateDatabaseSetting(payload).send().then((result) {
return result.fold(
(l) => FlowyResult.success(l),
(err) {
Log.error(err);
return FlowyResult.failure(err);
},
);
});
}
Future<FlowyResult<void, FlowyError>> insertSort({
required String fieldId,
required SortConditionPB condition,
}) {
final insertSortPayload = UpdateSortPayloadPB.create()
..fieldId = fieldId
..viewId = viewId
..condition = condition;
final payload = DatabaseSettingChangesetPB.create()
..viewId = viewId
..updateSort = insertSortPayload;
return DatabaseEventUpdateDatabaseSetting(payload).send().then((result) {
return result.fold(
(l) => FlowyResult.success(l),
(err) {
Log.error(err);
return FlowyResult.failure(err);
},
);
});
}
Future<FlowyResult<void, FlowyError>> reorderSort({
required String fromSortId,
required String toSortId,
}) {
final payload = DatabaseSettingChangesetPB()
..viewId = viewId
..reorderSort = (ReorderSortPayloadPB()
..viewId = viewId
..fromSortId = fromSortId
..toSortId = toSortId);
return DatabaseEventUpdateDatabaseSetting(payload).send();
}
Future<FlowyResult<void, FlowyError>> deleteSort({
required String fieldId,
required String sortId,
}) {
final deleteSortPayload = DeleteSortPayloadPB.create()
..sortId = sortId
..viewId = viewId;
final payload = DatabaseSettingChangesetPB.create()
..viewId = viewId
..deleteSort = deleteSortPayload;
return DatabaseEventUpdateDatabaseSetting(payload).send().then((result) {
return result.fold(
(l) => FlowyResult.success(l),
(err) {
Log.error(err);
return FlowyResult.failure(err);
},
);
});
}
Future<FlowyResult<void, FlowyError>> deleteAllSorts() {
final payload = DatabaseViewIdPB(value: viewId);
return DatabaseEventDeleteAllSorts(payload).send().then((result) {
return result.fold(
(l) => FlowyResult.success(l),
(err) {
Log.error(err);
return FlowyResult.failure(err);
},
);
});
}
}

View File

@ -0,0 +1,25 @@
import 'package:appflowy_backend/dispatch/dispatch.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';
class TypeOptionBackendService {
TypeOptionBackendService({
required this.viewId,
required this.fieldId,
});
final String viewId;
final String fieldId;
Future<FlowyResult<SelectOptionPB, FlowyError>> newOption({
required String name,
}) {
final payload = CreateSelectOptionPayloadPB.create()
..optionName = name
..viewId = viewId
..fieldId = fieldId;
return DatabaseEventCreateSelectOption(payload).send();
}
}