From 2607822412de6aeadb8ac5ce0aae6971b25df948 Mon Sep 17 00:00:00 2001 From: appflowy Date: Tue, 5 Apr 2022 21:25:59 +0800 Subject: [PATCH] chore: show selection --- .../grid/cell_bloc/cell_service.dart | 43 ++ .../grid/cell_bloc/selection_cell_bloc.dart | 36 +- .../grid/cell_bloc/selection_editor_bloc.dart | 8 +- .../type_option/type_option_service.dart | 6 +- .../application/grid/row/row_service.dart | 1 - .../cell/selection_cell/selection_cell.dart | 2 +- .../cell/selection_cell/selection_editor.dart | 19 +- .../dart_event/flowy-grid/dart_event.dart | 10 +- .../flowy-grid-data-model/grid.pb.dart | 170 ++--- .../flowy-grid-data-model/grid.pbjson.dart | 29 +- .../protobuf/flowy-grid/event_map.pbenum.dart | 4 +- .../protobuf/flowy-grid/event_map.pbjson.dart | 4 +- .../flowy-grid/selection_type_option.pb.dart | 42 +- .../selection_type_option.pbjson.dart | 7 +- .../rust-lib/flowy-grid/src/event_handler.rs | 66 +- frontend/rust-lib/flowy-grid/src/event_map.rs | 20 +- frontend/rust-lib/flowy-grid/src/manager.rs | 1 - .../src/protobuf/model/event_map.rs | 12 +- .../protobuf/model/selection_type_option.rs | 79 ++- .../src/protobuf/proto/event_map.proto | 2 +- .../proto/selection_type_option.proto | 5 +- .../src/services/block_meta_editor.rs | 8 +- .../type_options/checkbox_type_option.rs | 29 +- .../field/type_options/date_type_option.rs | 39 +- .../field/type_options/number_type_option.rs | 57 +- .../type_options/selection_type_option.rs | 194 ++++-- .../field/type_options/text_type_option.rs | 24 +- .../flowy-grid/src/services/grid_editor.rs | 102 ++- .../src/services/persistence/block_index.rs | 1 - .../flowy-grid/src/services/persistence/kv.rs | 1 - .../src/services/row/cell_data_operation.rs | 81 ++- .../src/services/row/row_builder.rs | 6 +- .../flowy-grid/src/services/row/row_loader.rs | 8 +- .../flowy-grid/tests/grid/grid_test.rs | 16 +- .../src/entities/grid.rs | 72 +- .../src/protobuf/model/grid.rs | 619 +++++++++--------- .../src/protobuf/proto/grid.proto | 11 +- .../src/client_grid/grid_meta_pad.rs | 1 - 38 files changed, 1080 insertions(+), 755 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart index e1af022d95..f7a0247a98 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart @@ -1,11 +1,54 @@ import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; class CellService { CellService(); + Future> addSelectOpiton({ + required String gridId, + required String fieldId, + required String rowId, + required String optionId, + }) { + final payload = SelectOptionChangesetPayload.create() + ..gridId = gridId + ..fieldId = fieldId + ..rowId = rowId + ..insertOptionId = optionId; + return GridEventApplySelectOptionChangeset(payload).send(); + } + + Future> getSelectOpitonContext({ + required String gridId, + required String fieldId, + required String rowId, + }) { + final payload = CellIdentifierPayload.create() + ..gridId = gridId + ..fieldId = fieldId + ..rowId = rowId; + + return GridEventGetSelectOptions(payload).send(); + } + + Future> removeSelectOpiton({ + required String gridId, + required String fieldId, + required String rowId, + required String optionId, + }) { + final payload = SelectOptionChangesetPayload.create() + ..gridId = gridId + ..fieldId = fieldId + ..rowId = rowId + ..deleteOptionId = optionId; + return GridEventApplySelectOptionChangeset(payload).send(); + } + Future> updateCell({ required String gridId, required String fieldId, diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart index 2cde7c6a96..1b38376e86 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_cell_bloc.dart @@ -11,12 +11,13 @@ import 'cell_service.dart'; part 'selection_cell_bloc.freezed.dart'; class SelectionCellBloc extends Bloc { - final CellService service; + final CellService _service; SelectionCellBloc({ - required this.service, + required CellService service, required CellData cellData, - }) : super(SelectionCellState.initial(cellData)) { + }) : _service = service, + super(SelectionCellState.initial(cellData)) { on( (event, emit) async { await event.map( @@ -37,30 +38,17 @@ class SelectionCellBloc extends Bloc { } void _loadOptions() async { - final result = await FieldContextLoaderAdaptor( + final result = await _service.getSelectOpitonContext( gridId: state.cellData.gridId, - field: state.cellData.field, - ).load(); + fieldId: state.cellData.field.id, + rowId: state.cellData.rowId, + ); result.fold( - (context) { - List options = []; - switch (state.cellData.field.fieldType) { - case FieldType.MultiSelect: - options.addAll(MultiSelectTypeOption.fromBuffer(context.typeOptionData).options); - break; - case FieldType.SingleSelect: - options.addAll(SingleSelectTypeOption.fromBuffer(context.typeOptionData).options); - break; - default: - Log.error("Invalid field type, expect single select or multiple select"); - break; - } - - final ids = state.cellData.cell?.content.split(','); - final selectedOptions = ids?.map((id) => options.firstWhere((option) => option.id == id)).toList() ?? []; - add(SelectionCellEvent.didReceiveOptions(options, selectedOptions)); - }, + (selectOptionContext) => add(SelectionCellEvent.didReceiveOptions( + selectOptionContext.options, + selectOptionContext.selectOptions, + )), (err) => Log.error(err), ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart index 5ce68105ea..671dc7ae8a 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/selection_editor_bloc.dart @@ -41,15 +41,15 @@ class SelectOptionEditorBloc extends Bloc null, (err) => Log.error(err)); }, selectOption: (_SelectOption value) { - _cellService.updateCell( + _cellService.addSelectOpiton( gridId: state.gridId, - fieldId: state.fieldId, + fieldId: state.field.id, rowId: state.rowId, - data: data, + optionId: value.optionId, ); }, ); 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 8ab3460b82..9121ded71b 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 @@ -10,8 +10,10 @@ class TypeOptionService { required this.fieldId, }); - Future> createOption(String name) { - final payload = CreateSelectOptionPayload.create()..optionName = name; + Future> createOption(String name, {bool selected = false}) { + final payload = CreateSelectOptionPayload.create() + ..optionName = name + ..selected = selected; return GridEventCreateSelectOption(payload).send(); } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart index a65cb81b29..1b3f9e87ec 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart @@ -22,7 +22,6 @@ class RowService { Future> getRow() { QueryRowPayload payload = QueryRowPayload.create() ..gridId = gridId - ..blockId = blockId ..rowId = rowId; return GridEventGetRow(payload).send(); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart index 3fe1b19c14..33a935d37e 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart @@ -39,7 +39,7 @@ class _SingleSelectCellState extends State { return SizedBox.expand( child: InkWell( onTap: () { - SelectionEditor.show(context, state.cellData, state.options, state.selectedOptions); + SelectOptionEditor.show(context, state.cellData, state.options, state.selectedOptions); }, child: Row(children: children), ), diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart index 0c8d207a4b..d10a5a8cf8 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_editor.dart @@ -21,12 +21,12 @@ import 'extension.dart'; const double _editorPannelWidth = 300; -class SelectionEditor extends StatelessWidget { +class SelectOptionEditor extends StatelessWidget { final CellData cellData; final List options; final List selectedOptions; - const SelectionEditor({ + const SelectOptionEditor({ required this.cellData, required this.options, required this.selectedOptions, @@ -34,15 +34,14 @@ class SelectionEditor extends StatelessWidget { }) : super(key: key); static String identifier() { - return (SelectionEditor).toString(); + return (SelectOptionEditor).toString(); } @override Widget build(BuildContext context) { return BlocProvider( create: (context) => SelectOptionEditorBloc( - gridId: cellData.gridId, - field: cellData.field, + cellData: cellData, options: options, selectedOptions: selectedOptions, ), @@ -68,8 +67,8 @@ class SelectionEditor extends StatelessWidget { List options, List selectedOptions, ) { - SelectionEditor.hide(context); - final editor = SelectionEditor( + SelectOptionEditor.hide(context); + final editor = SelectOptionEditor( cellData: cellData, options: options, selectedOptions: selectedOptions, @@ -81,7 +80,7 @@ class SelectionEditor extends StatelessWidget { child: SizedBox(width: _editorPannelWidth, child: editor), constraints: BoxConstraints.loose(const Size(_editorPannelWidth, 300)), ), - identifier: SelectionEditor.identifier(), + identifier: SelectOptionEditor.identifier(), anchorContext: context, anchorDirection: AnchorDirection.bottomWithCenterAligned, ); @@ -177,7 +176,9 @@ class _SelectOptionCell extends StatelessWidget { return SizedBox( height: GridSize.typeOptionItemHeight, child: InkWell( - onTap: () {}, + onTap: () { + context.read().add(SelectOptionEditorEvent.selectOption(option.id)); + }, child: FlowyHover( config: HoverDisplayConfig(hoverColor: theme.hover), builder: (_, onHover) { 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 a709d06fe8..2a23cfad4a 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 GridEventCreateSelectOption { } class GridEventGetSelectOptions { - FieldIdentifierPayload request; + CellIdentifierPayload request; GridEventGetSelectOptions(this.request); Future> send() { @@ -239,13 +239,13 @@ class GridEventUpdateCell { } } -class GridEventInsertSelectOption { - InsertSelectOptionPayload request; - GridEventInsertSelectOption(this.request); +class GridEventApplySelectOptionChangeset { + SelectOptionChangesetPayload request; + GridEventApplySelectOptionChangeset(this.request); Future> send() { final request = FFIRequest.create() - ..event = GridEvent.InsertSelectOption.toString() + ..event = GridEvent.ApplySelectOptionChangeset.toString() ..payload = requestToBytes(this.request); return Dispatch.asyncRequest(request) diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart index 7fcee422d7..ab195308c6 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart @@ -266,67 +266,6 @@ class FieldIdentifierPayload extends $pb.GeneratedMessage { void clearGridId() => clearField(2); } -class FieldIdentifierParams extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FieldIdentifierParams', createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') - ..hasRequiredFields = false - ; - - FieldIdentifierParams._() : super(); - factory FieldIdentifierParams({ - $core.String? fieldId, - $core.String? gridId, - }) { - final _result = create(); - if (fieldId != null) { - _result.fieldId = fieldId; - } - if (gridId != null) { - _result.gridId = gridId; - } - return _result; - } - factory FieldIdentifierParams.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory FieldIdentifierParams.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') - FieldIdentifierParams clone() => FieldIdentifierParams()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - FieldIdentifierParams copyWith(void Function(FieldIdentifierParams) updates) => super.copyWith((message) => updates(message as FieldIdentifierParams)) as FieldIdentifierParams; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static FieldIdentifierParams create() => FieldIdentifierParams._(); - FieldIdentifierParams createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static FieldIdentifierParams getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static FieldIdentifierParams? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get fieldId => $_getSZ(0); - @$pb.TagNumber(1) - set fieldId($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasFieldId() => $_has(0); - @$pb.TagNumber(1) - void clearFieldId() => clearField(1); - - @$pb.TagNumber(2) - $core.String get gridId => $_getSZ(1); - @$pb.TagNumber(2) - set gridId($core.String v) { $_setString(1, v); } - @$pb.TagNumber(2) - $core.bool hasGridId() => $_has(1); - @$pb.TagNumber(2) - void clearGridId() => clearField(2); -} - class FieldOrder extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FieldOrder', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') @@ -1085,6 +1024,81 @@ class Cell extends $pb.GeneratedMessage { void clearContent() => clearField(2); } +class CellIdentifierPayload extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CellIdentifierPayload', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') + ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') + ..hasRequiredFields = false + ; + + CellIdentifierPayload._() : super(); + factory CellIdentifierPayload({ + $core.String? gridId, + $core.String? fieldId, + $core.String? rowId, + }) { + final _result = create(); + if (gridId != null) { + _result.gridId = gridId; + } + if (fieldId != null) { + _result.fieldId = fieldId; + } + if (rowId != null) { + _result.rowId = rowId; + } + return _result; + } + factory CellIdentifierPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory CellIdentifierPayload.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') + CellIdentifierPayload clone() => CellIdentifierPayload()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + CellIdentifierPayload copyWith(void Function(CellIdentifierPayload) updates) => super.copyWith((message) => updates(message as CellIdentifierPayload)) as CellIdentifierPayload; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static CellIdentifierPayload create() => CellIdentifierPayload._(); + CellIdentifierPayload createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static CellIdentifierPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static CellIdentifierPayload? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get gridId => $_getSZ(0); + @$pb.TagNumber(1) + set gridId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasGridId() => $_has(0); + @$pb.TagNumber(1) + void clearGridId() => clearField(1); + + @$pb.TagNumber(2) + $core.String get fieldId => $_getSZ(1); + @$pb.TagNumber(2) + set fieldId($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasFieldId() => $_has(1); + @$pb.TagNumber(2) + void clearFieldId() => clearField(2); + + @$pb.TagNumber(3) + $core.String get rowId => $_getSZ(2); + @$pb.TagNumber(3) + set rowId($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasRowId() => $_has(2); + @$pb.TagNumber(3) + void clearRowId() => clearField(3); +} + class RepeatedCell extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedCell', createEmptyInstance: create) ..pc(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: Cell.create) @@ -1566,7 +1580,6 @@ class QueryGridBlocksPayload extends $pb.GeneratedMessage { class QueryRowPayload extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'QueryRowPayload', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') - ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId') ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') ..hasRequiredFields = false ; @@ -1574,16 +1587,12 @@ class QueryRowPayload extends $pb.GeneratedMessage { QueryRowPayload._() : super(); factory QueryRowPayload({ $core.String? gridId, - $core.String? blockId, $core.String? rowId, }) { final _result = create(); if (gridId != null) { _result.gridId = gridId; } - if (blockId != null) { - _result.blockId = blockId; - } if (rowId != null) { _result.rowId = rowId; } @@ -1619,21 +1628,12 @@ class QueryRowPayload extends $pb.GeneratedMessage { @$pb.TagNumber(1) void clearGridId() => clearField(1); - @$pb.TagNumber(2) - $core.String get blockId => $_getSZ(1); - @$pb.TagNumber(2) - set blockId($core.String v) { $_setString(1, v); } - @$pb.TagNumber(2) - $core.bool hasBlockId() => $_has(1); - @$pb.TagNumber(2) - void clearBlockId() => clearField(2); - @$pb.TagNumber(3) - $core.String get rowId => $_getSZ(2); + $core.String get rowId => $_getSZ(1); @$pb.TagNumber(3) - set rowId($core.String v) { $_setString(2, v); } + set rowId($core.String v) { $_setString(1, v); } @$pb.TagNumber(3) - $core.bool hasRowId() => $_has(2); + $core.bool hasRowId() => $_has(1); @$pb.TagNumber(3) void clearRowId() => clearField(3); } @@ -1641,17 +1641,22 @@ class QueryRowPayload extends $pb.GeneratedMessage { class CreateSelectOptionPayload extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CreateSelectOptionPayload', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'optionName') + ..aOB(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'selected') ..hasRequiredFields = false ; CreateSelectOptionPayload._() : super(); factory CreateSelectOptionPayload({ $core.String? optionName, + $core.bool? selected, }) { final _result = create(); if (optionName != null) { _result.optionName = optionName; } + if (selected != null) { + _result.selected = selected; + } return _result; } factory CreateSelectOptionPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); @@ -1683,5 +1688,14 @@ class CreateSelectOptionPayload extends $pb.GeneratedMessage { $core.bool hasOptionName() => $_has(0); @$pb.TagNumber(1) void clearOptionName() => clearField(1); + + @$pb.TagNumber(2) + $core.bool get selected => $_getBF(1); + @$pb.TagNumber(2) + set selected($core.bool v) { $_setBool(1, v); } + @$pb.TagNumber(2) + $core.bool hasSelected() => $_has(1); + @$pb.TagNumber(2) + void clearSelected() => clearField(2); } diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart index 596c7f6fc1..c51a224a9e 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart @@ -47,17 +47,6 @@ const FieldIdentifierPayload$json = const { /// Descriptor for `FieldIdentifierPayload`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List fieldIdentifierPayloadDescriptor = $convert.base64Decode('ChZGaWVsZElkZW50aWZpZXJQYXlsb2FkEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElkEhcKB2dyaWRfaWQYAiABKAlSBmdyaWRJZA=='); -@$core.Deprecated('Use fieldIdentifierParamsDescriptor instead') -const FieldIdentifierParams$json = const { - '1': 'FieldIdentifierParams', - '2': const [ - const {'1': 'field_id', '3': 1, '4': 1, '5': 9, '10': 'fieldId'}, - const {'1': 'grid_id', '3': 2, '4': 1, '5': 9, '10': 'gridId'}, - ], -}; - -/// Descriptor for `FieldIdentifierParams`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List fieldIdentifierParamsDescriptor = $convert.base64Decode('ChVGaWVsZElkZW50aWZpZXJQYXJhbXMSGQoIZmllbGRfaWQYASABKAlSB2ZpZWxkSWQSFwoHZ3JpZF9pZBgCIAEoCVIGZ3JpZElk'); @$core.Deprecated('Use fieldOrderDescriptor instead') const FieldOrder$json = const { '1': 'FieldOrder', @@ -214,6 +203,18 @@ const Cell$json = const { /// Descriptor for `Cell`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List cellDescriptor = $convert.base64Decode('CgRDZWxsEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElkEhgKB2NvbnRlbnQYAiABKAlSB2NvbnRlbnQ='); +@$core.Deprecated('Use cellIdentifierPayloadDescriptor instead') +const CellIdentifierPayload$json = const { + '1': 'CellIdentifierPayload', + '2': const [ + const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, + const {'1': 'field_id', '3': 2, '4': 1, '5': 9, '10': 'fieldId'}, + const {'1': 'row_id', '3': 3, '4': 1, '5': 9, '10': 'rowId'}, + ], +}; + +/// Descriptor for `CellIdentifierPayload`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List cellIdentifierPayloadDescriptor = $convert.base64Decode('ChVDZWxsSWRlbnRpZmllclBheWxvYWQSFwoHZ3JpZF9pZBgBIAEoCVIGZ3JpZElkEhkKCGZpZWxkX2lkGAIgASgJUgdmaWVsZElkEhUKBnJvd19pZBgDIAEoCVIFcm93SWQ='); @$core.Deprecated('Use repeatedCellDescriptor instead') const RepeatedCell$json = const { '1': 'RepeatedCell', @@ -311,20 +312,20 @@ const QueryRowPayload$json = const { '1': 'QueryRowPayload', '2': const [ const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, - const {'1': 'block_id', '3': 2, '4': 1, '5': 9, '10': 'blockId'}, const {'1': 'row_id', '3': 3, '4': 1, '5': 9, '10': 'rowId'}, ], }; /// Descriptor for `QueryRowPayload`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List queryRowPayloadDescriptor = $convert.base64Decode('Cg9RdWVyeVJvd1BheWxvYWQSFwoHZ3JpZF9pZBgBIAEoCVIGZ3JpZElkEhkKCGJsb2NrX2lkGAIgASgJUgdibG9ja0lkEhUKBnJvd19pZBgDIAEoCVIFcm93SWQ='); +final $typed_data.Uint8List queryRowPayloadDescriptor = $convert.base64Decode('Cg9RdWVyeVJvd1BheWxvYWQSFwoHZ3JpZF9pZBgBIAEoCVIGZ3JpZElkEhUKBnJvd19pZBgDIAEoCVIFcm93SWQ='); @$core.Deprecated('Use createSelectOptionPayloadDescriptor instead') const CreateSelectOptionPayload$json = const { '1': 'CreateSelectOptionPayload', '2': const [ const {'1': 'option_name', '3': 1, '4': 1, '5': 9, '10': 'optionName'}, + const {'1': 'selected', '3': 2, '4': 1, '5': 8, '10': 'selected'}, ], }; /// Descriptor for `CreateSelectOptionPayload`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List createSelectOptionPayloadDescriptor = $convert.base64Decode('ChlDcmVhdGVTZWxlY3RPcHRpb25QYXlsb2FkEh8KC29wdGlvbl9uYW1lGAEgASgJUgpvcHRpb25OYW1l'); +final $typed_data.Uint8List createSelectOptionPayloadDescriptor = $convert.base64Decode('ChlDcmVhdGVTZWxlY3RPcHRpb25QYXlsb2FkEh8KC29wdGlvbl9uYW1lGAEgASgJUgpvcHRpb25OYW1lEhoKCHNlbGVjdGVkGAIgASgIUghzZWxlY3RlZA=='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbenum.dart index 2de16d922c..4c8cff633b 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbenum.dart @@ -24,7 +24,7 @@ class GridEvent extends $pb.ProtobufEnum { static const GridEvent CreateRow = GridEvent._(50, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateRow'); static const GridEvent GetRow = GridEvent._(51, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetRow'); static const GridEvent UpdateCell = GridEvent._(70, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateCell'); - static const GridEvent InsertSelectOption = GridEvent._(71, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'InsertSelectOption'); + static const GridEvent ApplySelectOptionChangeset = GridEvent._(71, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ApplySelectOptionChangeset'); static const $core.List values = [ GetGridData, @@ -41,7 +41,7 @@ class GridEvent extends $pb.ProtobufEnum { CreateRow, GetRow, UpdateCell, - InsertSelectOption, + ApplySelectOptionChangeset, ]; static final $core.Map<$core.int, GridEvent> _byValue = $pb.ProtobufEnum.initByValue(values); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart index 56b593c688..017dc4b1aa 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart @@ -26,9 +26,9 @@ const GridEvent$json = const { const {'1': 'CreateRow', '2': 50}, const {'1': 'GetRow', '2': 51}, const {'1': 'UpdateCell', '2': 70}, - const {'1': 'InsertSelectOption', '2': 71}, + const {'1': 'ApplySelectOptionChangeset', '2': 71}, ], }; /// Descriptor for `GridEvent`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtDcmVhdGVGaWVsZBAMEg8KC0RlbGV0ZUZpZWxkEA0SEQoNU3dpdGNoVG9GaWVsZBAOEhIKDkR1cGxpY2F0ZUZpZWxkEA8SFwoTR2V0RWRpdEZpZWxkQ29udGV4dBAQEhYKEkNyZWF0ZVNlbGVjdE9wdGlvbhAeEhQKEEdldFNlbGVjdE9wdGlvbnMQHxINCglDcmVhdGVSb3cQMhIKCgZHZXRSb3cQMxIOCgpVcGRhdGVDZWxsEEYSFgoSSW5zZXJ0U2VsZWN0T3B0aW9uEEc='); +final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtDcmVhdGVGaWVsZBAMEg8KC0RlbGV0ZUZpZWxkEA0SEQoNU3dpdGNoVG9GaWVsZBAOEhIKDkR1cGxpY2F0ZUZpZWxkEA8SFwoTR2V0RWRpdEZpZWxkQ29udGV4dBAQEhYKEkNyZWF0ZVNlbGVjdE9wdGlvbhAeEhQKEEdldFNlbGVjdE9wdGlvbnMQHxINCglDcmVhdGVSb3cQMhIKCgZHZXRSb3cQMxIOCgpVcGRhdGVDZWxsEEYSHgoaQXBwbHlTZWxlY3RPcHRpb25DaGFuZ2VzZXQQRw=='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pb.dart index 2b9fc8a5ce..350806f275 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pb.dart @@ -210,20 +210,21 @@ enum SelectOptionChangesetPayload_OneOfDeleteOptionId { class SelectOptionChangesetPayload extends $pb.GeneratedMessage { static const $core.Map<$core.int, SelectOptionChangesetPayload_OneOfInsertOptionId> _SelectOptionChangesetPayload_OneOfInsertOptionIdByTag = { - 3 : SelectOptionChangesetPayload_OneOfInsertOptionId.insertOptionId, + 4 : SelectOptionChangesetPayload_OneOfInsertOptionId.insertOptionId, 0 : SelectOptionChangesetPayload_OneOfInsertOptionId.notSet }; static const $core.Map<$core.int, SelectOptionChangesetPayload_OneOfDeleteOptionId> _SelectOptionChangesetPayload_OneOfDeleteOptionIdByTag = { - 4 : SelectOptionChangesetPayload_OneOfDeleteOptionId.deleteOptionId, + 5 : SelectOptionChangesetPayload_OneOfDeleteOptionId.deleteOptionId, 0 : SelectOptionChangesetPayload_OneOfDeleteOptionId.notSet }; static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SelectOptionChangesetPayload', createEmptyInstance: create) - ..oo(0, [3]) - ..oo(1, [4]) + ..oo(0, [4]) + ..oo(1, [5]) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId') ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId') - ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'insertOptionId') - ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'deleteOptionId') + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') + ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'insertOptionId') + ..aOS(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'deleteOptionId') ..hasRequiredFields = false ; @@ -231,6 +232,7 @@ class SelectOptionChangesetPayload extends $pb.GeneratedMessage { factory SelectOptionChangesetPayload({ $core.String? gridId, $core.String? rowId, + $core.String? fieldId, $core.String? insertOptionId, $core.String? deleteOptionId, }) { @@ -241,6 +243,9 @@ class SelectOptionChangesetPayload extends $pb.GeneratedMessage { if (rowId != null) { _result.rowId = rowId; } + if (fieldId != null) { + _result.fieldId = fieldId; + } if (insertOptionId != null) { _result.insertOptionId = insertOptionId; } @@ -295,22 +300,31 @@ class SelectOptionChangesetPayload extends $pb.GeneratedMessage { void clearRowId() => clearField(2); @$pb.TagNumber(3) - $core.String get insertOptionId => $_getSZ(2); + $core.String get fieldId => $_getSZ(2); @$pb.TagNumber(3) - set insertOptionId($core.String v) { $_setString(2, v); } + set fieldId($core.String v) { $_setString(2, v); } @$pb.TagNumber(3) - $core.bool hasInsertOptionId() => $_has(2); + $core.bool hasFieldId() => $_has(2); @$pb.TagNumber(3) - void clearInsertOptionId() => clearField(3); + void clearFieldId() => clearField(3); @$pb.TagNumber(4) - $core.String get deleteOptionId => $_getSZ(3); + $core.String get insertOptionId => $_getSZ(3); @$pb.TagNumber(4) - set deleteOptionId($core.String v) { $_setString(3, v); } + set insertOptionId($core.String v) { $_setString(3, v); } @$pb.TagNumber(4) - $core.bool hasDeleteOptionId() => $_has(3); + $core.bool hasInsertOptionId() => $_has(3); @$pb.TagNumber(4) - void clearDeleteOptionId() => clearField(4); + void clearInsertOptionId() => clearField(4); + + @$pb.TagNumber(5) + $core.String get deleteOptionId => $_getSZ(4); + @$pb.TagNumber(5) + set deleteOptionId($core.String v) { $_setString(4, v); } + @$pb.TagNumber(5) + $core.bool hasDeleteOptionId() => $_has(4); + @$pb.TagNumber(5) + void clearDeleteOptionId() => clearField(5); } class SelectOptionContext extends $pb.GeneratedMessage { diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbjson.dart index 4002db9a33..04c44a3004 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/selection_type_option.pbjson.dart @@ -66,8 +66,9 @@ const SelectOptionChangesetPayload$json = const { '2': const [ const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'}, const {'1': 'row_id', '3': 2, '4': 1, '5': 9, '10': 'rowId'}, - const {'1': 'insert_option_id', '3': 3, '4': 1, '5': 9, '9': 0, '10': 'insertOptionId'}, - const {'1': 'delete_option_id', '3': 4, '4': 1, '5': 9, '9': 1, '10': 'deleteOptionId'}, + const {'1': 'field_id', '3': 3, '4': 1, '5': 9, '10': 'fieldId'}, + const {'1': 'insert_option_id', '3': 4, '4': 1, '5': 9, '9': 0, '10': 'insertOptionId'}, + const {'1': 'delete_option_id', '3': 5, '4': 1, '5': 9, '9': 1, '10': 'deleteOptionId'}, ], '8': const [ const {'1': 'one_of_insert_option_id'}, @@ -76,7 +77,7 @@ const SelectOptionChangesetPayload$json = const { }; /// Descriptor for `SelectOptionChangesetPayload`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List selectOptionChangesetPayloadDescriptor = $convert.base64Decode('ChxTZWxlY3RPcHRpb25DaGFuZ2VzZXRQYXlsb2FkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIVCgZyb3dfaWQYAiABKAlSBXJvd0lkEioKEGluc2VydF9vcHRpb25faWQYAyABKAlIAFIOaW5zZXJ0T3B0aW9uSWQSKgoQZGVsZXRlX29wdGlvbl9pZBgEIAEoCUgBUg5kZWxldGVPcHRpb25JZEIZChdvbmVfb2ZfaW5zZXJ0X29wdGlvbl9pZEIZChdvbmVfb2ZfZGVsZXRlX29wdGlvbl9pZA=='); +final $typed_data.Uint8List selectOptionChangesetPayloadDescriptor = $convert.base64Decode('ChxTZWxlY3RPcHRpb25DaGFuZ2VzZXRQYXlsb2FkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIVCgZyb3dfaWQYAiABKAlSBXJvd0lkEhkKCGZpZWxkX2lkGAMgASgJUgdmaWVsZElkEioKEGluc2VydF9vcHRpb25faWQYBCABKAlIAFIOaW5zZXJ0T3B0aW9uSWQSKgoQZGVsZXRlX29wdGlvbl9pZBgFIAEoCUgBUg5kZWxldGVPcHRpb25JZEIZChdvbmVfb2ZfaW5zZXJ0X29wdGlvbl9pZEIZChdvbmVfb2ZfZGVsZXRlX29wdGlvbl9pZA=='); @$core.Deprecated('Use selectOptionContextDescriptor instead') const SelectOptionContext$json = const { '1': 'SelectOptionContext', diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index dd7675e803..62cbb4abec 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -1,7 +1,7 @@ use crate::manager::GridManager; use crate::services::field::{ - default_type_option_builder_from_type, type_option_builder_from_json_str, SelectOption, - SelectOptionChangesetParams, SelectOptionChangesetPayload, + default_type_option_builder_from_type, type_option_builder_from_json_str, MultiSelectTypeOption, SelectOption, + SelectOptionChangesetParams, SelectOptionChangesetPayload, SelectOptionContext, SingleSelectTypeOption, }; use crate::services::grid_editor::ClientGridEditor; use flowy_error::{FlowyError, FlowyResult}; @@ -93,7 +93,10 @@ pub(crate) async fn switch_to_field_handler( .switch_to_field_type(¶ms.field_id, ¶ms.field_type) .await?; - let field_meta = editor.get_field(¶ms.field_id).await?; + let field_meta = editor + .get_field_metas(Some(vec![params.field_id.as_str()])) + .await? + .pop(); let edit_context = make_field_edit_context( ¶ms.grid_id, Some(params.field_id), @@ -124,6 +127,44 @@ pub(crate) async fn create_select_option_handler( data_result(SelectOption::new(¶ms.option_name)) } +#[tracing::instrument(level = "debug", skip(data, manager), err)] +pub(crate) async fn get_select_option_handler( + data: Data, + manager: AppData>, +) -> DataResult { + let params: CellIdentifierParams = data.into_inner().try_into()?; + let editor = manager.get_grid_editor(¶ms.grid_id)?; + match editor + .get_field_metas(Some(vec![params.field_id.as_str()])) + .await? + .pop() + { + None => { + tracing::error!("Can't find the corresponding field with id: {}", params.field_id); + data_result(SelectOptionContext::default()) + } + Some(field_meta) => { + let cell_meta = editor.get_cell_meta(¶ms.row_id, ¶ms.field_id).await?; + match field_meta.field_type { + FieldType::SingleSelect => { + let type_option = SingleSelectTypeOption::from(&field_meta); + let select_option_context = type_option.select_option_context(&cell_meta); + data_result(select_option_context) + } + FieldType::MultiSelect => { + let type_option = MultiSelectTypeOption::from(&field_meta); + let select_option_context = type_option.select_option_context(&cell_meta); + data_result(select_option_context) + } + ty => { + tracing::error!("Unsupported field type: {:?} for this handler", ty); + data_result(SelectOptionContext::default()) + } + } + } + } +} + #[tracing::instrument(level = "debug", skip(data, manager), err)] pub(crate) async fn get_field_context_handler( data: Data, @@ -164,13 +205,13 @@ async fn get_or_create_field_meta( field_type: &FieldType, editor: Arc, ) -> FlowyResult { - if field_id.is_some() { - if let Some(field_meta) = editor.get_field(field_id.as_ref().unwrap()).await? { - return Ok(field_meta); - } + match field_id { + None => editor.create_next_field_meta(field_type).await, + Some(field_id) => match editor.get_field_metas(Some(vec![field_id.as_str()])).await?.pop() { + None => editor.create_next_field_meta(field_type).await, + Some(field_meta) => Ok(field_meta), + }, } - - editor.create_next_field_meta(field_type).await } #[tracing::instrument(level = "debug", skip(data, manager), err)] @@ -180,7 +221,7 @@ pub(crate) async fn get_row_handler( ) -> DataResult { let params: QueryRowParams = data.into_inner().try_into()?; let editor = manager.get_grid_editor(¶ms.grid_id)?; - match editor.get_row(¶ms.block_id, ¶ms.row_id).await? { + match editor.get_row(¶ms.row_id).await? { None => Err(FlowyError::record_not_found().context("Can not find the row")), Some(row) => data_result(row), } @@ -209,12 +250,13 @@ pub(crate) async fn update_cell_handler( } #[tracing::instrument(level = "debug", skip_all, err)] -pub(crate) async fn insert_select_option_handler( +pub(crate) async fn apply_select_option_changeset_handler( data: Data, manager: AppData>, ) -> Result<(), FlowyError> { let params: SelectOptionChangesetParams = data.into_inner().try_into()?; let editor = manager.get_grid_editor(¶ms.grid_id)?; - let _ = editor.insert_select_option(params).await?; + let changeset: CellMetaChangeset = params.into(); + let _ = editor.update_cell(changeset).await?; Ok(()) } diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs index 64c7c70e56..2af4b28e35 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -10,18 +10,26 @@ pub fn create(grid_manager: Arc) -> Module { module = module .event(GridEvent::GetGridData, get_grid_data_handler) .event(GridEvent::GetGridBlocks, get_grid_blocks_handler) + // Field .event(GridEvent::GetFields, get_fields_handler) .event(GridEvent::UpdateField, update_field_handler) .event(GridEvent::CreateField, create_field_handler) .event(GridEvent::DeleteField, delete_field_handler) .event(GridEvent::SwitchToField, switch_to_field_handler) .event(GridEvent::DuplicateField, duplicate_field_handler) - .event(GridEvent::GetEditFieldContext, get_field_context_handler) - .event(GridEvent::CreateSelectOption, create_select_option_handler) + // Row .event(GridEvent::CreateRow, create_row_handler) .event(GridEvent::GetRow, get_row_handler) + // Cell .event(GridEvent::UpdateCell, update_cell_handler) - .event(GridEvent::InsertSelectOption, insert_select_option_handler); + // SelectOption + .event(GridEvent::CreateSelectOption, create_select_option_handler) + .event(GridEvent::GetSelectOptions, get_select_option_handler) + .event( + GridEvent::ApplySelectOptionChangeset, + apply_select_option_changeset_handler, + ) + .event(GridEvent::GetEditFieldContext, get_field_context_handler); module } @@ -59,7 +67,7 @@ pub enum GridEvent { #[event(input = "CreateSelectOptionPayload", output = "SelectOption")] CreateSelectOption = 30, - #[event(input = "FieldIdentifierPayload", output = "SelectOptionContext")] + #[event(input = "CellIdentifierPayload", output = "SelectOptionContext")] GetSelectOptions = 31, #[event(input = "CreateRowPayload", output = "Row")] @@ -71,6 +79,6 @@ pub enum GridEvent { #[event(input = "CellMetaChangeset")] UpdateCell = 70, - #[event(input = "InsertSelectOptionPayload")] - InsertSelectOption = 71, + #[event(input = "SelectOptionChangesetPayload")] + ApplySelectOptionChangeset = 71, } diff --git a/frontend/rust-lib/flowy-grid/src/manager.rs b/frontend/rust-lib/flowy-grid/src/manager.rs index 686f539b74..d82b2950da 100644 --- a/frontend/rust-lib/flowy-grid/src/manager.rs +++ b/frontend/rust-lib/flowy-grid/src/manager.rs @@ -12,7 +12,6 @@ use flowy_revision::{RevisionManager, RevisionPersistence, RevisionWebSocket}; use flowy_sync::client_grid::{make_block_meta_delta, make_grid_delta}; use flowy_sync::entities::revision::{RepeatedRevision, Revision}; use std::sync::Arc; -use tokio::sync::RwLock; pub trait GridUser: Send + Sync { fn user_id(&self) -> Result; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs index ae1dfe161d..72a0601391 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs @@ -39,7 +39,7 @@ pub enum GridEvent { CreateRow = 50, GetRow = 51, UpdateCell = 70, - InsertSelectOption = 71, + ApplySelectOptionChangeset = 71, } impl ::protobuf::ProtobufEnum for GridEvent { @@ -63,7 +63,7 @@ impl ::protobuf::ProtobufEnum for GridEvent { 50 => ::std::option::Option::Some(GridEvent::CreateRow), 51 => ::std::option::Option::Some(GridEvent::GetRow), 70 => ::std::option::Option::Some(GridEvent::UpdateCell), - 71 => ::std::option::Option::Some(GridEvent::InsertSelectOption), + 71 => ::std::option::Option::Some(GridEvent::ApplySelectOptionChangeset), _ => ::std::option::Option::None } } @@ -84,7 +84,7 @@ impl ::protobuf::ProtobufEnum for GridEvent { GridEvent::CreateRow, GridEvent::GetRow, GridEvent::UpdateCell, - GridEvent::InsertSelectOption, + GridEvent::ApplySelectOptionChangeset, ]; values } @@ -113,14 +113,14 @@ impl ::protobuf::reflect::ProtobufValue for GridEvent { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0fevent_map.proto*\xa2\x02\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\ + \n\x0fevent_map.proto*\xaa\x02\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\ \0\x12\x11\n\rGetGridBlocks\x10\x01\x12\r\n\tGetFields\x10\n\x12\x0f\n\ \x0bUpdateField\x10\x0b\x12\x0f\n\x0bCreateField\x10\x0c\x12\x0f\n\x0bDe\ leteField\x10\r\x12\x11\n\rSwitchToField\x10\x0e\x12\x12\n\x0eDuplicateF\ ield\x10\x0f\x12\x17\n\x13GetEditFieldContext\x10\x10\x12\x16\n\x12Creat\ eSelectOption\x10\x1e\x12\x14\n\x10GetSelectOptions\x10\x1f\x12\r\n\tCre\ - ateRow\x102\x12\n\n\x06GetRow\x103\x12\x0e\n\nUpdateCell\x10F\x12\x16\n\ - \x12InsertSelectOption\x10Gb\x06proto3\ + ateRow\x102\x12\n\n\x06GetRow\x103\x12\x0e\n\nUpdateCell\x10F\x12\x1e\n\ + \x1aApplySelectOptionChangeset\x10Gb\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/model/selection_type_option.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/selection_type_option.rs index ba0e1bebe9..7a65da1171 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/selection_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/selection_type_option.rs @@ -662,6 +662,7 @@ pub struct SelectOptionChangesetPayload { // message fields pub grid_id: ::std::string::String, pub row_id: ::std::string::String, + pub field_id: ::std::string::String, // message oneof groups pub one_of_insert_option_id: ::std::option::Option, pub one_of_delete_option_id: ::std::option::Option, @@ -743,7 +744,33 @@ impl SelectOptionChangesetPayload { ::std::mem::replace(&mut self.row_id, ::std::string::String::new()) } - // string insert_option_id = 3; + // string field_id = 3; + + + pub fn get_field_id(&self) -> &str { + &self.field_id + } + pub fn clear_field_id(&mut self) { + self.field_id.clear(); + } + + // Param is passed by value, moved + pub fn set_field_id(&mut self, v: ::std::string::String) { + self.field_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_field_id(&mut self) -> &mut ::std::string::String { + &mut self.field_id + } + + // Take field + pub fn take_field_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) + } + + // string insert_option_id = 4; pub fn get_insert_option_id(&self) -> &str { @@ -792,7 +819,7 @@ impl SelectOptionChangesetPayload { } } - // string delete_option_id = 4; + // string delete_option_id = 5; pub fn get_delete_option_id(&self) -> &str { @@ -858,12 +885,15 @@ impl ::protobuf::Message for SelectOptionChangesetPayload { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?; }, 3 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; + }, + 4 => { if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } self.one_of_insert_option_id = ::std::option::Option::Some(SelectOptionChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(is.read_string()?)); }, - 4 => { + 5 => { if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } @@ -887,17 +917,20 @@ impl ::protobuf::Message for SelectOptionChangesetPayload { if !self.row_id.is_empty() { my_size += ::protobuf::rt::string_size(2, &self.row_id); } + if !self.field_id.is_empty() { + my_size += ::protobuf::rt::string_size(3, &self.field_id); + } if let ::std::option::Option::Some(ref v) = self.one_of_insert_option_id { match v { &SelectOptionChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(ref v) => { - my_size += ::protobuf::rt::string_size(3, &v); + my_size += ::protobuf::rt::string_size(4, &v); }, }; } if let ::std::option::Option::Some(ref v) = self.one_of_delete_option_id { match v { &SelectOptionChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(ref v) => { - my_size += ::protobuf::rt::string_size(4, &v); + my_size += ::protobuf::rt::string_size(5, &v); }, }; } @@ -913,17 +946,20 @@ impl ::protobuf::Message for SelectOptionChangesetPayload { if !self.row_id.is_empty() { os.write_string(2, &self.row_id)?; } + if !self.field_id.is_empty() { + os.write_string(3, &self.field_id)?; + } if let ::std::option::Option::Some(ref v) = self.one_of_insert_option_id { match v { &SelectOptionChangesetPayload_oneof_one_of_insert_option_id::insert_option_id(ref v) => { - os.write_string(3, v)?; + os.write_string(4, v)?; }, }; } if let ::std::option::Option::Some(ref v) = self.one_of_delete_option_id { match v { &SelectOptionChangesetPayload_oneof_one_of_delete_option_id::delete_option_id(ref v) => { - os.write_string(4, v)?; + os.write_string(5, v)?; }, }; } @@ -975,6 +1011,11 @@ impl ::protobuf::Message for SelectOptionChangesetPayload { |m: &SelectOptionChangesetPayload| { &m.row_id }, |m: &mut SelectOptionChangesetPayload| { &mut m.row_id }, )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "field_id", + |m: &SelectOptionChangesetPayload| { &m.field_id }, + |m: &mut SelectOptionChangesetPayload| { &mut m.field_id }, + )); fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>( "insert_option_id", SelectOptionChangesetPayload::has_insert_option_id, @@ -1003,6 +1044,7 @@ impl ::protobuf::Clear for SelectOptionChangesetPayload { fn clear(&mut self) { self.grid_id.clear(); self.row_id.clear(); + self.field_id.clear(); self.one_of_insert_option_id = ::std::option::Option::None; self.one_of_delete_option_id = ::std::option::Option::None; self.unknown_fields.clear(); @@ -1315,18 +1357,19 @@ static file_descriptor_proto_data: &'static [u8] = b"\ s\x12#\n\rdisable_color\x18\x02\x20\x01(\x08R\x0cdisableColor\"\\\n\x0cS\ electOption\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\ \x18\x02\x20\x01(\tR\x04name\x12(\n\x05color\x18\x03\x20\x01(\x0e2\x12.S\ - electOptionColorR\x05color\"\xdc\x01\n\x1cSelectOptionChangesetPayload\ + electOptionColorR\x05color\"\xf7\x01\n\x1cSelectOptionChangesetPayload\ \x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x15\n\x06row_id\ - \x18\x02\x20\x01(\tR\x05rowId\x12*\n\x10insert_option_id\x18\x03\x20\x01\ - (\tH\0R\x0einsertOptionId\x12*\n\x10delete_option_id\x18\x04\x20\x01(\tH\ - \x01R\x0edeleteOptionIdB\x19\n\x17one_of_insert_option_idB\x19\n\x17one_\ - of_delete_option_id\"t\n\x13SelectOptionContext\x12'\n\x07options\x18\ - \x01\x20\x03(\x0b2\r.SelectOptionR\x07options\x124\n\x0eselect_options\ - \x18\x02\x20\x03(\x0b2\r.SelectOptionR\rselectOptions*y\n\x11SelectOptio\ - nColor\x12\n\n\x06Purple\x10\0\x12\x08\n\x04Pink\x10\x01\x12\r\n\tLightP\ - ink\x10\x02\x12\n\n\x06Orange\x10\x03\x12\n\n\x06Yellow\x10\x04\x12\x08\ - \n\x04Lime\x10\x05\x12\t\n\x05Green\x10\x06\x12\x08\n\x04Aqua\x10\x07\ - \x12\x08\n\x04Blue\x10\x08b\x06proto3\ + \x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\x20\x01(\tR\ + \x07fieldId\x12*\n\x10insert_option_id\x18\x04\x20\x01(\tH\0R\x0einsertO\ + ptionId\x12*\n\x10delete_option_id\x18\x05\x20\x01(\tH\x01R\x0edeleteOpt\ + ionIdB\x19\n\x17one_of_insert_option_idB\x19\n\x17one_of_delete_option_i\ + d\"t\n\x13SelectOptionContext\x12'\n\x07options\x18\x01\x20\x03(\x0b2\r.\ + SelectOptionR\x07options\x124\n\x0eselect_options\x18\x02\x20\x03(\x0b2\ + \r.SelectOptionR\rselectOptions*y\n\x11SelectOptionColor\x12\n\n\x06Purp\ + le\x10\0\x12\x08\n\x04Pink\x10\x01\x12\r\n\tLightPink\x10\x02\x12\n\n\ + \x06Orange\x10\x03\x12\n\n\x06Yellow\x10\x04\x12\x08\n\x04Lime\x10\x05\ + \x12\t\n\x05Green\x10\x06\x12\x08\n\x04Aqua\x10\x07\x12\x08\n\x04Blue\ + \x10\x08b\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/event_map.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/event_map.proto index 4703711cb3..b423fee748 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/event_map.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/event_map.proto @@ -15,5 +15,5 @@ enum GridEvent { CreateRow = 50; GetRow = 51; UpdateCell = 70; - InsertSelectOption = 71; + ApplySelectOptionChangeset = 71; } diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_type_option.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_type_option.proto index 37dc0a36c1..3431373504 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_type_option.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/selection_type_option.proto @@ -16,8 +16,9 @@ message SelectOption { message SelectOptionChangesetPayload { string grid_id = 1; string row_id = 2; - oneof one_of_insert_option_id { string insert_option_id = 3; }; - oneof one_of_delete_option_id { string delete_option_id = 4; }; + string field_id = 3; + oneof one_of_insert_option_id { string insert_option_id = 4; }; + oneof one_of_delete_option_id { string delete_option_id = 5; }; } message SelectOptionContext { repeated SelectOption options = 1; diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs index c5082a1c2e..abdf1d5cbe 100644 --- a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs @@ -22,9 +22,6 @@ use std::collections::HashMap; use std::sync::Arc; use tokio::sync::RwLock; -type RowId = String; -type BlockId = String; - pub(crate) struct GridBlockMetaEditorManager { grid_id: String, user: Arc, @@ -145,6 +142,11 @@ impl GridBlockMetaEditorManager { for block_id in block_ids { let editor = self.get_editor(&block_id).await?; let row_metas = editor.get_row_metas(None).await?; + + row_metas.iter().for_each(|row| { + let _ = self.persistence.insert_or_update(&row.block_id, &row.id); + }); + snapshots.push(GridBlockSnapshot { block_id, row_metas }); } Ok(snapshots) diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs index b91409c904..2afdadb2f4 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs @@ -1,10 +1,10 @@ use crate::impl_type_option; use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; -use crate::services::row::{CellDataOperation, TypeOptionCellData}; +use crate::services::row::{CellDataChangeset, CellDataOperation, TypeOptionCellData}; use bytes::Bytes; use flowy_derive::ProtoBuf; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry}; +use flowy_grid_data_model::entities::{CellMeta, FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry}; use serde::{Deserialize, Serialize}; use std::str::FromStr; @@ -41,7 +41,7 @@ const YES: &str = "Yes"; const NO: &str = "No"; impl CellDataOperation for CheckboxTypeOption { - fn deserialize_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { + fn decode_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) { if !type_option_cell_data.is_text() || !type_option_cell_data.is_checkbox() { return String::new(); @@ -55,8 +55,13 @@ impl CellDataOperation for CheckboxTypeOption { String::new() } - fn serialize_cell_data(&self, data: &str) -> Result { - let s = match string_to_bool(data) { + fn apply_changeset>( + &self, + changeset: T, + cell_meta: Option, + ) -> Result { + let changeset = changeset.into(); + let s = match string_to_bool(&changeset) { true => YES, false => NO, }; @@ -89,16 +94,16 @@ mod tests { let type_option = CheckboxTypeOption::default(); let field_meta = FieldBuilder::from_field_type(&FieldType::DateTime).build(); - assert_eq!(type_option.serialize_cell_data("true").unwrap(), "1".to_owned()); - assert_eq!(type_option.serialize_cell_data("1").unwrap(), "1".to_owned()); - assert_eq!(type_option.serialize_cell_data("yes").unwrap(), "1".to_owned()); + assert_eq!(type_option.apply_changeset("true").unwrap(), "1".to_owned()); + assert_eq!(type_option.apply_changeset("1").unwrap(), "1".to_owned()); + assert_eq!(type_option.apply_changeset("yes").unwrap(), "1".to_owned()); - assert_eq!(type_option.serialize_cell_data("false").unwrap(), "0".to_owned()); - assert_eq!(type_option.serialize_cell_data("no").unwrap(), "0".to_owned()); - assert_eq!(type_option.serialize_cell_data("123").unwrap(), "0".to_owned()); + assert_eq!(type_option.apply_changeset("false").unwrap(), "0".to_owned()); + assert_eq!(type_option.apply_changeset("no").unwrap(), "0".to_owned()); + assert_eq!(type_option.apply_changeset("123").unwrap(), "0".to_owned()); assert_eq!( - type_option.deserialize_cell_data("1".to_owned(), &field_meta), + type_option.decode_cell_data("1".to_owned(), &field_meta), "1".to_owned() ); } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs index 2c67c69fe5..6472b91bb7 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs @@ -1,11 +1,11 @@ use crate::impl_type_option; -use crate::services::row::{CellDataOperation, TypeOptionCellData}; +use crate::services::row::{CellDataChangeset, CellDataOperation, TypeOptionCellData}; use bytes::Bytes; use chrono::format::strftime::StrftimeItems; use chrono::NaiveDateTime; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry}; +use flowy_grid_data_model::entities::{CellMeta, FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry}; use serde::{Deserialize, Serialize}; use std::str::FromStr; @@ -43,7 +43,7 @@ impl DateTypeOption { } impl CellDataOperation for DateTypeOption { - fn deserialize_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { + fn decode_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) { if !type_option_cell_data.is_date() { return String::new(); @@ -63,13 +63,18 @@ impl CellDataOperation for DateTypeOption { String::new() } - fn serialize_cell_data(&self, data: &str) -> Result { - if let Err(e) = data.parse::() { - tracing::error!("Parse {} to i64 failed: {}", data, e); + fn apply_changeset>( + &self, + changeset: T, + cell_meta: Option, + ) -> Result { + let changeset = changeset.into(); + if let Err(e) = changeset.parse::() { + tracing::error!("Parse {} to i64 failed: {}", changeset.to_string(), e); return Err(FlowyError::internal().context(e)); }; - Ok(TypeOptionCellData::new(data, self.field_type()).json()) + Ok(TypeOptionCellData::new(changeset, self.field_type()).json()) } } @@ -195,7 +200,7 @@ mod tests { let field_meta = FieldBuilder::from_field_type(&FieldType::Number).build(); assert_eq!( "".to_owned(), - type_option.deserialize_cell_data("1e".to_owned(), &field_meta) + type_option.decode_cell_data("1e".to_owned(), &field_meta) ); } @@ -209,33 +214,33 @@ mod tests { DateFormat::Friendly => { assert_eq!( "Mar 14,2022 17:56".to_owned(), - type_option.deserialize_cell_data(data("1647251762"), &field_meta) + type_option.decode_cell_data(data("1647251762"), &field_meta) ); assert_eq!( "Mar 14,2022 17:56".to_owned(), - type_option.deserialize_cell_data(data("Mar 14,2022 17:56"), &field_meta) + type_option.decode_cell_data(data("Mar 14,2022 17:56"), &field_meta) ); } DateFormat::US => { assert_eq!( "2022/03/14 17:56".to_owned(), - type_option.deserialize_cell_data(data("1647251762"), &field_meta) + type_option.decode_cell_data(data("1647251762"), &field_meta) ); assert_eq!( "2022/03/14 17:56".to_owned(), - type_option.deserialize_cell_data(data("2022/03/14 17:56"), &field_meta) + type_option.decode_cell_data(data("2022/03/14 17:56"), &field_meta) ); } DateFormat::ISO => { assert_eq!( "2022-03-14 17:56".to_owned(), - type_option.deserialize_cell_data(data("1647251762"), &field_meta) + type_option.decode_cell_data(data("1647251762"), &field_meta) ); } DateFormat::Local => { assert_eq!( "2022/03/14 17:56".to_owned(), - type_option.deserialize_cell_data(data("1647251762"), &field_meta) + type_option.decode_cell_data(data("1647251762"), &field_meta) ); } } @@ -256,7 +261,7 @@ mod tests { ); assert_eq!( "Mar 14,2022 17:56".to_owned(), - type_option.deserialize_cell_data(data("1647251762"), &field_meta) + type_option.decode_cell_data(data("1647251762"), &field_meta) ); } TimeFormat::TwelveHour => { @@ -266,7 +271,7 @@ mod tests { ); assert_eq!( "Mar 14,2022 05:56:02 PM".to_owned(), - type_option.deserialize_cell_data(data("1647251762"), &field_meta) + type_option.decode_cell_data(data("1647251762"), &field_meta) ); } } @@ -277,7 +282,7 @@ mod tests { #[should_panic] fn date_description_invalid_data_test() { let type_option = DateTypeOption::default(); - type_option.serialize_cell_data("he").unwrap(); + type_option.apply_changeset("he").unwrap(); } fn data(s: &str) -> String { diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs index 55ce729a7f..b0b5967a9d 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs @@ -1,8 +1,8 @@ use crate::impl_type_option; -use crate::services::row::{CellDataOperation, TypeOptionCellData}; +use crate::services::row::{CellDataChangeset, CellDataOperation, TypeOptionCellData}; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry}; +use flowy_grid_data_model::entities::{CellMeta, FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry}; use lazy_static::lazy_static; use rust_decimal::Decimal; @@ -77,7 +77,7 @@ pub struct NumberTypeOption { impl_type_option!(NumberTypeOption, FieldType::Number); impl CellDataOperation for NumberTypeOption { - fn deserialize_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { + fn decode_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) { if type_option_cell_data.is_date() { return String::new(); @@ -101,8 +101,13 @@ impl CellDataOperation for NumberTypeOption { } } - fn serialize_cell_data(&self, data: &str) -> Result { - let data = self.strip_symbol(data); + fn apply_changeset>( + &self, + changeset: T, + cell_meta: Option, + ) -> Result { + let changeset = changeset.into(); + let data = self.strip_symbol(changeset); if !data.chars().all(char::is_numeric) { return Err(FlowyError::invalid_data().context("Should only contain numbers")); @@ -149,8 +154,8 @@ impl NumberTypeOption { } } - fn strip_symbol(&self, s: &str) -> String { - let mut s = String::from(s); + fn strip_symbol(&self, s: T) -> String { + let mut s = s.to_string(); if !s.chars().all(char::is_numeric) { s.retain(|c| !STRIP_SYMBOL.contains(&c.to_string())); } @@ -213,11 +218,8 @@ mod tests { fn number_description_invalid_input_test() { let type_option = NumberTypeOption::default(); let field_meta = FieldBuilder::from_field_type(&FieldType::Number).build(); - assert_eq!("".to_owned(), type_option.deserialize_cell_data(data(""), &field_meta)); - assert_eq!( - "".to_owned(), - type_option.deserialize_cell_data(data("abc"), &field_meta) - ); + assert_eq!("".to_owned(), type_option.decode_cell_data(data(""), &field_meta)); + assert_eq!("".to_owned(), type_option.decode_cell_data(data("abc"), &field_meta)); } #[test] @@ -233,30 +235,27 @@ mod tests { match format { NumberFormat::Number => { assert_eq!( - type_option.deserialize_cell_data(data("18443"), &field_meta), + type_option.decode_cell_data(data("18443"), &field_meta), "18443".to_owned() ); } NumberFormat::USD => { assert_eq!( - type_option.deserialize_cell_data(data("18443"), &field_meta), + type_option.decode_cell_data(data("18443"), &field_meta), "$18,443".to_owned() ); - assert_eq!(type_option.deserialize_cell_data(data(""), &field_meta), "".to_owned()); - assert_eq!( - type_option.deserialize_cell_data(data("abc"), &field_meta), - "".to_owned() - ); + assert_eq!(type_option.decode_cell_data(data(""), &field_meta), "".to_owned()); + assert_eq!(type_option.decode_cell_data(data("abc"), &field_meta), "".to_owned()); } NumberFormat::CNY => { assert_eq!( - type_option.deserialize_cell_data(data("18443"), &field_meta), + type_option.decode_cell_data(data("18443"), &field_meta), "¥18,443".to_owned() ); } NumberFormat::EUR => { assert_eq!( - type_option.deserialize_cell_data(data("18443"), &field_meta), + type_option.decode_cell_data(data("18443"), &field_meta), "€18.443".to_owned() ); } @@ -281,25 +280,25 @@ mod tests { match format { NumberFormat::Number => { assert_eq!( - type_option.deserialize_cell_data(data("18443"), &field_meta), + type_option.decode_cell_data(data("18443"), &field_meta), "18443".to_owned() ); } NumberFormat::USD => { assert_eq!( - type_option.deserialize_cell_data(data("18443"), &field_meta), + type_option.decode_cell_data(data("18443"), &field_meta), "$1,844.3".to_owned() ); } NumberFormat::CNY => { assert_eq!( - type_option.deserialize_cell_data(data("18443"), &field_meta), + type_option.decode_cell_data(data("18443"), &field_meta), "¥1,844.3".to_owned() ); } NumberFormat::EUR => { assert_eq!( - type_option.deserialize_cell_data(data("18443"), &field_meta), + type_option.decode_cell_data(data("18443"), &field_meta), "€1.844,3".to_owned() ); } @@ -320,25 +319,25 @@ mod tests { match format { NumberFormat::Number => { assert_eq!( - type_option.deserialize_cell_data(data("18443"), &field_meta), + type_option.decode_cell_data(data("18443"), &field_meta), "18443".to_owned() ); } NumberFormat::USD => { assert_eq!( - type_option.deserialize_cell_data(data("18443"), &field_meta), + type_option.decode_cell_data(data("18443"), &field_meta), "-$18,443".to_owned() ); } NumberFormat::CNY => { assert_eq!( - type_option.deserialize_cell_data(data("18443"), &field_meta), + type_option.decode_cell_data(data("18443"), &field_meta), "-¥18,443".to_owned() ); } NumberFormat::EUR => { assert_eq!( - type_option.deserialize_cell_data(data("18443"), &field_meta), + type_option.decode_cell_data(data("18443"), &field_meta), "-€18.443".to_owned() ); } 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 1774b12ce3..07bef42e5f 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,11 +1,13 @@ use crate::impl_type_option; use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; -use crate::services::row::{CellDataOperation, TypeOptionCellData}; +use crate::services::row::{CellDataChangeset, CellDataOperation, TypeOptionCellData}; use crate::services::util::*; use bytes::Bytes; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::{ErrorCode, FlowyError, FlowyResult}; -use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry}; +use flowy_grid_data_model::entities::{ + CellMeta, CellMetaChangeset, FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry, +}; use flowy_grid_data_model::parser::{NotEmptyStr, NotEmptyUuid}; use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; use serde::{Deserialize, Serialize}; @@ -25,26 +27,66 @@ pub struct SingleSelectTypeOption { } impl_type_option!(SingleSelectTypeOption, FieldType::SingleSelect); +impl SingleSelectTypeOption { + pub fn select_option_context(&self, cell_meta: &Option) -> SelectOptionContext { + let select_options = make_select_context_from(cell_meta, &self.options); + SelectOptionContext { + options: self.options.clone(), + select_options, + } + } +} + +fn make_select_context_from(cell_meta: &Option, options: &Vec) -> Vec { + match cell_meta { + None => vec![], + Some(cell_meta) => { + if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&cell_meta.data) { + select_option_ids(type_option_cell_data.data) + .into_iter() + .flat_map(|option_id| options.iter().find(|option| option.id == option_id).cloned()) + .collect() + } else { + vec![] + } + } + } +} + impl CellDataOperation for SingleSelectTypeOption { - fn deserialize_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { + fn decode_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) { - if !type_option_cell_data.is_single_select() || !type_option_cell_data.is_multi_select() { + if !type_option_cell_data.is_single_select() { return String::new(); } - let option_id = type_option_cell_data.data; - match self.options.iter().find(|option| option.id == option_id) { + match select_option_ids(type_option_cell_data.data).pop() { None => String::new(), - Some(option) => option.name.clone(), + Some(option_id) => match self.options.iter().find(|option| option.id == option_id) { + None => String::new(), + Some(option) => option.name.clone(), + }, } } else { String::new() } } - fn serialize_cell_data(&self, data: &str) -> Result { - let data = single_select_option_id_from_data(data.to_owned())?; - Ok(TypeOptionCellData::new(&data, self.field_type()).json()) + fn apply_changeset>( + &self, + changeset: T, + _cell_meta: Option, + ) -> Result { + let changeset = changeset.into(); + let select_option_changeset: SelectOptionChangeset = serde_json::from_str(&changeset)?; + let new_cell_data: String; + if let Some(insert_option_id) = select_option_changeset.insert_option_id { + new_cell_data = insert_option_id; + } else { + new_cell_data = "".to_string() + } + + return Ok(TypeOptionCellData::new(&new_cell_data, self.field_type()).json()); } } @@ -81,33 +123,59 @@ pub struct MultiSelectTypeOption { } impl_type_option!(MultiSelectTypeOption, FieldType::MultiSelect); +impl MultiSelectTypeOption { + pub fn select_option_context(&self, cell_meta: &Option) -> SelectOptionContext { + todo!() + } +} + impl CellDataOperation for MultiSelectTypeOption { - fn deserialize_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { + fn decode_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) { - if !type_option_cell_data.is_single_select() || !type_option_cell_data.is_multi_select() { + if !type_option_cell_data.is_multi_select() { return String::new(); } - - match select_option_ids(type_option_cell_data.data) { - Ok(option_ids) => { - // - self.options - .iter() - .filter(|option| option_ids.contains(&option.id)) - .map(|option| option.name.clone()) - .collect::>() - .join(SELECTION_IDS_SEPARATOR) - } - Err(_) => String::new(), - } + let option_ids = select_option_ids(type_option_cell_data.data); + self.options + .iter() + .filter(|option| option_ids.contains(&option.id)) + .map(|option| option.name.clone()) + .collect::>() + .join(SELECTION_IDS_SEPARATOR) } else { String::new() } } - fn serialize_cell_data(&self, data: &str) -> Result { - let data = multi_select_option_id_from_data(data.to_owned())?; - Ok(TypeOptionCellData::new(&data, self.field_type()).json()) + fn apply_changeset>( + &self, + changeset: T, + cell_meta: Option, + ) -> Result { + let changeset = changeset.into(); + let select_option_changeset: SelectOptionChangeset = serde_json::from_str(&changeset)?; + let new_cell_data: String; + match cell_meta { + None => { + new_cell_data = select_option_changeset + .insert_option_id + .unwrap_or_else(|| "".to_owned()); + } + Some(cell_meta) => { + let mut selected_options = select_option_ids(cell_meta.data); + if let Some(insert_option_id) = select_option_changeset.insert_option_id { + selected_options.push(insert_option_id); + } + + if let Some(delete_option_id) = select_option_changeset.delete_option_id { + selected_options.retain(|id| id != &delete_option_id); + } + + new_cell_data = selected_options.join(SELECTION_IDS_SEPARATOR); + } + } + + Ok(TypeOptionCellData::new(&new_cell_data, self.field_type()).json()) } } @@ -132,41 +200,10 @@ impl TypeOptionBuilder for MultiSelectTypeOptionBuilder { } } -fn single_select_option_id_from_data(data: String) -> FlowyResult { - let select_option_ids = select_option_ids(data)?; - if select_option_ids.is_empty() { - return Ok("".to_owned()); - } - - Ok(select_option_ids.split_first().unwrap().0.to_string()) -} - -fn multi_select_option_id_from_data(data: String) -> FlowyResult { - let select_option_ids = select_option_ids(data)?; - Ok(select_option_ids.join(SELECTION_IDS_SEPARATOR)) -} - -fn select_option_ids(mut data: String) -> FlowyResult> { - data.retain(|c| !c.is_whitespace()); - let select_option_ids = data.split(SELECTION_IDS_SEPARATOR).collect::>(); - if select_option_ids - .par_iter() - .find_first(|option_id| match Uuid::parse_str(option_id) { - Ok(_) => false, - Err(e) => { - tracing::error!("{}", e); - true - } - }) - .is_some() - { - let msg = format!( - "Invalid selection id string: {}. It should consist of the uuid string and separated by comma", - data - ); - return Err(FlowyError::internal().context(msg)); - } - Ok(select_option_ids.iter().map(|id| id.to_string()).collect::>()) +fn select_option_ids(data: String) -> Vec { + data.split(SELECTION_IDS_SEPARATOR) + .map(|id| id.to_string()) + .collect::>() } #[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)] @@ -209,7 +246,6 @@ pub struct SelectOptionChangesetPayload { pub delete_option_id: Option, } -#[derive(Clone)] pub struct SelectOptionChangesetParams { pub grid_id: String, pub field_id: String, @@ -218,6 +254,28 @@ pub struct SelectOptionChangesetParams { pub delete_option_id: Option, } +#[derive(Clone, Serialize, Deserialize)] +pub struct SelectOptionChangeset { + pub insert_option_id: Option, + pub delete_option_id: Option, +} + +impl std::convert::From for CellMetaChangeset { + fn from(params: SelectOptionChangesetParams) -> Self { + let changeset = SelectOptionChangeset { + insert_option_id: params.insert_option_id, + delete_option_id: params.delete_option_id, + }; + let s = serde_json::to_string(&changeset).unwrap(); + CellMetaChangeset { + grid_id: params.grid_id, + row_id: params.row_id, + field_id: params.field_id, + data: Some(s), + } + } +} + impl TryInto for SelectOptionChangesetPayload { type Error = ErrorCode; @@ -228,7 +286,7 @@ impl TryInto for SelectOptionChangesetPayload { let insert_option_id = match self.insert_option_id { None => None, Some(insert_option_id) => Some( - NotEmptyStr::parse(insert_option_id) + NotEmptyUuid::parse(insert_option_id) .map_err(|_| ErrorCode::OptionIdIsEmpty)? .0, ), @@ -237,7 +295,7 @@ impl TryInto for SelectOptionChangesetPayload { let delete_option_id = match self.delete_option_id { None => None, Some(delete_option_id) => Some( - NotEmptyStr::parse(delete_option_id) + NotEmptyUuid::parse(delete_option_id) .map_err(|_| ErrorCode::OptionIdIsEmpty)? .0, ), @@ -291,9 +349,9 @@ mod tests { #[should_panic] fn selection_description_test() { let type_option = SingleSelectTypeOption::default(); - assert_eq!(type_option.serialize_cell_data("1,2,3").unwrap(), "1".to_owned()); + assert_eq!(type_option.apply_changeset("1,2,3").unwrap(), "1".to_owned()); let type_option = MultiSelectTypeOption::default(); - assert_eq!(type_option.serialize_cell_data("1,2,3").unwrap(), "1,2,3".to_owned()); + assert_eq!(type_option.apply_changeset("1,2,3").unwrap(), "1,2,3".to_owned()); } } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs index 4b7195a305..f38f24ac9d 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs @@ -1,10 +1,10 @@ use crate::impl_type_option; use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; -use crate::services::row::{deserialize_cell_data, CellDataOperation, TypeOptionCellData}; +use crate::services::row::{decode_cell_data, CellDataChangeset, CellDataOperation, TypeOptionCellData}; use bytes::Bytes; use flowy_derive::ProtoBuf; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry}; +use flowy_grid_data_model::entities::{CellMeta, FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry}; use serde::{Deserialize, Serialize}; use std::str::FromStr; @@ -31,14 +31,14 @@ pub struct RichTextTypeOption { impl_type_option!(RichTextTypeOption, FieldType::RichText); impl CellDataOperation for RichTextTypeOption { - fn deserialize_cell_data(&self, data: String, field_meta: &FieldMeta) -> String { + fn decode_cell_data(&self, data: String, field_meta: &FieldMeta) -> String { if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) { if type_option_cell_data.is_date() || type_option_cell_data.is_single_select() || type_option_cell_data.is_multi_select() || type_option_cell_data.is_number() { - deserialize_cell_data(data, field_meta).unwrap_or_else(|_| "".to_owned()) + decode_cell_data(data, field_meta).unwrap_or_else(|_| "".to_owned()) } else { type_option_cell_data.data } @@ -47,8 +47,12 @@ impl CellDataOperation for RichTextTypeOption { } } - fn serialize_cell_data(&self, data: &str) -> Result { - let data = data.to_owned(); + fn apply_changeset>( + &self, + changeset: T, + cell_meta: Option, + ) -> Result { + let data = changeset.into(); if data.len() > 10000 { Err(FlowyError::text_too_long().context("The len of the text should not be more than 10000")) } else { @@ -72,7 +76,7 @@ mod tests { let date_time_field_meta = FieldBuilder::from_field_type(&FieldType::DateTime).build(); let data = TypeOptionCellData::new("1647251762", FieldType::DateTime).json(); assert_eq!( - type_option.deserialize_cell_data(data, &date_time_field_meta), + type_option.decode_cell_data(data, &date_time_field_meta), "Mar 14,2022 17:56".to_owned() ); @@ -83,7 +87,7 @@ mod tests { let single_select_field_meta = FieldBuilder::new(single_select).build(); let data = TypeOptionCellData::new(&done_option_id, FieldType::SingleSelect).json(); assert_eq!( - type_option.deserialize_cell_data(data, &single_select_field_meta), + type_option.decode_cell_data(data, &single_select_field_meta), "Done".to_owned() ); @@ -103,7 +107,7 @@ mod tests { ) .json(); assert_eq!( - type_option.deserialize_cell_data(data, &multi_select_field_meta), + type_option.decode_cell_data(data, &multi_select_field_meta), "Google,Facebook".to_owned() ); @@ -112,7 +116,7 @@ mod tests { let number_field_meta = FieldBuilder::new(number).build(); let data = TypeOptionCellData::new("18443", FieldType::Number).json(); assert_eq!( - type_option.deserialize_cell_data(data, &number_field_meta), + type_option.decode_cell_data(data, &number_field_meta), "$18,443".to_owned() ); } 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 708e07fd74..17fb852e07 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -1,9 +1,7 @@ use crate::dart_notification::{send_dart_notification, GridNotification}; use crate::manager::GridUser; use crate::services::block_meta_editor::GridBlockMetaEditorManager; -use crate::services::field::{ - default_type_option_builder_from_type, type_option_builder_from_bytes, FieldBuilder, SelectOptionChangesetParams, -}; +use crate::services::field::{default_type_option_builder_from_type, type_option_builder_from_bytes, FieldBuilder}; use crate::services::persistence::block_index::BlockIndexPersistence; use crate::services::row::*; use bytes::Bytes; @@ -40,7 +38,7 @@ impl ClientGridEditor { 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().clone(); + let blocks = pad.read().await.get_block_metas(); let block_meta_manager = Arc::new(GridBlockMetaEditorManager::new(grid_id, &user, blocks, persistence).await?); Ok(Arc::new(Self { @@ -100,7 +98,7 @@ impl ClientGridEditor { pub async fn update_field(&self, params: FieldChangesetParams) -> FlowyResult<()> { let field_id = params.field_id.clone(); - let deserializer = match self.pad.read().await.get_field(¶ms.field_id) { + let deserializer = match self.pad.read().await.get_field(params.field_id.as_str()) { None => return Err(ErrorCode::FieldDoesNotExist.into()), Some(field_meta) => TypeOptionChangesetDeserializer(field_meta.field_type.clone()), }; @@ -147,11 +145,27 @@ impl ClientGridEditor { Ok(()) } - pub async fn get_field(&self, field_id: &str) -> FlowyResult> { - match self.pad.read().await.get_field(field_id) { - None => Ok(None), - Some(field_meta) => Ok(Some(field_meta.clone())), + pub async fn get_field_metas(&self, field_orders: Option>) -> FlowyResult> + where + T: Into, + { + if field_orders.is_none() { + let field_metas = self.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_orders.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))?; + if expected_len != 0 && field_metas.len() != expected_len { + tracing::error!( + "This is a bug. The len of the field_metas should equal to {}", + expected_len + ); + debug_assert!(field_metas.len() == expected_len); + } + Ok(field_metas) } pub async fn create_block(&self, grid_block: GridBlockMeta) -> FlowyResult<()> { @@ -217,7 +231,7 @@ impl ClientGridEditor { debug_assert_eq!(grid_block_snapshot.len(), 1); if grid_block_snapshot.len() == 1 { let snapshot = grid_block_snapshot.pop().unwrap(); - let field_metas = self.get_field_metas(None).await?; + let field_metas = self.get_field_metas::(None).await?; let rows = make_rows_from_row_metas(&field_metas, &snapshot.row_metas); Ok(rows.into()) } else { @@ -229,7 +243,7 @@ impl ClientGridEditor { match self.block_meta_manager.get_row_meta(row_id).await? { None => Ok(None), Some(row_meta) => { - let field_metas = self.get_field_metas(None).await?; + let field_metas = self.get_field_metas::(None).await?; let row_metas = vec![row_meta]; let mut rows = make_rows_from_row_metas(&field_metas, &row_metas); debug_assert!(rows.len() == 1); @@ -249,32 +263,30 @@ impl ClientGridEditor { } } - pub async fn apply_select_option(&self, params: SelectOptionChangesetParams) -> FlowyResult<()> { - let cell_meta = self.get_cell_meta(¶ms.row_id, ¶ms.field_id).await?; - todo!() - } - pub async fn update_cell(&self, mut changeset: CellMetaChangeset) -> FlowyResult<()> { - if let Some(cell_data) = changeset.data.as_ref() { - match self.pad.read().await.get_field(&changeset.field_id) { - None => { - let msg = format!("Can not find the field with id: {}", &changeset.field_id); - return Err(FlowyError::internal().context(msg)); - } - Some(field_meta) => { - let cell_data = serialize_cell_data(cell_data, field_meta)?; - changeset.data = Some(cell_data); - } - } + if changeset.data.as_ref().is_none() { + return Ok(()); } - let field_metas = self.get_field_metas(None).await?; - let row_changeset: RowMetaChangeset = changeset.into(); - let _ = self - .block_meta_manager - .update_row_cells(&field_metas, row_changeset) - .await?; - Ok(()) + let cell_data_changeset = changeset.data.unwrap(); + let cell_meta = self.get_cell_meta(&changeset.row_id, &changeset.field_id).await?; + match self.pad.read().await.get_field(&changeset.field_id) { + None => { + let msg = format!("Field not found with id: {}", &changeset.field_id); + return Err(FlowyError::internal().context(msg)); + } + Some(field_meta) => { + // Update the changeset.data property with the return value. + changeset.data = Some(apply_cell_data_changeset(cell_data_changeset, cell_meta, field_meta)?); + let field_metas = self.get_field_metas::(None).await?; + let row_changeset: RowMetaChangeset = changeset.into(); + let _ = self + .block_meta_manager + .update_row_cells(&field_metas, row_changeset) + .await?; + Ok(()) + } + } } pub async fn get_blocks(&self, block_ids: Option>) -> FlowyResult { @@ -314,23 +326,6 @@ impl ClientGridEditor { }) } - pub async fn get_field_metas(&self, field_orders: Option>) -> FlowyResult> { - let expected_len = match field_orders.as_ref() { - None => 0, - Some(field_orders) => field_orders.len(), - }; - - let field_metas = self.pad.read().await.get_field_metas(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 {}", - expected_len - ); - debug_assert!(field_metas.len() == expected_len); - } - Ok(field_metas) - } - pub async fn grid_block_snapshots(&self, block_ids: Option>) -> FlowyResult> { let block_ids = match block_ids { None => self @@ -393,7 +388,7 @@ impl ClientGridEditor { } async fn notify_did_update_fields(&self) -> FlowyResult<()> { - let field_metas = self.get_field_metas(None).await?; + let field_metas = self.get_field_metas::(None).await?; let repeated_field: RepeatedField = field_metas.into_iter().map(Field::from).collect::>().into(); send_dart_notification(&self.grid_id, GridNotification::DidUpdateFields) .payload(repeated_field) @@ -402,8 +397,7 @@ impl ClientGridEditor { } async fn notify_did_update_field(&self, field_id: &str) -> FlowyResult<()> { - let field_order = FieldOrder::from(field_id); - let mut field_metas = self.get_field_metas(Some(field_order.into())).await?; + 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() { diff --git a/frontend/rust-lib/flowy-grid/src/services/persistence/block_index.rs b/frontend/rust-lib/flowy-grid/src/services/persistence/block_index.rs index a639776394..df75ec629c 100644 --- a/frontend/rust-lib/flowy-grid/src/services/persistence/block_index.rs +++ b/frontend/rust-lib/flowy-grid/src/services/persistence/block_index.rs @@ -3,7 +3,6 @@ use diesel::{ExpressionMethods, QueryDsl, RunQueryDsl}; use flowy_database::{ prelude::*, schema::{grid_block_index_table, grid_block_index_table::dsl}, - ConnectionPool, }; use flowy_error::FlowyResult; use std::sync::Arc; diff --git a/frontend/rust-lib/flowy-grid/src/services/persistence/kv.rs b/frontend/rust-lib/flowy-grid/src/services/persistence/kv.rs index cf66211fab..06a5a2d68f 100644 --- a/frontend/rust-lib/flowy-grid/src/services/persistence/kv.rs +++ b/frontend/rust-lib/flowy-grid/src/services/persistence/kv.rs @@ -5,7 +5,6 @@ use diesel::SqliteConnection; use flowy_database::{ prelude::*, schema::{kv_table, kv_table::dsl}, - ConnectionPool, }; use flowy_error::{FlowyError, FlowyResult}; use std::sync::Arc; diff --git a/frontend/rust-lib/flowy-grid/src/services/row/cell_data_operation.rs b/frontend/rust-lib/flowy-grid/src/services/row/cell_data_operation.rs index ad0dcb1646..9c8a04bdc3 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/cell_data_operation.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/cell_data_operation.rs @@ -1,16 +1,44 @@ use crate::services::field::*; -use bytes::Bytes; +use std::fmt::Formatter; + use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{FieldMeta, FieldType}; +use flowy_grid_data_model::entities::{CellMeta, FieldMeta, FieldType}; use serde::{Deserialize, Serialize}; pub trait CellDataOperation { - fn deserialize_cell_data(&self, data: String, field_meta: &FieldMeta) -> String; - fn serialize_cell_data(&self, data: &str) -> Result; - // fn apply_changeset() + fn decode_cell_data(&self, data: String, field_meta: &FieldMeta) -> String; + fn apply_changeset>( + &self, + changeset: T, + cell_meta: Option, + ) -> Result; } -#[derive(Serialize, Deserialize)] +#[derive(Debug)] +pub struct CellDataChangeset(String); + +impl std::fmt::Display for CellDataChangeset { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", &self.0) + } +} + +impl> std::convert::From for CellDataChangeset { + fn from(s: T) -> Self { + let s = s.as_ref().to_owned(); + CellDataChangeset(s) + } +} + +impl std::ops::Deref for CellDataChangeset { + type Target = str; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +#[derive(Debug, Serialize, Deserialize)] pub struct TypeOptionCellData { pub data: String, pub field_type: FieldType, @@ -26,9 +54,9 @@ impl std::str::FromStr for TypeOptionCellData { } impl TypeOptionCellData { - pub fn new(data: &str, field_type: FieldType) -> Self { + pub fn new(data: T, field_type: FieldType) -> Self { TypeOptionCellData { - data: data.to_owned(), + data: data.to_string(), field_type, } } @@ -62,25 +90,34 @@ impl TypeOptionCellData { } } -pub fn serialize_cell_data(data: &str, field_meta: &FieldMeta) -> Result { +/// The function,apply_cell_data_changeset, will apply the cell_data_changeset. +/// +/// The cell_data_changeset will be deserialized into specific data base on the FieldType. +pub fn apply_cell_data_changeset>( + changeset: T, + cell_meta: Option, + field_meta: &FieldMeta, +) -> Result { match field_meta.field_type { - FieldType::RichText => RichTextTypeOption::from(field_meta).serialize_cell_data(data), - FieldType::Number => NumberTypeOption::from(field_meta).serialize_cell_data(data), - FieldType::DateTime => DateTypeOption::from(field_meta).serialize_cell_data(data), - FieldType::SingleSelect => SingleSelectTypeOption::from(field_meta).serialize_cell_data(data), - FieldType::MultiSelect => MultiSelectTypeOption::from(field_meta).serialize_cell_data(data), - FieldType::Checkbox => CheckboxTypeOption::from(field_meta).serialize_cell_data(data), + FieldType::RichText => RichTextTypeOption::from(field_meta).apply_changeset(changeset, cell_meta), + FieldType::Number => NumberTypeOption::from(field_meta).apply_changeset(changeset, cell_meta), + FieldType::DateTime => DateTypeOption::from(field_meta).apply_changeset(changeset, cell_meta), + FieldType::SingleSelect => SingleSelectTypeOption::from(field_meta).apply_changeset(changeset, cell_meta), + FieldType::MultiSelect => MultiSelectTypeOption::from(field_meta).apply_changeset(changeset, cell_meta), + FieldType::Checkbox => CheckboxTypeOption::from(field_meta).apply_changeset(changeset, cell_meta), } } -pub fn deserialize_cell_data(data: String, field_meta: &FieldMeta) -> Result { +#[tracing::instrument(level = "trace", skip(field_meta, data), fields(content), err)] +pub fn decode_cell_data(data: String, field_meta: &FieldMeta) -> Result { let s = match field_meta.field_type { - FieldType::RichText => RichTextTypeOption::from(field_meta).deserialize_cell_data(data, field_meta), - FieldType::Number => NumberTypeOption::from(field_meta).deserialize_cell_data(data, field_meta), - FieldType::DateTime => DateTypeOption::from(field_meta).deserialize_cell_data(data, field_meta), - FieldType::SingleSelect => SingleSelectTypeOption::from(field_meta).deserialize_cell_data(data, field_meta), - FieldType::MultiSelect => MultiSelectTypeOption::from(field_meta).deserialize_cell_data(data, field_meta), - FieldType::Checkbox => CheckboxTypeOption::from(field_meta).deserialize_cell_data(data, field_meta), + FieldType::RichText => RichTextTypeOption::from(field_meta).decode_cell_data(data, field_meta), + FieldType::Number => NumberTypeOption::from(field_meta).decode_cell_data(data, field_meta), + FieldType::DateTime => DateTypeOption::from(field_meta).decode_cell_data(data, field_meta), + FieldType::SingleSelect => SingleSelectTypeOption::from(field_meta).decode_cell_data(data, field_meta), + FieldType::MultiSelect => MultiSelectTypeOption::from(field_meta).decode_cell_data(data, field_meta), + FieldType::Checkbox => CheckboxTypeOption::from(field_meta).decode_cell_data(data, field_meta), }; + tracing::Span::current().record("content", &format!("{:?}: {}", field_meta.field_type, s).as_str()); Ok(s) } diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs index 698d4ac4ec..22fc0f14ae 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs @@ -1,5 +1,5 @@ -use crate::services::row::serialize_cell_data; -use bytes::Bytes; +use crate::services::row::apply_cell_data_changeset; + use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{CellMeta, FieldMeta, RowMeta, DEFAULT_ROW_HEIGHT}; use std::collections::HashMap; @@ -36,7 +36,7 @@ impl<'a> CreateRowMetaBuilder<'a> { Err(FlowyError::internal().context(msg)) } Some(field_meta) => { - let data = serialize_cell_data(&data, field_meta)?; + let data = apply_cell_data_changeset(&data, None, field_meta)?; let cell = CellMeta::new(field_id, data); self.payload.cell_by_field_id.insert(field_id.to_owned(), cell); Ok(()) diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs index c497d7e12d..b37d937c0f 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs @@ -1,4 +1,4 @@ -use crate::services::row::deserialize_cell_data; +use crate::services::row::decode_cell_data; use flowy_error::FlowyResult; use flowy_grid_data_model::entities::{ Cell, CellMeta, FieldMeta, GridBlock, RepeatedGridBlock, Row, RowMeta, RowOrder, @@ -47,7 +47,7 @@ pub fn make_cell_by_field_id( cell_meta: CellMeta, ) -> Option<(String, Cell)> { let field_meta = field_map.get(&field_id)?; - match deserialize_cell_data(cell_meta.data, field_meta) { + match decode_cell_data(cell_meta.data, field_meta) { Ok(content) => { let cell = Cell::new(&field_id, content); Some((field_id, cell)) @@ -62,8 +62,8 @@ pub fn make_cell_by_field_id( #[allow(dead_code)] pub fn make_cell(field_id: &str, field_meta: &FieldMeta, row_meta: &RowMeta) -> Option { let cell_meta = row_meta.cell_by_field_id.get(field_id)?.clone(); - match deserialize_cell_data(cell_meta.data, field_meta) { - Ok(content) => Some(Cell::new(&field_id, content)), + match decode_cell_data(cell_meta.data, field_meta) { + Ok(content) => Some(Cell::new(field_id, content)), Err(e) => { tracing::error!("{}", e); None diff --git a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs index 26dd3896dc..c14c937f00 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -4,7 +4,7 @@ use chrono::NaiveDateTime; use flowy_grid::services::field::{ MultiSelectTypeOption, SelectOption, SingleSelectTypeOption, SELECTION_IDS_SEPARATOR, }; -use flowy_grid::services::row::{deserialize_cell_data, serialize_cell_data, CellDataOperation, CreateRowMetaBuilder}; +use flowy_grid::services::row::{apply_cell_data_changeset, decode_cell_data, CellDataOperation, CreateRowMetaBuilder}; use flowy_grid_data_model::entities::{ CellMetaChangeset, FieldChangesetParams, FieldType, GridBlockMeta, GridBlockMetaChangeset, RowMetaChangeset, TypeOptionDataEntry, @@ -242,21 +242,21 @@ async fn grid_row_add_cells_test() { for field in &test.field_metas { match field.field_type { FieldType::RichText => { - let data = serialize_cell_data("hello world", field).unwrap(); + let data = apply_cell_data_changeset("hello world", field).unwrap(); builder.add_cell(&field.id, data).unwrap(); } FieldType::Number => { - let data = serialize_cell_data("¥18,443", field).unwrap(); + let data = apply_cell_data_changeset("¥18,443", field).unwrap(); builder.add_cell(&field.id, data).unwrap(); } FieldType::DateTime => { - let data = serialize_cell_data("1647251762", field).unwrap(); + let data = apply_cell_data_changeset("1647251762", field).unwrap(); builder.add_cell(&field.id, data).unwrap(); } FieldType::SingleSelect => { let type_option = SingleSelectTypeOption::from(field); let options = type_option.options.first().unwrap(); - let data = type_option.serialize_cell_data(&options.id).unwrap(); + let data = type_option.apply_changeset(&options.id).unwrap(); builder.add_cell(&field.id, data).unwrap(); } FieldType::MultiSelect => { @@ -267,11 +267,11 @@ async fn grid_row_add_cells_test() { .map(|option| option.id.clone()) .collect::>() .join(SELECTION_IDS_SEPARATOR); - let data = type_option.serialize_cell_data(&options).unwrap(); + let data = type_option.apply_changeset(&options).unwrap(); builder.add_cell(&field.id, data).unwrap(); } FieldType::Checkbox => { - let data = serialize_cell_data("false", field).unwrap(); + let data = apply_cell_data_changeset("false", field).unwrap(); builder.add_cell(&field.id, data).unwrap(); } } @@ -357,7 +357,7 @@ async fn grid_row_add_date_cell_test() { let date_field = date_field.unwrap(); let cell_data = context.cell_by_field_id.get(&date_field.id).unwrap().clone(); assert_eq!( - deserialize_cell_data(cell_data.data.clone(), &date_field).unwrap(), + decode_cell_data(cell_data.data.clone(), &date_field).unwrap(), "2022/03/16 08:31", ); let scripts = vec![CreateRow { context }]; diff --git a/shared-lib/flowy-grid-data-model/src/entities/grid.rs b/shared-lib/flowy-grid-data-model/src/entities/grid.rs index c92a3b23a4..de15556008 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -64,12 +64,8 @@ pub struct FieldIdentifierPayload { pub grid_id: String, } -#[derive(Debug, Clone, Default, ProtoBuf)] pub struct FieldIdentifierParams { - #[pb(index = 1)] pub field_id: String, - - #[pb(index = 2)] pub grid_id: String, } @@ -92,12 +88,6 @@ pub struct FieldOrder { pub field_id: String, } -impl std::convert::Into> for FieldOrder { - fn into(self) -> Vec { - vec![self] - } -} - impl std::convert::From<&FieldMeta> for FieldOrder { fn from(field_meta: &FieldMeta) -> Self { Self { @@ -112,6 +102,12 @@ impl std::convert::From<&str> for FieldOrder { } } +impl std::convert::From for FieldOrder { + fn from(s: String) -> Self { + FieldOrder { field_id: s } + } +} + #[derive(Debug, Default, ProtoBuf)] pub struct GetEditFieldContextPayload { #[pb(index = 1)] @@ -211,6 +207,14 @@ impl std::convert::From> for RepeatedFieldOrder { } } +impl std::convert::From for RepeatedFieldOrder { + fn from(s: String) -> Self { + RepeatedFieldOrder { + items: vec![FieldOrder::from(s)], + } + } +} + #[derive(Debug, Default, Clone, ProtoBuf)] pub struct RowOrder { #[pb(index = 1)] @@ -327,6 +331,39 @@ impl Cell { } } +#[derive(Debug, Clone, Default, ProtoBuf)] +pub struct CellIdentifierPayload { + #[pb(index = 1)] + pub grid_id: String, + + #[pb(index = 2)] + pub field_id: String, + + #[pb(index = 3)] + pub row_id: String, +} + +pub struct CellIdentifierParams { + pub grid_id: String, + pub field_id: String, + pub row_id: String, +} + +impl TryInto for CellIdentifierPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; + let field_id = NotEmptyUuid::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?; + let row_id = NotEmptyUuid::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?; + Ok(CellIdentifierParams { + grid_id: grid_id.0, + field_id: field_id.0, + row_id: row_id.0, + }) + } +} + #[derive(Debug, Default, ProtoBuf)] pub struct RepeatedCell { #[pb(index = 1)] @@ -430,7 +467,6 @@ pub struct CreateFieldPayload { pub start_field_id: Option, } -#[derive(Default, Clone)] pub struct CreateFieldParams { pub grid_id: String, pub field: Field, @@ -468,7 +504,6 @@ pub struct QueryFieldPayload { pub field_orders: RepeatedFieldOrder, } -#[derive(Default)] pub struct QueryFieldParams { pub grid_id: String, pub field_orders: RepeatedFieldOrder, @@ -495,7 +530,6 @@ pub struct QueryGridBlocksPayload { pub block_orders: Vec, } -#[derive(Default)] pub struct QueryGridBlocksParams { pub grid_id: String, pub block_orders: Vec, @@ -518,17 +552,12 @@ pub struct QueryRowPayload { #[pb(index = 1)] pub grid_id: String, - #[pb(index = 2)] - pub block_id: String, - #[pb(index = 3)] pub row_id: String, } -#[derive(Default)] pub struct QueryRowParams { pub grid_id: String, - pub block_id: String, pub row_id: String, } @@ -537,12 +566,10 @@ impl TryInto for QueryRowPayload { fn try_into(self) -> Result { let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; - let block_id = NotEmptyUuid::parse(self.block_id).map_err(|_| ErrorCode::BlockIdIsEmpty)?; let row_id = NotEmptyUuid::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?; Ok(QueryRowParams { grid_id: grid_id.0, - block_id: block_id.0, row_id: row_id.0, }) } @@ -552,10 +579,14 @@ impl TryInto for QueryRowPayload { pub struct CreateSelectOptionPayload { #[pb(index = 1)] pub option_name: String, + + #[pb(index = 2)] + pub selected: bool, } pub struct CreateSelectOptionParams { pub option_name: String, + pub selected: bool, } impl TryInto for CreateSelectOptionPayload { @@ -565,6 +596,7 @@ impl TryInto for CreateSelectOptionPayload { let option_name = NotEmptyStr::parse(self.option_name).map_err(|_| ErrorCode::SelectOptionNameIsEmpty)?; Ok(CreateSelectOptionParams { option_name: option_name.0, + selected: self.selected, }) } } diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs index 7d13585c86..e80c31d8ad 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs @@ -860,207 +860,6 @@ impl ::protobuf::reflect::ProtobufValue for FieldIdentifierPayload { } } -#[derive(PartialEq,Clone,Default)] -pub struct FieldIdentifierParams { - // message fields - pub field_id: ::std::string::String, - pub grid_id: ::std::string::String, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a FieldIdentifierParams { - fn default() -> &'a FieldIdentifierParams { - ::default_instance() - } -} - -impl FieldIdentifierParams { - pub fn new() -> FieldIdentifierParams { - ::std::default::Default::default() - } - - // string field_id = 1; - - - pub fn get_field_id(&self) -> &str { - &self.field_id - } - pub fn clear_field_id(&mut self) { - self.field_id.clear(); - } - - // Param is passed by value, moved - pub fn set_field_id(&mut self, v: ::std::string::String) { - self.field_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_field_id(&mut self) -> &mut ::std::string::String { - &mut self.field_id - } - - // Take field - pub fn take_field_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) - } - - // string grid_id = 2; - - - pub fn get_grid_id(&self) -> &str { - &self.grid_id - } - pub fn clear_grid_id(&mut self) { - self.grid_id.clear(); - } - - // Param is passed by value, moved - pub fn set_grid_id(&mut self, v: ::std::string::String) { - self.grid_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_grid_id(&mut self) -> &mut ::std::string::String { - &mut self.grid_id - } - - // Take field - pub fn take_grid_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) - } -} - -impl ::protobuf::Message for FieldIdentifierParams { - 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.field_id)?; - }, - 2 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; - }, - _ => { - ::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.field_id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.field_id); - } - if !self.grid_id.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.grid_id); - } - 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.field_id.is_empty() { - os.write_string(1, &self.field_id)?; - } - if !self.grid_id.is_empty() { - os.write_string(2, &self.grid_id)?; - } - 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() -> FieldIdentifierParams { - FieldIdentifierParams::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>( - "field_id", - |m: &FieldIdentifierParams| { &m.field_id }, - |m: &mut FieldIdentifierParams| { &mut m.field_id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "grid_id", - |m: &FieldIdentifierParams| { &m.grid_id }, - |m: &mut FieldIdentifierParams| { &mut m.grid_id }, - )); - ::protobuf::reflect::MessageDescriptor::new_pb_name::( - "FieldIdentifierParams", - fields, - file_descriptor_proto() - ) - }) - } - - fn default_instance() -> &'static FieldIdentifierParams { - static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; - instance.get(FieldIdentifierParams::new) - } -} - -impl ::protobuf::Clear for FieldIdentifierParams { - fn clear(&mut self) { - self.field_id.clear(); - self.grid_id.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for FieldIdentifierParams { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for FieldIdentifierParams { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Message(self) - } -} - #[derive(PartialEq,Clone,Default)] pub struct FieldOrder { // message fields @@ -3681,6 +3480,249 @@ impl ::protobuf::reflect::ProtobufValue for Cell { } } +#[derive(PartialEq,Clone,Default)] +pub struct CellIdentifierPayload { + // message fields + pub grid_id: ::std::string::String, + pub field_id: ::std::string::String, + pub row_id: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a CellIdentifierPayload { + fn default() -> &'a CellIdentifierPayload { + ::default_instance() + } +} + +impl CellIdentifierPayload { + pub fn new() -> CellIdentifierPayload { + ::std::default::Default::default() + } + + // string grid_id = 1; + + + pub fn get_grid_id(&self) -> &str { + &self.grid_id + } + pub fn clear_grid_id(&mut self) { + self.grid_id.clear(); + } + + // Param is passed by value, moved + pub fn set_grid_id(&mut self, v: ::std::string::String) { + self.grid_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_grid_id(&mut self) -> &mut ::std::string::String { + &mut self.grid_id + } + + // Take field + pub fn take_grid_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) + } + + // string field_id = 2; + + + pub fn get_field_id(&self) -> &str { + &self.field_id + } + pub fn clear_field_id(&mut self) { + self.field_id.clear(); + } + + // Param is passed by value, moved + pub fn set_field_id(&mut self, v: ::std::string::String) { + self.field_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_field_id(&mut self) -> &mut ::std::string::String { + &mut self.field_id + } + + // Take field + pub fn take_field_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.field_id, ::std::string::String::new()) + } + + // string row_id = 3; + + + pub fn get_row_id(&self) -> &str { + &self.row_id + } + pub fn clear_row_id(&mut self) { + self.row_id.clear(); + } + + // Param is passed by value, moved + pub fn set_row_id(&mut self, v: ::std::string::String) { + self.row_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_row_id(&mut self) -> &mut ::std::string::String { + &mut self.row_id + } + + // Take field + pub fn take_row_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.row_id, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for CellIdentifierPayload { + 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.grid_id)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?; + }, + 3 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?; + }, + _ => { + ::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.grid_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.grid_id); + } + if !self.field_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.field_id); + } + if !self.row_id.is_empty() { + my_size += ::protobuf::rt::string_size(3, &self.row_id); + } + 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.grid_id.is_empty() { + os.write_string(1, &self.grid_id)?; + } + if !self.field_id.is_empty() { + os.write_string(2, &self.field_id)?; + } + if !self.row_id.is_empty() { + os.write_string(3, &self.row_id)?; + } + 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() -> CellIdentifierPayload { + CellIdentifierPayload::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>( + "grid_id", + |m: &CellIdentifierPayload| { &m.grid_id }, + |m: &mut CellIdentifierPayload| { &mut m.grid_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "field_id", + |m: &CellIdentifierPayload| { &m.field_id }, + |m: &mut CellIdentifierPayload| { &mut m.field_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "row_id", + |m: &CellIdentifierPayload| { &m.row_id }, + |m: &mut CellIdentifierPayload| { &mut m.row_id }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "CellIdentifierPayload", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static CellIdentifierPayload { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(CellIdentifierPayload::new) + } +} + +impl ::protobuf::Clear for CellIdentifierPayload { + fn clear(&mut self) { + self.grid_id.clear(); + self.field_id.clear(); + self.row_id.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for CellIdentifierPayload { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for CellIdentifierPayload { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(PartialEq,Clone,Default)] pub struct RepeatedCell { // message fields @@ -5333,7 +5375,6 @@ impl ::protobuf::reflect::ProtobufValue for QueryGridBlocksPayload { pub struct QueryRowPayload { // message fields pub grid_id: ::std::string::String, - pub block_id: ::std::string::String, pub row_id: ::std::string::String, // special fields pub unknown_fields: ::protobuf::UnknownFields, @@ -5377,32 +5418,6 @@ impl QueryRowPayload { ::std::mem::replace(&mut self.grid_id, ::std::string::String::new()) } - // string block_id = 2; - - - pub fn get_block_id(&self) -> &str { - &self.block_id - } - pub fn clear_block_id(&mut self) { - self.block_id.clear(); - } - - // Param is passed by value, moved - pub fn set_block_id(&mut self, v: ::std::string::String) { - self.block_id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_block_id(&mut self) -> &mut ::std::string::String { - &mut self.block_id - } - - // Take field - pub fn take_block_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.block_id, ::std::string::String::new()) - } - // string row_id = 3; @@ -5442,9 +5457,6 @@ impl ::protobuf::Message for QueryRowPayload { 1 => { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?; }, - 2 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?; - }, 3 => { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?; }, @@ -5463,9 +5475,6 @@ impl ::protobuf::Message for QueryRowPayload { if !self.grid_id.is_empty() { my_size += ::protobuf::rt::string_size(1, &self.grid_id); } - if !self.block_id.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.block_id); - } if !self.row_id.is_empty() { my_size += ::protobuf::rt::string_size(3, &self.row_id); } @@ -5478,9 +5487,6 @@ impl ::protobuf::Message for QueryRowPayload { if !self.grid_id.is_empty() { os.write_string(1, &self.grid_id)?; } - if !self.block_id.is_empty() { - os.write_string(2, &self.block_id)?; - } if !self.row_id.is_empty() { os.write_string(3, &self.row_id)?; } @@ -5527,11 +5533,6 @@ impl ::protobuf::Message for QueryRowPayload { |m: &QueryRowPayload| { &m.grid_id }, |m: &mut QueryRowPayload| { &mut m.grid_id }, )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "block_id", - |m: &QueryRowPayload| { &m.block_id }, - |m: &mut QueryRowPayload| { &mut m.block_id }, - )); fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( "row_id", |m: &QueryRowPayload| { &m.row_id }, @@ -5554,7 +5555,6 @@ impl ::protobuf::Message for QueryRowPayload { impl ::protobuf::Clear for QueryRowPayload { fn clear(&mut self) { self.grid_id.clear(); - self.block_id.clear(); self.row_id.clear(); self.unknown_fields.clear(); } @@ -5576,6 +5576,7 @@ impl ::protobuf::reflect::ProtobufValue for QueryRowPayload { pub struct CreateSelectOptionPayload { // message fields pub option_name: ::std::string::String, + pub selected: bool, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -5617,6 +5618,21 @@ impl CreateSelectOptionPayload { pub fn take_option_name(&mut self) -> ::std::string::String { ::std::mem::replace(&mut self.option_name, ::std::string::String::new()) } + + // bool selected = 2; + + + pub fn get_selected(&self) -> bool { + self.selected + } + pub fn clear_selected(&mut self) { + self.selected = false; + } + + // Param is passed by value, moved + pub fn set_selected(&mut self, v: bool) { + self.selected = v; + } } impl ::protobuf::Message for CreateSelectOptionPayload { @@ -5631,6 +5647,13 @@ impl ::protobuf::Message for CreateSelectOptionPayload { 1 => { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.option_name)?; }, + 2 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_bool()?; + self.selected = tmp; + }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; }, @@ -5646,6 +5669,9 @@ impl ::protobuf::Message for CreateSelectOptionPayload { if !self.option_name.is_empty() { my_size += ::protobuf::rt::string_size(1, &self.option_name); } + if self.selected != false { + my_size += 2; + } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); my_size @@ -5655,6 +5681,9 @@ impl ::protobuf::Message for CreateSelectOptionPayload { if !self.option_name.is_empty() { os.write_string(1, &self.option_name)?; } + if self.selected != false { + os.write_bool(2, self.selected)?; + } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) } @@ -5698,6 +5727,11 @@ impl ::protobuf::Message for CreateSelectOptionPayload { |m: &CreateSelectOptionPayload| { &m.option_name }, |m: &mut CreateSelectOptionPayload| { &mut m.option_name }, )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( + "selected", + |m: &CreateSelectOptionPayload| { &m.selected }, + |m: &mut CreateSelectOptionPayload| { &mut m.selected }, + )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "CreateSelectOptionPayload", fields, @@ -5715,6 +5749,7 @@ impl ::protobuf::Message for CreateSelectOptionPayload { impl ::protobuf::Clear for CreateSelectOptionPayload { fn clear(&mut self) { self.option_name.clear(); + self.selected = false; self.unknown_fields.clear(); } } @@ -5742,55 +5777,55 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x08R\x06frozen\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\ \x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05width\"L\n\x16FieldIdentifi\ erPayload\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x17\n\ - \x07grid_id\x18\x02\x20\x01(\tR\x06gridId\"K\n\x15FieldIdentifierParams\ - \x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x17\n\x07grid_\ - id\x18\x02\x20\x01(\tR\x06gridId\"'\n\nFieldOrder\x12\x19\n\x08field_id\ - \x18\x01\x20\x01(\tR\x07fieldId\"\x90\x01\n\x1aGetEditFieldContextPayloa\ - d\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x1b\n\x08field_\ - id\x18\x02\x20\x01(\tH\0R\x07fieldId\x12)\n\nfield_type\x18\x03\x20\x01(\ - \x0e2\n.FieldTypeR\tfieldTypeB\x11\n\x0fone_of_field_id\"q\n\x10EditFiel\ - dPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x19\n\ - \x08field_id\x18\x02\x20\x01(\tR\x07fieldId\x12)\n\nfield_type\x18\x03\ - \x20\x01(\x0e2\n.FieldTypeR\tfieldType\"|\n\x10EditFieldContext\x12\x17\ - \n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12%\n\ngrid_field\x18\x02\ - \x20\x01(\x0b2\x06.FieldR\tgridField\x12(\n\x10type_option_data\x18\x03\ - \x20\x01(\x0cR\x0etypeOptionData\"-\n\rRepeatedField\x12\x1c\n\x05items\ - \x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"7\n\x12RepeatedFieldOrder\ - \x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOrderR\x05items\"T\n\x08\ - RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\x12\x19\n\x08b\ - lock_id\x18\x02\x20\x01(\tR\x07blockId\x12\x16\n\x06height\x18\x03\x20\ - \x01(\x05R\x06height\"\xb8\x01\n\x03Row\x12\x0e\n\x02id\x18\x01\x20\x01(\ - \tR\x02id\x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\x0b2\x17.Row.CellB\ - yFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x03\x20\x01(\x05R\ - \x06height\x1aG\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01\ - (\tR\x03key\x12\x1b\n\x05value\x18\x02\x20\x01(\x0b2\x05.CellR\x05value:\ - \x028\x01\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\x01\x20\x03(\x0b2\ - \x04.RowR\x05items\"5\n\x11RepeatedGridBlock\x12\x20\n\x05items\x18\x01\ - \x20\x03(\x0b2\n.GridBlockR\x05items\"+\n\x0eGridBlockOrder\x12\x19\n\ - \x08block_id\x18\x01\x20\x01(\tR\x07blockId\"E\n\tGridBlock\x12\x0e\n\ - \x02id\x18\x01\x20\x01(\tR\x02id\x12(\n\nrow_orders\x18\x02\x20\x03(\x0b\ - 2\t.RowOrderR\trowOrders\";\n\x04Cell\x12\x19\n\x08field_id\x18\x01\x20\ - \x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x02\x20\x01(\tR\x07content\ - \"+\n\x0cRepeatedCell\x12\x1b\n\x05items\x18\x01\x20\x03(\x0b2\x05.CellR\ - \x05items\"'\n\x11CreateGridPayload\x12\x12\n\x04name\x18\x01\x20\x01(\t\ - R\x04name\"\x1e\n\x06GridId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05va\ - lue\"#\n\x0bGridBlockId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\ - \"f\n\x10CreateRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gr\ - idId\x12\"\n\x0cstart_row_id\x18\x02\x20\x01(\tH\0R\nstartRowIdB\x15\n\ - \x13one_of_start_row_id\"\xb6\x01\n\x12CreateFieldPayload\x12\x17\n\x07g\ - rid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x1c\n\x05field\x18\x02\x20\x01(\ - \x0b2\x06.FieldR\x05field\x12(\n\x10type_option_data\x18\x03\x20\x01(\ - \x0cR\x0etypeOptionData\x12&\n\x0estart_field_id\x18\x04\x20\x01(\tH\0R\ - \x0cstartFieldIdB\x17\n\x15one_of_start_field_id\"d\n\x11QueryFieldPaylo\ - ad\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_or\ - ders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"e\n\ - \x16QueryGridBlocksPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06g\ - ridId\x122\n\x0cblock_orders\x18\x02\x20\x03(\x0b2\x0f.GridBlockOrderR\ - \x0bblockOrders\"\\\n\x0fQueryRowPayload\x12\x17\n\x07grid_id\x18\x01\ - \x20\x01(\tR\x06gridId\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07bloc\ - kId\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowId\"<\n\x19CreateSelec\ - tOptionPayload\x12\x1f\n\x0boption_name\x18\x01\x20\x01(\tR\noptionNameb\ - \x06proto3\ + \x07grid_id\x18\x02\x20\x01(\tR\x06gridId\"'\n\nFieldOrder\x12\x19\n\x08\ + field_id\x18\x01\x20\x01(\tR\x07fieldId\"\x90\x01\n\x1aGetEditFieldConte\ + xtPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x1b\n\ + \x08field_id\x18\x02\x20\x01(\tH\0R\x07fieldId\x12)\n\nfield_type\x18\ + \x03\x20\x01(\x0e2\n.FieldTypeR\tfieldTypeB\x11\n\x0fone_of_field_id\"q\ + \n\x10EditFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridI\ + d\x12\x19\n\x08field_id\x18\x02\x20\x01(\tR\x07fieldId\x12)\n\nfield_typ\ + e\x18\x03\x20\x01(\x0e2\n.FieldTypeR\tfieldType\"|\n\x10EditFieldContext\ + \x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12%\n\ngrid_field\ + \x18\x02\x20\x01(\x0b2\x06.FieldR\tgridField\x12(\n\x10type_option_data\ + \x18\x03\x20\x01(\x0cR\x0etypeOptionData\"-\n\rRepeatedField\x12\x1c\n\ + \x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"7\n\x12RepeatedFiel\ + dOrder\x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOrderR\x05items\"T\ + \n\x08RowOrder\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\x05rowId\x12\x19\ + \n\x08block_id\x18\x02\x20\x01(\tR\x07blockId\x12\x16\n\x06height\x18\ + \x03\x20\x01(\x05R\x06height\"\xb8\x01\n\x03Row\x12\x0e\n\x02id\x18\x01\ + \x20\x01(\tR\x02id\x12@\n\x10cell_by_field_id\x18\x02\x20\x03(\x0b2\x17.\ + Row.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x03\x20\ + \x01(\x05R\x06height\x1aG\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\ + \x01\x20\x01(\tR\x03key\x12\x1b\n\x05value\x18\x02\x20\x01(\x0b2\x05.Cel\ + lR\x05value:\x028\x01\")\n\x0bRepeatedRow\x12\x1a\n\x05items\x18\x01\x20\ + \x03(\x0b2\x04.RowR\x05items\"5\n\x11RepeatedGridBlock\x12\x20\n\x05item\ + s\x18\x01\x20\x03(\x0b2\n.GridBlockR\x05items\"+\n\x0eGridBlockOrder\x12\ + \x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\"E\n\tGridBlock\x12\ + \x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12(\n\nrow_orders\x18\x02\x20\ + \x03(\x0b2\t.RowOrderR\trowOrders\";\n\x04Cell\x12\x19\n\x08field_id\x18\ + \x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x02\x20\x01(\tR\x07\ + content\"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\"+\n\x0cRepeatedCell\ + \x12\x1b\n\x05items\x18\x01\x20\x03(\x0b2\x05.CellR\x05items\"'\n\x11Cre\ + ateGridPayload\x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06\ + GridId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"#\n\x0bGridBlock\ + Id\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"f\n\x10CreateRowPayl\ + oad\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\"\n\x0cstart_\ + row_id\x18\x02\x20\x01(\tH\0R\nstartRowIdB\x15\n\x13one_of_start_row_id\ + \"\xb6\x01\n\x12CreateFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\ + \tR\x06gridId\x12\x1c\n\x05field\x18\x02\x20\x01(\x0b2\x06.FieldR\x05fie\ + ld\x12(\n\x10type_option_data\x18\x03\x20\x01(\x0cR\x0etypeOptionData\ + \x12&\n\x0estart_field_id\x18\x04\x20\x01(\tH\0R\x0cstartFieldIdB\x17\n\ + \x15one_of_start_field_id\"d\n\x11QueryFieldPayload\x12\x17\n\x07grid_id\ + \x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_orders\x18\x02\x20\x01(\ + \x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"e\n\x16QueryGridBlocksPayl\ + oad\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x122\n\x0cblock_o\ + rders\x18\x02\x20\x03(\x0b2\x0f.GridBlockOrderR\x0bblockOrders\"A\n\x0fQ\ + ueryRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\ + \x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowId\"X\n\x19CreateSelectOption\ + Payload\x12\x1f\n\x0boption_name\x18\x01\x20\x01(\tR\noptionName\x12\x1a\ + \n\x08selected\x18\x02\x20\x01(\x08R\x08selectedb\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto index 6e4a4f31cf..b3fcea8740 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto @@ -19,10 +19,6 @@ message FieldIdentifierPayload { string field_id = 1; string grid_id = 2; } -message FieldIdentifierParams { - string field_id = 1; - string grid_id = 2; -} message FieldOrder { string field_id = 1; } @@ -74,6 +70,11 @@ message Cell { string field_id = 1; string content = 2; } +message CellIdentifierPayload { + string grid_id = 1; + string field_id = 2; + string row_id = 3; +} message RepeatedCell { repeated Cell items = 1; } @@ -106,9 +107,9 @@ message QueryGridBlocksPayload { } message QueryRowPayload { string grid_id = 1; - string block_id = 2; string row_id = 3; } message CreateSelectOptionPayload { string option_name = 1; + bool selected = 2; } diff --git a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs index f022488f0a..2d2e9888f6 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs @@ -4,7 +4,6 @@ use crate::util::{cal_diff, make_delta_from_revisions}; use bytes::Bytes; use flowy_grid_data_model::entities::{ FieldChangesetParams, FieldMeta, FieldOrder, FieldType, GridBlockMeta, GridBlockMetaChangeset, GridMeta, - RepeatedFieldOrder, }; use lib_infra::uuid;