From 5ee4b8a2bcecf50a24bdedfbc5a250b8fde5a6ee Mon Sep 17 00:00:00 2001 From: appflowy Date: Mon, 18 Apr 2022 17:17:42 +0800 Subject: [PATCH] chore: different color when create option for single-select or multi-select --- .../app_flowy/lib/startup/deps_resolver.dart | 10 - .../grid/cell/select_option_service.dart | 3 +- .../field/type_option/multi_select_bloc.dart | 8 +- .../field/type_option/single_select_bloc.dart | 9 +- .../type_option/type_option_service.dart | 31 ++- .../src/widgets/header/field_switcher.dart | 44 ++-- .../header/type_option/multi_select.dart | 17 +- .../header/type_option/single_select.dart | 17 +- .../dart_event/flowy-grid/dart_event.dart | 2 +- .../protobuf/flowy-grid/cell_entities.pb.dart | 67 +----- .../flowy-grid/cell_entities.pbjson.dart | 14 +- frontend/rust-lib/flowy-grid/Flowy.toml | 4 +- .../rust-lib/flowy-grid/src/event_handler.rs | 38 ++- frontend/rust-lib/flowy-grid/src/event_map.rs | 2 +- .../src/protobuf/model/cell_entities.rs | 223 +++--------------- .../src/protobuf/proto/cell_entities.proto | 6 +- .../flowy-grid/src/services/cell/mod.rs | 3 - .../{cell => entities}/cell_entities.rs | 23 +- .../{field => entities}/field_entities.rs | 0 .../flowy-grid/src/services/entities/mod.rs | 7 + .../src/services/entities/row_entities.rs | 31 +++ .../flowy-grid/src/services/field/mod.rs | 2 - .../type_options/selection_type_option.rs | 60 ++++- .../flowy-grid/src/services/grid_editor.rs | 58 +++-- .../rust-lib/flowy-grid/src/services/mod.rs | 2 +- 25 files changed, 281 insertions(+), 400 deletions(-) delete mode 100644 frontend/rust-lib/flowy-grid/src/services/cell/mod.rs rename frontend/rust-lib/flowy-grid/src/services/{cell => entities}/cell_entities.rs (79%) rename frontend/rust-lib/flowy-grid/src/services/{field => entities}/field_entities.rs (100%) create mode 100644 frontend/rust-lib/flowy-grid/src/services/entities/mod.rs create mode 100644 frontend/rust-lib/flowy-grid/src/services/entities/row_entities.rs diff --git a/frontend/app_flowy/lib/startup/deps_resolver.dart b/frontend/app_flowy/lib/startup/deps_resolver.dart index 1a51652458..13eeae9033 100644 --- a/frontend/app_flowy/lib/startup/deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/deps_resolver.dart @@ -3,7 +3,6 @@ import 'package:app_flowy/user/application/user_listener.dart'; import 'package:app_flowy/user/application/user_service.dart'; import 'package:app_flowy/workspace/application/app/prelude.dart'; import 'package:app_flowy/workspace/application/doc/prelude.dart'; -import 'package:app_flowy/workspace/application/grid/field/type_option/multi_select_bloc.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:app_flowy/workspace/application/trash/prelude.dart'; import 'package:app_flowy/workspace/application/workspace/prelude.dart'; @@ -19,7 +18,6 @@ import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/number_type_option.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart'; import 'package:get_it/get_it.dart'; @@ -206,14 +204,6 @@ void _resolveGridDeps(GetIt getIt) { (context, _) => FieldSwitcherBloc(context), ); - getIt.registerFactoryParam( - (typeOption, fieldId) => SingleSelectTypeOptionBloc(typeOption, fieldId), - ); - - getIt.registerFactoryParam( - (typeOption, fieldId) => MultiSelectTypeOptionBloc(typeOption, fieldId), - ); - getIt.registerFactoryParam( (typeOption, _) => DateTypeOptionBloc(typeOption: typeOption), ); diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/select_option_service.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/select_option_service.dart index 65a05e4a5b..c76f06adc9 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/select_option_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/select_option_service.dart @@ -1,3 +1,4 @@ +import 'package:app_flowy/workspace/application/grid/field/type_option/type_option_service.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; @@ -13,7 +14,7 @@ class SelectOptionService { required String rowId, required String name, }) { - return GridEventNewSelectOption(SelectOptionName.create()..name = name).send().then( + return TypeOptionService(gridId: gridId, fieldId: fieldId).newOption(name: name).then( (result) { return result.fold( (option) { diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/multi_select_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/multi_select_bloc.dart index c5a55e20e1..0d42612595 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/multi_select_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/multi_select_bloc.dart @@ -11,14 +11,14 @@ part 'multi_select_bloc.freezed.dart'; class MultiSelectTypeOptionBloc extends Bloc { final TypeOptionService service; - MultiSelectTypeOptionBloc(MultiSelectTypeOption typeOption, String fieldId) - : service = TypeOptionService(fieldId: fieldId), - super(MultiSelectTypeOptionState.initial(typeOption)) { + MultiSelectTypeOptionBloc(TypeOptionContext typeOptionContext) + : service = TypeOptionService(gridId: typeOptionContext.gridId, fieldId: typeOptionContext.field.id), + super(MultiSelectTypeOptionState.initial(MultiSelectTypeOption.fromBuffer(typeOptionContext.data))) { on( (event, emit) async { await event.map( createOption: (_CreateOption value) async { - final result = await service.newOption(value.optionName); + final result = await service.newOption(name: value.optionName); result.fold( (option) { emit(state.copyWith(typeOption: _insertOption(option))); diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/single_select_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/single_select_bloc.dart index 82e4bba790..36a2f956b3 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/single_select_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/single_select_bloc.dart @@ -12,17 +12,16 @@ class SingleSelectTypeOptionBloc extends Bloc( (event, emit) async { await event.map( createOption: (_CreateOption value) async { - final result = await service.newOption(value.optionName); + final result = await service.newOption(name: value.optionName); result.fold( (option) { emit(state.copyWith(typeOption: _insertOption(option))); diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/type_option_service.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/type_option_service.dart index 0f0c2f067d..92f2263c5d 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/type_option_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/type_option_service.dart @@ -1,17 +1,44 @@ +import 'dart:typed_data'; + import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/cell_entities.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; class TypeOptionService { + final String gridId; final String fieldId; + TypeOptionService({ + required this.gridId, required this.fieldId, }); - Future> newOption(String name, {bool selected = false}) { - final payload = SelectOptionName.create()..name = name; + Future> newOption({ + required String name, + }) { + final fieldIdentifier = FieldIdentifierPayload.create() + ..gridId = gridId + ..fieldId = fieldId; + + final payload = CreateSelectOptionPayload.create() + ..optionName = name + ..fieldIdentifier = fieldIdentifier; + return GridEventNewSelectOption(payload).send(); } } + +class TypeOptionContext { + final String gridId; + final Field field; + final Uint8List data; + const TypeOptionContext({ + required this.gridId, + required this.field, + required this.data, + }); +} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart index 80ebd456e7..5d86b7249d 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart @@ -1,7 +1,7 @@ import 'dart:typed_data'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; -import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart'; +import 'package:app_flowy/workspace/application/grid/field/type_option/type_option_service.dart'; +import 'package:dartz/dartz.dart' show Either; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; @@ -14,11 +14,14 @@ import 'package:flowy_sdk/protobuf/flowy-grid/checkbox_type_option.pbserver.dart import 'package:flowy_sdk/protobuf/flowy-grid/text_type_option.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; + import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart'; +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart'; + import 'field_type_extension.dart'; -import 'package:dartz/dartz.dart' show Either; import 'type_option/multi_select.dart'; import 'type_option/number.dart'; import 'type_option/single_select.dart'; @@ -58,11 +61,7 @@ class _FieldSwitcherState extends State { }, builder: (context, state) { List children = [_switchFieldTypeButton(context, state.field)]; - final typeOptionWidget = _typeOptionWidget( - context: context, - field: state.field, - data: state.typeOptionData, - ); + final typeOptionWidget = _typeOptionWidget(context: context, state: state); if (typeOptionWidget != null) { children.add(typeOptionWidget); @@ -111,8 +110,7 @@ class _FieldSwitcherState extends State { Widget? _typeOptionWidget({ required BuildContext context, - required Field field, - required TypeOptionData data, + required FieldSwitchState state, }) { final overlayDelegate = TypeOptionOverlayDelegate( showOverlay: _showOverlay, @@ -123,9 +121,14 @@ class _FieldSwitcherState extends State { context.read().add(FieldSwitchEvent.didUpdateTypeOptionData(data)); }); + final typeOptionContext = TypeOptionContext( + gridId: state.gridId, + field: state.field, + data: state.typeOptionData, + ); + final builder = _makeTypeOptionBuild( - field: field, - data: data, + typeOptionContext: typeOptionContext, overlayDelegate: overlayDelegate, dataDelegate: dataDelegate, ); @@ -165,24 +168,23 @@ abstract class TypeOptionBuilder { } TypeOptionBuilder _makeTypeOptionBuild({ - required Field field, - required TypeOptionData data, + required TypeOptionContext typeOptionContext, required TypeOptionOverlayDelegate overlayDelegate, required TypeOptionDataDelegate dataDelegate, }) { - switch (field.fieldType) { + switch (typeOptionContext.field.fieldType) { case FieldType.Checkbox: - return CheckboxTypeOptionBuilder(data); + return CheckboxTypeOptionBuilder(typeOptionContext.data); case FieldType.DateTime: - return DateTypeOptionBuilder(data, overlayDelegate, dataDelegate); + return DateTypeOptionBuilder(typeOptionContext.data, overlayDelegate, dataDelegate); case FieldType.SingleSelect: - return SingleSelectTypeOptionBuilder(field.id, data, overlayDelegate, dataDelegate); + return SingleSelectTypeOptionBuilder(typeOptionContext, overlayDelegate, dataDelegate); case FieldType.MultiSelect: - return MultiSelectTypeOptionBuilder(field.id, data, overlayDelegate, dataDelegate); + return MultiSelectTypeOptionBuilder(typeOptionContext, overlayDelegate, dataDelegate); case FieldType.Number: - return NumberTypeOptionBuilder(data, overlayDelegate, dataDelegate); + return NumberTypeOptionBuilder(typeOptionContext.data, overlayDelegate, dataDelegate); case FieldType.RichText: - return RichTextTypeOptionBuilder(data); + return RichTextTypeOptionBuilder(typeOptionContext.data); default: throw UnimplementedError; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart index 873a63ceef..fb5da57bec 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/multi_select.dart @@ -1,7 +1,6 @@ -import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/field/type_option/multi_select_bloc.dart'; +import 'package:app_flowy/workspace/application/grid/field/type_option/type_option_service.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -11,13 +10,11 @@ class MultiSelectTypeOptionBuilder extends TypeOptionBuilder { final MultiSelectTypeOptionWidget _widget; MultiSelectTypeOptionBuilder( - String fieldId, - TypeOptionData typeOptionData, + TypeOptionContext typeOptionContext, TypeOptionOverlayDelegate overlayDelegate, TypeOptionDataDelegate dataDelegate, ) : _widget = MultiSelectTypeOptionWidget( - fieldId: fieldId, - typeOption: MultiSelectTypeOption.fromBuffer(typeOptionData), + typeOptionContext: typeOptionContext, overlayDelegate: overlayDelegate, dataDelegate: dataDelegate, ); @@ -27,13 +24,11 @@ class MultiSelectTypeOptionBuilder extends TypeOptionBuilder { } class MultiSelectTypeOptionWidget extends TypeOptionWidget { - final String fieldId; - final MultiSelectTypeOption typeOption; + final TypeOptionContext typeOptionContext; final TypeOptionOverlayDelegate overlayDelegate; final TypeOptionDataDelegate dataDelegate; const MultiSelectTypeOptionWidget({ - required this.fieldId, - required this.typeOption, + required this.typeOptionContext, required this.overlayDelegate, required this.dataDelegate, Key? key, @@ -42,7 +37,7 @@ class MultiSelectTypeOptionWidget extends TypeOptionWidget { @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => getIt(param1: typeOption, param2: fieldId), + create: (context) => MultiSelectTypeOptionBloc(typeOptionContext), child: BlocConsumer( listener: (context, state) { dataDelegate.didUpdateTypeOptionData(state.typeOption.writeToBuffer()); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/single_select.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/single_select.dart index ba2668f851..89d2f63a2d 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/single_select.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/single_select.dart @@ -1,7 +1,6 @@ -import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/field/type_option/single_select_bloc.dart'; +import 'package:app_flowy/workspace/application/grid/field/type_option/type_option_service.dart'; import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_switcher.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'field_option_pannel.dart'; @@ -10,13 +9,11 @@ class SingleSelectTypeOptionBuilder extends TypeOptionBuilder { final SingleSelectTypeOptionWidget _widget; SingleSelectTypeOptionBuilder( - String fieldId, - TypeOptionData typeOptionData, + TypeOptionContext typeOptionContext, TypeOptionOverlayDelegate overlayDelegate, TypeOptionDataDelegate dataDelegate, ) : _widget = SingleSelectTypeOptionWidget( - fieldId: fieldId, - typeOption: SingleSelectTypeOption.fromBuffer(typeOptionData), + typeOptionContext: typeOptionContext, dataDelegate: dataDelegate, overlayDelegate: overlayDelegate, ); @@ -26,13 +23,11 @@ class SingleSelectTypeOptionBuilder extends TypeOptionBuilder { } class SingleSelectTypeOptionWidget extends TypeOptionWidget { - final String fieldId; - final SingleSelectTypeOption typeOption; + final TypeOptionContext typeOptionContext; final TypeOptionOverlayDelegate overlayDelegate; final TypeOptionDataDelegate dataDelegate; const SingleSelectTypeOptionWidget({ - required this.fieldId, - required this.typeOption, + required this.typeOptionContext, required this.dataDelegate, required this.overlayDelegate, Key? key, @@ -41,7 +36,7 @@ class SingleSelectTypeOptionWidget extends TypeOptionWidget { @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => getIt(param1: typeOption, param2: fieldId), + create: (context) => SingleSelectTypeOptionBloc(typeOptionContext), child: BlocConsumer( listener: (context, state) { dataDelegate.didUpdateTypeOptionData(state.typeOption.writeToBuffer()); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart index 33925ca955..9f87c2ad26 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart @@ -172,7 +172,7 @@ class GridEventMoveItem { } class GridEventNewSelectOption { - SelectOptionName request; + CreateSelectOptionPayload request; GridEventNewSelectOption(this.request); Future> send() { diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_entities.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_entities.pb.dart index 259fcf1422..7645632fb8 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_entities.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_entities.pb.dart @@ -9,21 +9,23 @@ import 'dart:core' as $core; import 'package:protobuf/protobuf.dart' as $pb; +import 'field_entities.pb.dart' as $0; + class CreateSelectOptionPayload extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CreateSelectOptionPayload', createEmptyInstance: create) - ..aOM(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'cellIdentifier', subBuilder: CellIdentifierPayload.create) + ..aOM<$0.FieldIdentifierPayload>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldIdentifier', subBuilder: $0.FieldIdentifierPayload.create) ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'optionName') ..hasRequiredFields = false ; CreateSelectOptionPayload._() : super(); factory CreateSelectOptionPayload({ - CellIdentifierPayload? cellIdentifier, + $0.FieldIdentifierPayload? fieldIdentifier, $core.String? optionName, }) { final _result = create(); - if (cellIdentifier != null) { - _result.cellIdentifier = cellIdentifier; + if (fieldIdentifier != null) { + _result.fieldIdentifier = fieldIdentifier; } if (optionName != null) { _result.optionName = optionName; @@ -52,15 +54,15 @@ class CreateSelectOptionPayload extends $pb.GeneratedMessage { static CreateSelectOptionPayload? _defaultInstance; @$pb.TagNumber(1) - CellIdentifierPayload get cellIdentifier => $_getN(0); + $0.FieldIdentifierPayload get fieldIdentifier => $_getN(0); @$pb.TagNumber(1) - set cellIdentifier(CellIdentifierPayload v) { setField(1, v); } + set fieldIdentifier($0.FieldIdentifierPayload v) { setField(1, v); } @$pb.TagNumber(1) - $core.bool hasCellIdentifier() => $_has(0); + $core.bool hasFieldIdentifier() => $_has(0); @$pb.TagNumber(1) - void clearCellIdentifier() => clearField(1); + void clearFieldIdentifier() => clearField(1); @$pb.TagNumber(1) - CellIdentifierPayload ensureCellIdentifier() => $_ensure(0); + $0.FieldIdentifierPayload ensureFieldIdentifier() => $_ensure(0); @$pb.TagNumber(2) $core.String get optionName => $_getSZ(1); @@ -147,50 +149,3 @@ class CellIdentifierPayload extends $pb.GeneratedMessage { void clearRowId() => clearField(3); } -class SelectOptionName extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SelectOptionName', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name') - ..hasRequiredFields = false - ; - - SelectOptionName._() : super(); - factory SelectOptionName({ - $core.String? name, - }) { - final _result = create(); - if (name != null) { - _result.name = name; - } - return _result; - } - factory SelectOptionName.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory SelectOptionName.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - SelectOptionName clone() => SelectOptionName()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - SelectOptionName copyWith(void Function(SelectOptionName) updates) => super.copyWith((message) => updates(message as SelectOptionName)) as SelectOptionName; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static SelectOptionName create() => SelectOptionName._(); - SelectOptionName createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static SelectOptionName getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static SelectOptionName? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get name => $_getSZ(0); - @$pb.TagNumber(1) - set name($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasName() => $_has(0); - @$pb.TagNumber(1) - void clearName() => clearField(1); -} - diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_entities.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_entities.pbjson.dart index ac0c9add9c..931b310a69 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_entities.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/cell_entities.pbjson.dart @@ -12,13 +12,13 @@ import 'dart:typed_data' as $typed_data; const CreateSelectOptionPayload$json = const { '1': 'CreateSelectOptionPayload', '2': const [ - const {'1': 'cell_identifier', '3': 1, '4': 1, '5': 11, '6': '.CellIdentifierPayload', '10': 'cellIdentifier'}, + const {'1': 'field_identifier', '3': 1, '4': 1, '5': 11, '6': '.FieldIdentifierPayload', '10': 'fieldIdentifier'}, const {'1': 'option_name', '3': 2, '4': 1, '5': 9, '10': 'optionName'}, ], }; /// Descriptor for `CreateSelectOptionPayload`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List createSelectOptionPayloadDescriptor = $convert.base64Decode('ChlDcmVhdGVTZWxlY3RPcHRpb25QYXlsb2FkEj8KD2NlbGxfaWRlbnRpZmllchgBIAEoCzIWLkNlbGxJZGVudGlmaWVyUGF5bG9hZFIOY2VsbElkZW50aWZpZXISHwoLb3B0aW9uX25hbWUYAiABKAlSCm9wdGlvbk5hbWU='); +final $typed_data.Uint8List createSelectOptionPayloadDescriptor = $convert.base64Decode('ChlDcmVhdGVTZWxlY3RPcHRpb25QYXlsb2FkEkIKEGZpZWxkX2lkZW50aWZpZXIYASABKAsyFy5GaWVsZElkZW50aWZpZXJQYXlsb2FkUg9maWVsZElkZW50aWZpZXISHwoLb3B0aW9uX25hbWUYAiABKAlSCm9wdGlvbk5hbWU='); @$core.Deprecated('Use cellIdentifierPayloadDescriptor instead') const CellIdentifierPayload$json = const { '1': 'CellIdentifierPayload', @@ -31,13 +31,3 @@ const CellIdentifierPayload$json = const { /// Descriptor for `CellIdentifierPayload`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List cellIdentifierPayloadDescriptor = $convert.base64Decode('ChVDZWxsSWRlbnRpZmllclBheWxvYWQSFwoHZ3JpZF9pZBgBIAEoCVIGZ3JpZElkEhkKCGZpZWxkX2lkGAIgASgJUgdmaWVsZElkEhUKBnJvd19pZBgDIAEoCVIFcm93SWQ='); -@$core.Deprecated('Use selectOptionNameDescriptor instead') -const SelectOptionName$json = const { - '1': 'SelectOptionName', - '2': const [ - const {'1': 'name', '3': 1, '4': 1, '5': 9, '10': 'name'}, - ], -}; - -/// Descriptor for `SelectOptionName`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List selectOptionNameDescriptor = $convert.base64Decode('ChBTZWxlY3RPcHRpb25OYW1lEhIKBG5hbWUYASABKAlSBG5hbWU='); diff --git a/frontend/rust-lib/flowy-grid/Flowy.toml b/frontend/rust-lib/flowy-grid/Flowy.toml index b0b15a1a2a..1d0d2baea8 100644 --- a/frontend/rust-lib/flowy-grid/Flowy.toml +++ b/frontend/rust-lib/flowy-grid/Flowy.toml @@ -2,9 +2,7 @@ proto_crates = [ "src/event_map.rs", "src/services/field/type_options", - "src/services/field/field_entities.rs", - "src/services/cell/cell_entities.rs", - "src/services/row/row_entities.rs", + "src/services/entities", "src/dart_notification.rs" ] event_files = ["src/event_map.rs"] \ No newline at end of file diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 9efdf0d01f..2ef933f039 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -1,10 +1,8 @@ use crate::manager::GridManager; -use crate::services::cell::cell_entities::*; -use crate::services::field::field_entities::*; +use crate::services::entities::*; use crate::services::field::type_options::*; use crate::services::field::{default_type_option_builder_from_type, type_option_builder_from_json_str}; use crate::services::grid_editor::ClientGridEditor; -use crate::services::row::row_entities::*; use flowy_error::{ErrorCode, FlowyError, FlowyResult}; use flowy_grid_data_model::entities::*; use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; @@ -248,9 +246,20 @@ pub(crate) async fn update_cell_handler( } #[tracing::instrument(level = "debug", skip_all, err)] -pub(crate) async fn new_select_option_handler(data: Data) -> DataResult { - let params = data.into_inner(); - data_result(SelectOption::new(¶ms.name)) +pub(crate) async fn new_select_option_handler( + data: Data, + manager: AppData>, +) -> DataResult { + let params: CreateSelectOptionParams = data.into_inner().try_into()?; + let editor = manager.get_grid_editor(¶ms.grid_id)?; + match editor.get_field_meta(¶ms.field_id).await { + None => Err(ErrorCode::InvalidData.into()), + Some(field_meta) => { + let type_option = select_option_operation(&field_meta)?; + let select_option = type_option.create_option(¶ms.option_name); + data_result(select_option) + } + } } #[tracing::instrument(level = "debug", skip_all, err)] @@ -337,20 +346,3 @@ pub(crate) async fn update_cell_select_option_handler( let _ = editor.update_cell(changeset).await?; Ok(()) } - -fn select_option_operation(field_meta: &FieldMeta) -> FlowyResult> { - match &field_meta.field_type { - FieldType::SingleSelect => { - let type_option = SingleSelectTypeOption::from(field_meta); - Ok(Box::new(type_option)) - } - FieldType::MultiSelect => { - let type_option = MultiSelectTypeOption::from(field_meta); - Ok(Box::new(type_option)) - } - ty => { - tracing::error!("Unsupported field type: {:?} for this handler", ty); - Err(ErrorCode::FieldInvalidOperation.into()) - } - } -} diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs index 67cbebe2d9..46513a43c9 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -69,7 +69,7 @@ pub enum GridEvent { #[event(input = "MoveItemPayload")] MoveItem = 17, - #[event(input = "SelectOptionName", output = "SelectOption")] + #[event(input = "CreateSelectOptionPayload", output = "SelectOption")] NewSelectOption = 30, #[event(input = "CellIdentifierPayload", output = "SelectOptionContext")] diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/cell_entities.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/cell_entities.rs index 107f783e59..08a0cb0c1d 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/cell_entities.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/cell_entities.rs @@ -26,7 +26,7 @@ #[derive(PartialEq,Clone,Default)] pub struct CreateSelectOptionPayload { // message fields - pub cell_identifier: ::protobuf::SingularPtrField, + pub field_identifier: ::protobuf::SingularPtrField, pub option_name: ::std::string::String, // special fields pub unknown_fields: ::protobuf::UnknownFields, @@ -44,37 +44,37 @@ impl CreateSelectOptionPayload { ::std::default::Default::default() } - // .CellIdentifierPayload cell_identifier = 1; + // .FieldIdentifierPayload field_identifier = 1; - pub fn get_cell_identifier(&self) -> &CellIdentifierPayload { - self.cell_identifier.as_ref().unwrap_or_else(|| ::default_instance()) + pub fn get_field_identifier(&self) -> &super::field_entities::FieldIdentifierPayload { + self.field_identifier.as_ref().unwrap_or_else(|| ::default_instance()) } - pub fn clear_cell_identifier(&mut self) { - self.cell_identifier.clear(); + pub fn clear_field_identifier(&mut self) { + self.field_identifier.clear(); } - pub fn has_cell_identifier(&self) -> bool { - self.cell_identifier.is_some() + pub fn has_field_identifier(&self) -> bool { + self.field_identifier.is_some() } // Param is passed by value, moved - pub fn set_cell_identifier(&mut self, v: CellIdentifierPayload) { - self.cell_identifier = ::protobuf::SingularPtrField::some(v); + pub fn set_field_identifier(&mut self, v: super::field_entities::FieldIdentifierPayload) { + self.field_identifier = ::protobuf::SingularPtrField::some(v); } // Mutable pointer to the field. // If field is not initialized, it is initialized with default value first. - pub fn mut_cell_identifier(&mut self) -> &mut CellIdentifierPayload { - if self.cell_identifier.is_none() { - self.cell_identifier.set_default(); + pub fn mut_field_identifier(&mut self) -> &mut super::field_entities::FieldIdentifierPayload { + if self.field_identifier.is_none() { + self.field_identifier.set_default(); } - self.cell_identifier.as_mut().unwrap() + self.field_identifier.as_mut().unwrap() } // Take field - pub fn take_cell_identifier(&mut self) -> CellIdentifierPayload { - self.cell_identifier.take().unwrap_or_else(|| CellIdentifierPayload::new()) + pub fn take_field_identifier(&mut self) -> super::field_entities::FieldIdentifierPayload { + self.field_identifier.take().unwrap_or_else(|| super::field_entities::FieldIdentifierPayload::new()) } // string option_name = 2; @@ -106,7 +106,7 @@ impl CreateSelectOptionPayload { impl ::protobuf::Message for CreateSelectOptionPayload { fn is_initialized(&self) -> bool { - for v in &self.cell_identifier { + for v in &self.field_identifier { if !v.is_initialized() { return false; } @@ -119,7 +119,7 @@ impl ::protobuf::Message for CreateSelectOptionPayload { let (field_number, wire_type) = is.read_tag_unpack()?; match field_number { 1 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.cell_identifier)?; + ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.field_identifier)?; }, 2 => { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.option_name)?; @@ -136,7 +136,7 @@ impl ::protobuf::Message for CreateSelectOptionPayload { #[allow(unused_variables)] fn compute_size(&self) -> u32 { let mut my_size = 0; - if let Some(ref v) = self.cell_identifier.as_ref() { + if let Some(ref v) = self.field_identifier.as_ref() { let len = v.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; } @@ -149,7 +149,7 @@ impl ::protobuf::Message for CreateSelectOptionPayload { } fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if let Some(ref v) = self.cell_identifier.as_ref() { + if let Some(ref v) = self.field_identifier.as_ref() { os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; v.write_to_with_cached_sizes(os)?; @@ -195,10 +195,10 @@ impl ::protobuf::Message for CreateSelectOptionPayload { static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; descriptor.get(|| { let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "cell_identifier", - |m: &CreateSelectOptionPayload| { &m.cell_identifier }, - |m: &mut CreateSelectOptionPayload| { &mut m.cell_identifier }, + fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( + "field_identifier", + |m: &CreateSelectOptionPayload| { &m.field_identifier }, + |m: &mut CreateSelectOptionPayload| { &mut m.field_identifier }, )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "option_name", @@ -221,7 +221,7 @@ impl ::protobuf::Message for CreateSelectOptionPayload { impl ::protobuf::Clear for CreateSelectOptionPayload { fn clear(&mut self) { - self.cell_identifier.clear(); + self.field_identifier.clear(); self.option_name.clear(); self.unknown_fields.clear(); } @@ -482,173 +482,14 @@ impl ::protobuf::reflect::ProtobufValue for CellIdentifierPayload { } } -#[derive(PartialEq,Clone,Default)] -pub struct SelectOptionName { - // message fields - pub name: ::std::string::String, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a SelectOptionName { - fn default() -> &'a SelectOptionName { - ::default_instance() - } -} - -impl SelectOptionName { - pub fn new() -> SelectOptionName { - ::std::default::Default::default() - } - - // string name = 1; - - - pub fn get_name(&self) -> &str { - &self.name - } - pub fn clear_name(&mut self) { - self.name.clear(); - } - - // Param is passed by value, moved - pub fn set_name(&mut self, v: ::std::string::String) { - self.name = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_name(&mut self) -> &mut ::std::string::String { - &mut self.name - } - - // Take field - pub fn take_name(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.name, ::std::string::String::new()) - } -} - -impl ::protobuf::Message for SelectOptionName { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.name.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.name); - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.name.is_empty() { - os.write_string(1, &self.name)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> SelectOptionName { - SelectOptionName::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "name", - |m: &SelectOptionName| { &m.name }, - |m: &mut SelectOptionName| { &mut m.name }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "SelectOptionName", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static SelectOptionName { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(SelectOptionName::new) - } -} - -impl ::protobuf::Clear for SelectOptionName { - fn clear(&mut self) { - self.name.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for SelectOptionName { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for SelectOptionName { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x13cell_entities.proto\"}\n\x19CreateSelectOptionPayload\x12?\n\x0fce\ - ll_identifier\x18\x01\x20\x01(\x0b2\x16.CellIdentifierPayloadR\x0ecellId\ - entifier\x12\x1f\n\x0boption_name\x18\x02\x20\x01(\tR\noptionName\"b\n\ - \x15CellIdentifierPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gr\ - idId\x12\x19\n\x08field_id\x18\x02\x20\x01(\tR\x07fieldId\x12\x15\n\x06r\ - ow_id\x18\x03\x20\x01(\tR\x05rowId\"&\n\x10SelectOptionName\x12\x12\n\ - \x04name\x18\x01\x20\x01(\tR\x04nameb\x06proto3\ + \n\x13cell_entities.proto\x1a\x14field_entities.proto\"\x80\x01\n\x19Cre\ + ateSelectOptionPayload\x12B\n\x10field_identifier\x18\x01\x20\x01(\x0b2\ + \x17.FieldIdentifierPayloadR\x0ffieldIdentifier\x12\x1f\n\x0boption_name\ + \x18\x02\x20\x01(\tR\noptionName\"b\n\x15CellIdentifierPayload\x12\x17\n\ + \x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x19\n\x08field_id\x18\x02\ + \x20\x01(\tR\x07fieldId\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowId\ + b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/cell_entities.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/cell_entities.proto index d20ec4e34c..558ed90034 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/cell_entities.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/cell_entities.proto @@ -1,7 +1,8 @@ syntax = "proto3"; +import "field_entities.proto"; message CreateSelectOptionPayload { - CellIdentifierPayload cell_identifier = 1; + FieldIdentifierPayload field_identifier = 1; string option_name = 2; } message CellIdentifierPayload { @@ -9,6 +10,3 @@ message CellIdentifierPayload { string field_id = 2; string row_id = 3; } -message SelectOptionName { - string name = 1; -} diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/mod.rs b/frontend/rust-lib/flowy-grid/src/services/cell/mod.rs deleted file mode 100644 index d2541866be..0000000000 --- a/frontend/rust-lib/flowy-grid/src/services/cell/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub(crate) mod cell_entities; - -pub use cell_entities::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/cell/cell_entities.rs b/frontend/rust-lib/flowy-grid/src/services/entities/cell_entities.rs similarity index 79% rename from frontend/rust-lib/flowy-grid/src/services/cell/cell_entities.rs rename to frontend/rust-lib/flowy-grid/src/services/entities/cell_entities.rs index 0947e37f06..2f408db992 100644 --- a/frontend/rust-lib/flowy-grid/src/services/cell/cell_entities.rs +++ b/frontend/rust-lib/flowy-grid/src/services/entities/cell_entities.rs @@ -1,3 +1,4 @@ +use crate::services::entities::{FieldIdentifier, FieldIdentifierPayload}; use flowy_derive::ProtoBuf; use flowy_error::ErrorCode; use flowy_grid_data_model::parser::NotEmptyStr; @@ -5,25 +6,33 @@ use flowy_grid_data_model::parser::NotEmptyStr; #[derive(ProtoBuf, Default)] pub struct CreateSelectOptionPayload { #[pb(index = 1)] - pub cell_identifier: CellIdentifierPayload, + pub field_identifier: FieldIdentifierPayload, #[pb(index = 2)] pub option_name: String, } pub struct CreateSelectOptionParams { - pub cell_identifier: CellIdentifier, + pub field_identifier: FieldIdentifier, pub option_name: String, } +impl std::ops::Deref for CreateSelectOptionParams { + type Target = FieldIdentifier; + + fn deref(&self) -> &Self::Target { + &self.field_identifier + } +} + impl TryInto for CreateSelectOptionPayload { type Error = ErrorCode; fn try_into(self) -> Result { let option_name = NotEmptyStr::parse(self.option_name).map_err(|_| ErrorCode::SelectOptionNameIsEmpty)?; - let cell_identifier = self.cell_identifier.try_into()?; + let field_identifier = self.field_identifier.try_into()?; Ok(CreateSelectOptionParams { - cell_identifier, + field_identifier, option_name: option_name.0, }) } @@ -61,9 +70,3 @@ impl TryInto for CellIdentifierPayload { }) } } - -#[derive(ProtoBuf, Default)] -pub struct SelectOptionName { - #[pb(index = 1)] - pub name: String, -} diff --git a/frontend/rust-lib/flowy-grid/src/services/field/field_entities.rs b/frontend/rust-lib/flowy-grid/src/services/entities/field_entities.rs similarity index 100% rename from frontend/rust-lib/flowy-grid/src/services/field/field_entities.rs rename to frontend/rust-lib/flowy-grid/src/services/entities/field_entities.rs diff --git a/frontend/rust-lib/flowy-grid/src/services/entities/mod.rs b/frontend/rust-lib/flowy-grid/src/services/entities/mod.rs new file mode 100644 index 0000000000..61bcf6ebed --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/entities/mod.rs @@ -0,0 +1,7 @@ +mod cell_entities; +mod field_entities; +mod row_entities; + +pub use cell_entities::*; +pub use field_entities::*; +pub use row_entities::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/entities/row_entities.rs b/frontend/rust-lib/flowy-grid/src/services/entities/row_entities.rs new file mode 100644 index 0000000000..c97becbd34 --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/entities/row_entities.rs @@ -0,0 +1,31 @@ +use flowy_derive::ProtoBuf; +use flowy_error::ErrorCode; +use flowy_grid_data_model::parser::NotEmptyStr; + +#[derive(ProtoBuf, Default)] +pub struct RowIdentifierPayload { + #[pb(index = 1)] + pub grid_id: String, + + #[pb(index = 3)] + pub row_id: String, +} + +pub struct RowIdentifier { + pub grid_id: String, + pub row_id: String, +} + +impl TryInto for RowIdentifierPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + let row_id = NotEmptyStr::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?; + + Ok(RowIdentifier { + grid_id: grid_id.0, + row_id: row_id.0, + }) + } +} diff --git a/frontend/rust-lib/flowy-grid/src/services/field/mod.rs b/frontend/rust-lib/flowy-grid/src/services/field/mod.rs index 89a1f05c57..c1b689fbf4 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/mod.rs @@ -1,7 +1,5 @@ mod field_builder; -pub(crate) mod field_entities; pub(crate) mod type_options; pub use field_builder::*; -pub use field_entities::*; pub use type_options::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs index a80f5760ac..ecaf2344b8 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs @@ -1,10 +1,10 @@ use crate::impl_type_option; -use crate::services::cell::{CellIdentifier, CellIdentifierPayload}; +use crate::services::entities::{CellIdentifier, CellIdentifierPayload}; use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; use crate::services::row::{CellDataChangeset, CellDataOperation, TypeOptionCellData}; use bytes::Bytes; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; -use flowy_error::{ErrorCode, FlowyError}; +use flowy_error::{ErrorCode, FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ CellChangeset, CellMeta, FieldMeta, FieldType, TypeOptionDataDeserializer, TypeOptionDataEntry, }; @@ -36,10 +36,35 @@ pub trait SelectOptionOperation: TypeOptionDataEntry + Send + Sync { } } + fn create_option(&self, name: &str) -> SelectOption { + let color = select_option_color_from_index(self.options().len()); + SelectOption::with_color(name, color) + } + fn option_context(&self, cell_meta: &Option) -> SelectOptionContext; + + fn options(&self) -> &Vec; + fn mut_options(&mut self) -> &mut Vec; } +pub fn select_option_operation(field_meta: &FieldMeta) -> FlowyResult> { + match &field_meta.field_type { + FieldType::SingleSelect => { + let type_option = SingleSelectTypeOption::from(field_meta); + Ok(Box::new(type_option)) + } + FieldType::MultiSelect => { + let type_option = MultiSelectTypeOption::from(field_meta); + Ok(Box::new(type_option)) + } + ty => { + tracing::error!("Unsupported field type: {:?} for this handler", ty); + Err(ErrorCode::FieldInvalidOperation.into()) + } + } +} + // Single select #[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] pub struct SingleSelectTypeOption { @@ -60,6 +85,10 @@ impl SelectOptionOperation for SingleSelectTypeOption { } } + fn options(&self) -> &Vec { + &self.options + } + fn mut_options(&mut self) -> &mut Vec { &mut self.options } @@ -155,6 +184,10 @@ impl SelectOptionOperation for MultiSelectTypeOption { } } + fn options(&self) -> &Vec { + &self.options + } + fn mut_options(&mut self) -> &mut Vec { &mut self.options } @@ -265,6 +298,14 @@ impl SelectOption { color: SelectOptionColor::default(), } } + + pub fn with_color(name: &str, color: SelectOptionColor) -> Self { + SelectOption { + id: nanoid!(4), + name: name.to_owned(), + color, + } + } } #[derive(Clone, Debug, Default, ProtoBuf)] @@ -430,6 +471,21 @@ pub enum SelectOptionColor { Blue = 8, } +pub fn select_option_color_from_index(index: usize) -> SelectOptionColor { + match index % 8 { + 0 => SelectOptionColor::Purple, + 1 => SelectOptionColor::Pink, + 2 => SelectOptionColor::LightPink, + 3 => SelectOptionColor::Orange, + 4 => SelectOptionColor::Yellow, + 5 => SelectOptionColor::Lime, + 6 => SelectOptionColor::Green, + 7 => SelectOptionColor::Aqua, + 8 => SelectOptionColor::Blue, + _ => SelectOptionColor::Purple, + } +} + impl std::default::Default for SelectOptionColor { fn default() -> Self { SelectOptionColor::Purple diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index d2312708b1..724ec65e8f 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -1,8 +1,11 @@ use crate::dart_notification::{send_dart_notification, GridNotification}; use crate::manager::GridUser; use crate::services::block_meta_manager::GridBlockMetaEditorManager; -use crate::services::cell::CellIdentifier; -use crate::services::field::{default_type_option_builder_from_type, type_option_builder_from_bytes, FieldBuilder}; +use crate::services::entities::{CellIdentifier, CreateSelectOptionParams}; +use crate::services::field::{ + default_type_option_builder_from_type, select_option_operation, type_option_builder_from_bytes, FieldBuilder, + SelectOption, +}; use crate::services::persistence::block_index::BlockIndexPersistence; use crate::services::row::*; use bytes::Bytes; @@ -22,7 +25,7 @@ use tokio::sync::RwLock; pub struct ClientGridEditor { grid_id: String, user: Arc, - pad: Arc>, + grid_pad: Arc>, rev_manager: Arc, block_meta_manager: Arc, } @@ -38,14 +41,14 @@ impl ClientGridEditor { let cloud = Arc::new(GridRevisionCloudService { token }); let grid_pad = rev_manager.load::(Some(cloud)).await?; let rev_manager = Arc::new(rev_manager); - let pad = Arc::new(RwLock::new(grid_pad)); - let blocks = pad.read().await.get_block_metas(); + let grid_pad = Arc::new(RwLock::new(grid_pad)); + let blocks = grid_pad.read().await.get_block_metas(); let block_meta_manager = Arc::new(GridBlockMetaEditorManager::new(grid_id, &user, blocks, persistence).await?); Ok(Arc::new(Self { grid_id: grid_id.to_owned(), user, - pad, + grid_pad, rev_manager, block_meta_manager, })) @@ -94,18 +97,18 @@ impl ClientGridEditor { } pub async fn create_next_field_meta(&self, field_type: &FieldType) -> FlowyResult { - let name = format!("Property {}", self.pad.read().await.fields().len() + 1); + let name = format!("Property {}", self.grid_pad.read().await.fields().len() + 1); let field_meta = FieldBuilder::from_field_type(field_type).name(&name).build(); Ok(field_meta) } pub async fn contain_field(&self, field_id: &str) -> bool { - self.pad.read().await.contain_field(field_id) + self.grid_pad.read().await.contain_field(field_id) } pub async fn update_field(&self, params: FieldChangesetParams) -> FlowyResult<()> { let field_id = params.field_id.clone(); - let json_deserializer = match self.pad.read().await.get_field_meta(params.field_id.as_str()) { + let json_deserializer = match self.grid_pad.read().await.get_field_meta(params.field_id.as_str()) { None => return Err(ErrorCode::FieldDoesNotExist.into()), Some((_, field_meta)) => TypeOptionJsonDeserializer(field_meta.field_type.clone()), }; @@ -169,7 +172,7 @@ impl ClientGridEditor { } pub async fn get_field_meta(&self, field_id: &str) -> Option { - let field_meta = self.pad.read().await.get_field_meta(field_id)?.1.clone(); + let field_meta = self.grid_pad.read().await.get_field_meta(field_id)?.1.clone(); Some(field_meta) } @@ -178,14 +181,14 @@ impl ClientGridEditor { T: Into, { if field_ids.is_none() { - let field_metas = self.pad.read().await.get_field_metas(None)?; + let field_metas = self.grid_pad.read().await.get_field_metas(None)?; return Ok(field_metas); } let to_field_orders = |item: Vec| item.into_iter().map(|data| data.into()).collect(); let field_orders = field_ids.map_or(vec![], to_field_orders); let expected_len = field_orders.len(); - let field_metas = self.pad.read().await.get_field_metas(Some(field_orders))?; + let field_metas = self.grid_pad.read().await.get_field_metas(Some(field_orders))?; if expected_len != 0 && field_metas.len() != expected_len { tracing::error!( "This is a bug. The len of the field_metas should equal to {}", @@ -207,7 +210,7 @@ impl ClientGridEditor { } pub async fn create_row(&self, start_row_id: Option) -> FlowyResult { - let field_metas = self.pad.read().await.get_field_metas(None)?; + let field_metas = self.grid_pad.read().await.get_field_metas(None)?; let block_id = self.block_id().await?; // insert empty row below the row whose id is upper_row_id @@ -314,7 +317,7 @@ impl ClientGridEditor { let cell_data_changeset = changeset.data.unwrap(); let cell_meta = self.get_cell_meta(&changeset.row_id, &changeset.field_id).await?; tracing::trace!("{}: {:?}", &changeset.field_id, cell_meta); - match self.pad.read().await.get_field_meta(&changeset.field_id) { + match self.grid_pad.read().await.get_field_meta(&changeset.field_id) { None => { let msg = format!("Field not found with id: {}", &changeset.field_id); Err(FlowyError::internal().context(msg)) @@ -334,7 +337,7 @@ impl ClientGridEditor { } pub async fn get_block_metas(&self) -> FlowyResult> { - let grid_blocks = self.pad.read().await.get_block_metas(); + let grid_blocks = self.grid_pad.read().await.get_block_metas(); Ok(grid_blocks) } @@ -347,7 +350,7 @@ impl ClientGridEditor { } pub async fn grid_data(&self) -> FlowyResult { - let pad_read_guard = self.pad.read().await; + let pad_read_guard = self.grid_pad.read().await; let field_orders = pad_read_guard.get_field_orders(); let mut block_orders = vec![]; for block_order in pad_read_guard.get_block_metas() { @@ -369,7 +372,7 @@ impl ClientGridEditor { pub async fn grid_block_snapshots(&self, block_ids: Option>) -> FlowyResult> { let block_ids = match block_ids { None => self - .pad + .grid_pad .read() .await .get_block_metas() @@ -396,7 +399,7 @@ impl ClientGridEditor { let _ = self .modify(|grid_pad| Ok(grid_pad.move_field(field_id, from as usize, to as usize)?)) .await?; - if let Some((index, field_meta)) = self.pad.read().await.get_field_meta(field_id) { + if let Some((index, field_meta)) = self.grid_pad.read().await.get_field_meta(field_id) { let delete_field_order = FieldOrder::from(field_id); let insert_field = IndexField::from_field_meta(field_meta, index); let notified_changeset = GridFieldChangeset { @@ -420,14 +423,14 @@ impl ClientGridEditor { } pub async fn delta_bytes(&self) -> Bytes { - self.pad.read().await.delta_bytes() + self.grid_pad.read().await.delta_bytes() } async fn modify(&self, f: F) -> FlowyResult<()> where F: for<'a> FnOnce(&'a mut GridMetaPad) -> FlowyResult>, { - let mut write_guard = self.pad.write().await; + let mut write_guard = self.grid_pad.write().await; if let Some(changeset) = f(&mut *write_guard)? { let _ = self.apply_change(changeset).await?; } @@ -455,7 +458,7 @@ impl ClientGridEditor { } async fn block_id(&self) -> FlowyResult { - match self.pad.read().await.get_block_metas().last() { + match self.grid_pad.read().await.get_block_metas().last() { None => Err(FlowyError::internal().context("There is no grid block in this grid")), Some(grid_block) => Ok(grid_block.block_id.clone()), } @@ -463,7 +466,7 @@ impl ClientGridEditor { #[tracing::instrument(level = "trace", skip_all, err)] async fn notify_did_insert_grid_field(&self, field_id: &str) -> FlowyResult<()> { - if let Some((index, field_meta)) = self.pad.read().await.get_field_meta(field_id) { + if let Some((index, field_meta)) = self.grid_pad.read().await.get_field_meta(field_id) { let index_field = IndexField::from_field_meta(field_meta, index); let notified_changeset = GridFieldChangeset::insert(&self.grid_id, vec![index_field]); let _ = self.notify_did_update_grid(notified_changeset).await?; @@ -473,10 +476,13 @@ impl ClientGridEditor { #[tracing::instrument(level = "trace", skip_all, err)] async fn notify_did_update_grid_field(&self, field_id: &str) -> FlowyResult<()> { - let mut field_metas = self.get_field_metas(Some(vec![field_id])).await?; - debug_assert!(field_metas.len() == 1); - - if let Some(field_meta) = field_metas.pop() { + if let Some((_, field_meta)) = self + .grid_pad + .read() + .await + .get_field_meta(field_id) + .map(|(index, field)| (index, field.clone())) + { let updated_field = Field::from(field_meta); let notified_changeset = GridFieldChangeset::update(&self.grid_id, vec![updated_field.clone()]); let _ = self.notify_did_update_grid(notified_changeset).await?; diff --git a/frontend/rust-lib/flowy-grid/src/services/mod.rs b/frontend/rust-lib/flowy-grid/src/services/mod.rs index d6ca2d5c45..036efd6ada 100644 --- a/frontend/rust-lib/flowy-grid/src/services/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/mod.rs @@ -2,7 +2,7 @@ mod util; pub mod block_meta_editor; mod block_meta_manager; -pub mod cell; +pub mod entities; pub mod field; pub mod grid_editor; pub mod persistence;