瀏覽代碼

refactor: add grid view info

appflowy 2 年之前
父節點
當前提交
820b7fcb75
共有 56 個文件被更改,包括 2673 次插入2506 次删除
  1. 1 2
      frontend/app_flowy/analysis_options.yaml
  2. 1 1
      frontend/app_flowy/lib/workspace/presentation/plugins/board/board.dart
  3. 1 0
      frontend/app_flowy/packages/flowy_sdk/analysis_options.yaml
  4. 0 17
      frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-folder/dart_event.dart
  5. 4 389
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view_info.pb.dart
  6. 2 66
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view_info.pbjson.dart
  7. 0 2
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder/event_map.pbenum.dart
  8. 1 2
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder/event_map.pbjson.dart
  9. 433 0
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid_info.pb.dart
  10. 7 0
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid_info.pbenum.dart
  11. 81 0
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid_info.pbjson.dart
  12. 9 0
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid_info.pbserver.dart
  13. 1 0
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/protobuf.dart
  14. 0 4
      frontend/rust-lib/flowy-folder/src/event_map.rs
  15. 1 6
      frontend/rust-lib/flowy-folder/src/manager.rs
  16. 6 10
      frontend/rust-lib/flowy-folder/src/protobuf/model/event_map.rs
  17. 0 1
      frontend/rust-lib/flowy-folder/src/protobuf/proto/event_map.proto
  18. 5 7
      frontend/rust-lib/flowy-folder/src/services/folder_editor.rs
  19. 2 8
      frontend/rust-lib/flowy-folder/src/services/view/controller.rs
  20. 1 12
      frontend/rust-lib/flowy-folder/src/services/view/event_handler.rs
  21. 2 1
      frontend/rust-lib/flowy-grid/src/manager.rs
  22. 1 1
      frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs
  23. 1 1
      frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs
  24. 1 1
      frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option/number_type_option.rs
  25. 2 2
      frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs
  26. 1 1
      frontend/rust-lib/flowy-grid/src/services/field/type_options/url_type_option.rs
  27. 1 4
      frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs
  28. 0 10
      frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs
  29. 1 90
      shared-lib/flowy-folder-data-model/src/entities/view_info.rs
  30. 0 1
      shared-lib/flowy-folder-data-model/src/parser/mod.rs
  31. 0 5
      shared-lib/flowy-folder-data-model/src/parser/view_info/mod.rs
  32. 0 19
      shared-lib/flowy-folder-data-model/src/parser/view_info/object_id.rs
  33. 0 40
      shared-lib/flowy-folder-data-model/src/parser/view_info/view_ext.rs
  34. 19 1321
      shared-lib/flowy-folder-data-model/src/protobuf/model/view_info.rs
  35. 1 22
      shared-lib/flowy-folder-data-model/src/protobuf/proto/view_info.proto
  36. 0 0
      shared-lib/flowy-folder-data-model/src/revision/app_rev.rs
  37. 8 8
      shared-lib/flowy-folder-data-model/src/revision/mod.rs
  38. 0 0
      shared-lib/flowy-folder-data-model/src/revision/trash_rev.rs
  39. 0 142
      shared-lib/flowy-folder-data-model/src/revision/view.rs
  40. 71 0
      shared-lib/flowy-folder-data-model/src/revision/view_rev.rs
  41. 0 0
      shared-lib/flowy-folder-data-model/src/revision/workspace_rev.rs
  42. 1 3
      shared-lib/flowy-grid-data-model/src/entities/field.rs
  43. 1 1
      shared-lib/flowy-grid-data-model/src/entities/grid.rs
  44. 91 0
      shared-lib/flowy-grid-data-model/src/entities/grid_info.rs
  45. 2 0
      shared-lib/flowy-grid-data-model/src/entities/mod.rs
  46. 58 0
      shared-lib/flowy-grid-data-model/src/parser/grid_info_parser.rs
  47. 2 0
      shared-lib/flowy-grid-data-model/src/parser/mod.rs
  48. 1444 0
      shared-lib/flowy-grid-data-model/src/protobuf/model/grid_info.rs
  49. 3 0
      shared-lib/flowy-grid-data-model/src/protobuf/model/mod.rs
  50. 23 0
      shared-lib/flowy-grid-data-model/src/protobuf/proto/grid_info.proto
  51. 66 0
      shared-lib/flowy-grid-data-model/src/revision/grid_info_rev.rs
  52. 310 0
      shared-lib/flowy-grid-data-model/src/revision/grid_rev.rs
  53. 4 295
      shared-lib/flowy-grid-data-model/src/revision/mod.rs
  54. 1 5
      shared-lib/flowy-grid-data-model/tests/serde_test.rs
  55. 1 0
      shared-lib/flowy-sync/src/client_grid/grid_builder.rs
  56. 1 6
      shared-lib/flowy-sync/src/client_grid/grid_revision_pad.rs

+ 1 - 2
frontend/app_flowy/analysis_options.yaml

@@ -17,7 +17,6 @@ analyzer:
     - "packages/flowy_editor/**"
     - "packages/editor/**"
     # - "packages/flowy_infra_ui/**"
-    
 linter:
   # The lint rules applied to this project can be customized in the
   # section below to disable rules from the `package:flutter_lints/flutter.yaml`
@@ -38,4 +37,4 @@ linter:
 # https://dart.dev/guides/language/analysis-options
 
 errors:
-  invalid_annotation_target: ignore
+  invalid_annotation_target: ignore

+ 1 - 1
frontend/app_flowy/lib/workspace/presentation/plugins/board/board.dart

@@ -28,7 +28,7 @@ class BoardPluginBuilder implements PluginBuilder {
 
 class BoardPluginConfig implements PluginConfig {
   @override
-  bool get creatable => true;
+  bool get creatable => false;
 }
 
 class BoardPlugin extends Plugin {

+ 1 - 0
frontend/app_flowy/packages/flowy_sdk/analysis_options.yaml

@@ -1,4 +1,5 @@
 analyzer:
   exclude:
     - "**/*.g.dart"
+    - "**/*.pb.dart"
     - "**/*.freezed.dart"

+ 0 - 17
frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-folder/dart_event.dart

@@ -287,23 +287,6 @@ class FolderEventReadViewInfo {
     }
 }
 
-class FolderEventUpdateViewInfo {
-     UpdateViewInfoPayload request;
-     FolderEventUpdateViewInfo(this.request);
-
-    Future<Either<ViewInfo, FlowyError>> send() {
-    final request = FFIRequest.create()
-          ..event = FolderEvent.UpdateViewInfo.toString()
-          ..payload = requestToBytes(this.request);
-
-    return Dispatch.asyncRequest(request)
-        .then((bytesResult) => bytesResult.fold(
-           (okBytes) => left(ViewInfo.fromBuffer(okBytes)),
-           (errBytes) => right(FlowyError.fromBuffer(errBytes)),
-        ));
-    }
-}
-
 class FolderEventCopyLink {
     FolderEventCopyLink();
 

+ 4 - 389
frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view_info.pb.dart

@@ -21,7 +21,7 @@ class ViewInfo extends $pb.GeneratedMessage {
     ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc')
     ..e<$0.ViewDataType>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dataType', $pb.PbFieldType.OE, defaultOrMaker: $0.ViewDataType.TextBlock, valueOf: $0.ViewDataType.valueOf, enumValues: $0.ViewDataType.values)
     ..aOM<$0.RepeatedView>(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'belongings', subBuilder: $0.RepeatedView.create)
-    ..aOM<ViewExtData>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'extData', subBuilder: ViewExtData.create)
+    ..aOS(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'extData')
     ..hasRequiredFields = false
   ;
 
@@ -33,7 +33,7 @@ class ViewInfo extends $pb.GeneratedMessage {
     $core.String? desc,
     $0.ViewDataType? dataType,
     $0.RepeatedView? belongings,
-    ViewExtData? extData,
+    $core.String? extData,
   }) {
     final _result = create();
     if (id != null) {
@@ -137,397 +137,12 @@ class ViewInfo extends $pb.GeneratedMessage {
   $0.RepeatedView ensureBelongings() => $_ensure(5);
 
   @$pb.TagNumber(7)
-  ViewExtData get extData => $_getN(6);
+  $core.String get extData => $_getSZ(6);
   @$pb.TagNumber(7)
-  set extData(ViewExtData v) { setField(7, v); }
+  set extData($core.String v) { $_setString(6, v); }
   @$pb.TagNumber(7)
   $core.bool hasExtData() => $_has(6);
   @$pb.TagNumber(7)
   void clearExtData() => clearField(7);
-  @$pb.TagNumber(7)
-  ViewExtData ensureExtData() => $_ensure(6);
-}
-
-class ViewExtData extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ViewExtData', createEmptyInstance: create)
-    ..aOM<ViewFilter>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'filter', subBuilder: ViewFilter.create)
-    ..aOM<ViewGroup>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'group', subBuilder: ViewGroup.create)
-    ..aOM<ViewSort>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'sort', subBuilder: ViewSort.create)
-    ..hasRequiredFields = false
-  ;
-
-  ViewExtData._() : super();
-  factory ViewExtData({
-    ViewFilter? filter,
-    ViewGroup? group,
-    ViewSort? sort,
-  }) {
-    final _result = create();
-    if (filter != null) {
-      _result.filter = filter;
-    }
-    if (group != null) {
-      _result.group = group;
-    }
-    if (sort != null) {
-      _result.sort = sort;
-    }
-    return _result;
-  }
-  factory ViewExtData.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
-  factory ViewExtData.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')
-  ViewExtData clone() => ViewExtData()..mergeFromMessage(this);
-  @$core.Deprecated(
-  'Using this can add significant overhead to your binary. '
-  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
-  'Will be removed in next major version')
-  ViewExtData copyWith(void Function(ViewExtData) updates) => super.copyWith((message) => updates(message as ViewExtData)) as ViewExtData; // ignore: deprecated_member_use
-  $pb.BuilderInfo get info_ => _i;
-  @$core.pragma('dart2js:noInline')
-  static ViewExtData create() => ViewExtData._();
-  ViewExtData createEmptyInstance() => create();
-  static $pb.PbList<ViewExtData> createRepeated() => $pb.PbList<ViewExtData>();
-  @$core.pragma('dart2js:noInline')
-  static ViewExtData getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ViewExtData>(create);
-  static ViewExtData? _defaultInstance;
-
-  @$pb.TagNumber(1)
-  ViewFilter get filter => $_getN(0);
-  @$pb.TagNumber(1)
-  set filter(ViewFilter v) { setField(1, v); }
-  @$pb.TagNumber(1)
-  $core.bool hasFilter() => $_has(0);
-  @$pb.TagNumber(1)
-  void clearFilter() => clearField(1);
-  @$pb.TagNumber(1)
-  ViewFilter ensureFilter() => $_ensure(0);
-
-  @$pb.TagNumber(2)
-  ViewGroup get group => $_getN(1);
-  @$pb.TagNumber(2)
-  set group(ViewGroup v) { setField(2, v); }
-  @$pb.TagNumber(2)
-  $core.bool hasGroup() => $_has(1);
-  @$pb.TagNumber(2)
-  void clearGroup() => clearField(2);
-  @$pb.TagNumber(2)
-  ViewGroup ensureGroup() => $_ensure(1);
-
-  @$pb.TagNumber(3)
-  ViewSort get sort => $_getN(2);
-  @$pb.TagNumber(3)
-  set sort(ViewSort v) { setField(3, v); }
-  @$pb.TagNumber(3)
-  $core.bool hasSort() => $_has(2);
-  @$pb.TagNumber(3)
-  void clearSort() => clearField(3);
-  @$pb.TagNumber(3)
-  ViewSort ensureSort() => $_ensure(2);
-}
-
-class ViewFilter extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ViewFilter', createEmptyInstance: create)
-    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'objectId')
-    ..hasRequiredFields = false
-  ;
-
-  ViewFilter._() : super();
-  factory ViewFilter({
-    $core.String? objectId,
-  }) {
-    final _result = create();
-    if (objectId != null) {
-      _result.objectId = objectId;
-    }
-    return _result;
-  }
-  factory ViewFilter.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
-  factory ViewFilter.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')
-  ViewFilter clone() => ViewFilter()..mergeFromMessage(this);
-  @$core.Deprecated(
-  'Using this can add significant overhead to your binary. '
-  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
-  'Will be removed in next major version')
-  ViewFilter copyWith(void Function(ViewFilter) updates) => super.copyWith((message) => updates(message as ViewFilter)) as ViewFilter; // ignore: deprecated_member_use
-  $pb.BuilderInfo get info_ => _i;
-  @$core.pragma('dart2js:noInline')
-  static ViewFilter create() => ViewFilter._();
-  ViewFilter createEmptyInstance() => create();
-  static $pb.PbList<ViewFilter> createRepeated() => $pb.PbList<ViewFilter>();
-  @$core.pragma('dart2js:noInline')
-  static ViewFilter getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ViewFilter>(create);
-  static ViewFilter? _defaultInstance;
-
-  @$pb.TagNumber(1)
-  $core.String get objectId => $_getSZ(0);
-  @$pb.TagNumber(1)
-  set objectId($core.String v) { $_setString(0, v); }
-  @$pb.TagNumber(1)
-  $core.bool hasObjectId() => $_has(0);
-  @$pb.TagNumber(1)
-  void clearObjectId() => clearField(1);
-}
-
-enum ViewGroup_OneOfSubGroupObjectId {
-  subGroupObjectId, 
-  notSet
-}
-
-class ViewGroup extends $pb.GeneratedMessage {
-  static const $core.Map<$core.int, ViewGroup_OneOfSubGroupObjectId> _ViewGroup_OneOfSubGroupObjectIdByTag = {
-    2 : ViewGroup_OneOfSubGroupObjectId.subGroupObjectId,
-    0 : ViewGroup_OneOfSubGroupObjectId.notSet
-  };
-  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ViewGroup', createEmptyInstance: create)
-    ..oo(0, [2])
-    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'groupObjectId')
-    ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'subGroupObjectId')
-    ..hasRequiredFields = false
-  ;
-
-  ViewGroup._() : super();
-  factory ViewGroup({
-    $core.String? groupObjectId,
-    $core.String? subGroupObjectId,
-  }) {
-    final _result = create();
-    if (groupObjectId != null) {
-      _result.groupObjectId = groupObjectId;
-    }
-    if (subGroupObjectId != null) {
-      _result.subGroupObjectId = subGroupObjectId;
-    }
-    return _result;
-  }
-  factory ViewGroup.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
-  factory ViewGroup.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')
-  ViewGroup clone() => ViewGroup()..mergeFromMessage(this);
-  @$core.Deprecated(
-  'Using this can add significant overhead to your binary. '
-  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
-  'Will be removed in next major version')
-  ViewGroup copyWith(void Function(ViewGroup) updates) => super.copyWith((message) => updates(message as ViewGroup)) as ViewGroup; // ignore: deprecated_member_use
-  $pb.BuilderInfo get info_ => _i;
-  @$core.pragma('dart2js:noInline')
-  static ViewGroup create() => ViewGroup._();
-  ViewGroup createEmptyInstance() => create();
-  static $pb.PbList<ViewGroup> createRepeated() => $pb.PbList<ViewGroup>();
-  @$core.pragma('dart2js:noInline')
-  static ViewGroup getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ViewGroup>(create);
-  static ViewGroup? _defaultInstance;
-
-  ViewGroup_OneOfSubGroupObjectId whichOneOfSubGroupObjectId() => _ViewGroup_OneOfSubGroupObjectIdByTag[$_whichOneof(0)]!;
-  void clearOneOfSubGroupObjectId() => clearField($_whichOneof(0));
-
-  @$pb.TagNumber(1)
-  $core.String get groupObjectId => $_getSZ(0);
-  @$pb.TagNumber(1)
-  set groupObjectId($core.String v) { $_setString(0, v); }
-  @$pb.TagNumber(1)
-  $core.bool hasGroupObjectId() => $_has(0);
-  @$pb.TagNumber(1)
-  void clearGroupObjectId() => clearField(1);
-
-  @$pb.TagNumber(2)
-  $core.String get subGroupObjectId => $_getSZ(1);
-  @$pb.TagNumber(2)
-  set subGroupObjectId($core.String v) { $_setString(1, v); }
-  @$pb.TagNumber(2)
-  $core.bool hasSubGroupObjectId() => $_has(1);
-  @$pb.TagNumber(2)
-  void clearSubGroupObjectId() => clearField(2);
-}
-
-class ViewSort extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ViewSort', createEmptyInstance: create)
-    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'objectId')
-    ..hasRequiredFields = false
-  ;
-
-  ViewSort._() : super();
-  factory ViewSort({
-    $core.String? objectId,
-  }) {
-    final _result = create();
-    if (objectId != null) {
-      _result.objectId = objectId;
-    }
-    return _result;
-  }
-  factory ViewSort.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
-  factory ViewSort.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')
-  ViewSort clone() => ViewSort()..mergeFromMessage(this);
-  @$core.Deprecated(
-  'Using this can add significant overhead to your binary. '
-  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
-  'Will be removed in next major version')
-  ViewSort copyWith(void Function(ViewSort) updates) => super.copyWith((message) => updates(message as ViewSort)) as ViewSort; // ignore: deprecated_member_use
-  $pb.BuilderInfo get info_ => _i;
-  @$core.pragma('dart2js:noInline')
-  static ViewSort create() => ViewSort._();
-  ViewSort createEmptyInstance() => create();
-  static $pb.PbList<ViewSort> createRepeated() => $pb.PbList<ViewSort>();
-  @$core.pragma('dart2js:noInline')
-  static ViewSort getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ViewSort>(create);
-  static ViewSort? _defaultInstance;
-
-  @$pb.TagNumber(1)
-  $core.String get objectId => $_getSZ(0);
-  @$pb.TagNumber(1)
-  set objectId($core.String v) { $_setString(0, v); }
-  @$pb.TagNumber(1)
-  $core.bool hasObjectId() => $_has(0);
-  @$pb.TagNumber(1)
-  void clearObjectId() => clearField(1);
-}
-
-enum UpdateViewInfoPayload_OneOfFilter {
-  filter, 
-  notSet
-}
-
-enum UpdateViewInfoPayload_OneOfGroup {
-  group, 
-  notSet
-}
-
-enum UpdateViewInfoPayload_OneOfSort {
-  sort, 
-  notSet
-}
-
-class UpdateViewInfoPayload extends $pb.GeneratedMessage {
-  static const $core.Map<$core.int, UpdateViewInfoPayload_OneOfFilter> _UpdateViewInfoPayload_OneOfFilterByTag = {
-    2 : UpdateViewInfoPayload_OneOfFilter.filter,
-    0 : UpdateViewInfoPayload_OneOfFilter.notSet
-  };
-  static const $core.Map<$core.int, UpdateViewInfoPayload_OneOfGroup> _UpdateViewInfoPayload_OneOfGroupByTag = {
-    3 : UpdateViewInfoPayload_OneOfGroup.group,
-    0 : UpdateViewInfoPayload_OneOfGroup.notSet
-  };
-  static const $core.Map<$core.int, UpdateViewInfoPayload_OneOfSort> _UpdateViewInfoPayload_OneOfSortByTag = {
-    4 : UpdateViewInfoPayload_OneOfSort.sort,
-    0 : UpdateViewInfoPayload_OneOfSort.notSet
-  };
-  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'UpdateViewInfoPayload', createEmptyInstance: create)
-    ..oo(0, [2])
-    ..oo(1, [3])
-    ..oo(2, [4])
-    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'viewId')
-    ..aOM<ViewFilter>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'filter', subBuilder: ViewFilter.create)
-    ..aOM<ViewGroup>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'group', subBuilder: ViewGroup.create)
-    ..aOM<ViewSort>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'sort', subBuilder: ViewSort.create)
-    ..hasRequiredFields = false
-  ;
-
-  UpdateViewInfoPayload._() : super();
-  factory UpdateViewInfoPayload({
-    $core.String? viewId,
-    ViewFilter? filter,
-    ViewGroup? group,
-    ViewSort? sort,
-  }) {
-    final _result = create();
-    if (viewId != null) {
-      _result.viewId = viewId;
-    }
-    if (filter != null) {
-      _result.filter = filter;
-    }
-    if (group != null) {
-      _result.group = group;
-    }
-    if (sort != null) {
-      _result.sort = sort;
-    }
-    return _result;
-  }
-  factory UpdateViewInfoPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
-  factory UpdateViewInfoPayload.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')
-  UpdateViewInfoPayload clone() => UpdateViewInfoPayload()..mergeFromMessage(this);
-  @$core.Deprecated(
-  'Using this can add significant overhead to your binary. '
-  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
-  'Will be removed in next major version')
-  UpdateViewInfoPayload copyWith(void Function(UpdateViewInfoPayload) updates) => super.copyWith((message) => updates(message as UpdateViewInfoPayload)) as UpdateViewInfoPayload; // ignore: deprecated_member_use
-  $pb.BuilderInfo get info_ => _i;
-  @$core.pragma('dart2js:noInline')
-  static UpdateViewInfoPayload create() => UpdateViewInfoPayload._();
-  UpdateViewInfoPayload createEmptyInstance() => create();
-  static $pb.PbList<UpdateViewInfoPayload> createRepeated() => $pb.PbList<UpdateViewInfoPayload>();
-  @$core.pragma('dart2js:noInline')
-  static UpdateViewInfoPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<UpdateViewInfoPayload>(create);
-  static UpdateViewInfoPayload? _defaultInstance;
-
-  UpdateViewInfoPayload_OneOfFilter whichOneOfFilter() => _UpdateViewInfoPayload_OneOfFilterByTag[$_whichOneof(0)]!;
-  void clearOneOfFilter() => clearField($_whichOneof(0));
-
-  UpdateViewInfoPayload_OneOfGroup whichOneOfGroup() => _UpdateViewInfoPayload_OneOfGroupByTag[$_whichOneof(1)]!;
-  void clearOneOfGroup() => clearField($_whichOneof(1));
-
-  UpdateViewInfoPayload_OneOfSort whichOneOfSort() => _UpdateViewInfoPayload_OneOfSortByTag[$_whichOneof(2)]!;
-  void clearOneOfSort() => clearField($_whichOneof(2));
-
-  @$pb.TagNumber(1)
-  $core.String get viewId => $_getSZ(0);
-  @$pb.TagNumber(1)
-  set viewId($core.String v) { $_setString(0, v); }
-  @$pb.TagNumber(1)
-  $core.bool hasViewId() => $_has(0);
-  @$pb.TagNumber(1)
-  void clearViewId() => clearField(1);
-
-  @$pb.TagNumber(2)
-  ViewFilter get filter => $_getN(1);
-  @$pb.TagNumber(2)
-  set filter(ViewFilter v) { setField(2, v); }
-  @$pb.TagNumber(2)
-  $core.bool hasFilter() => $_has(1);
-  @$pb.TagNumber(2)
-  void clearFilter() => clearField(2);
-  @$pb.TagNumber(2)
-  ViewFilter ensureFilter() => $_ensure(1);
-
-  @$pb.TagNumber(3)
-  ViewGroup get group => $_getN(2);
-  @$pb.TagNumber(3)
-  set group(ViewGroup v) { setField(3, v); }
-  @$pb.TagNumber(3)
-  $core.bool hasGroup() => $_has(2);
-  @$pb.TagNumber(3)
-  void clearGroup() => clearField(3);
-  @$pb.TagNumber(3)
-  ViewGroup ensureGroup() => $_ensure(2);
-
-  @$pb.TagNumber(4)
-  ViewSort get sort => $_getN(3);
-  @$pb.TagNumber(4)
-  set sort(ViewSort v) { setField(4, v); }
-  @$pb.TagNumber(4)
-  $core.bool hasSort() => $_has(3);
-  @$pb.TagNumber(4)
-  void clearSort() => clearField(4);
-  @$pb.TagNumber(4)
-  ViewSort ensureSort() => $_ensure(3);
 }
 

+ 2 - 66
frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view_info.pbjson.dart

@@ -18,73 +18,9 @@ const ViewInfo$json = const {
     const {'1': 'desc', '3': 4, '4': 1, '5': 9, '10': 'desc'},
     const {'1': 'data_type', '3': 5, '4': 1, '5': 14, '6': '.ViewDataType', '10': 'dataType'},
     const {'1': 'belongings', '3': 6, '4': 1, '5': 11, '6': '.RepeatedView', '10': 'belongings'},
-    const {'1': 'ext_data', '3': 7, '4': 1, '5': 11, '6': '.ViewExtData', '10': 'extData'},
+    const {'1': 'ext_data', '3': 7, '4': 1, '5': 9, '10': 'extData'},
   ],
 };
 
 /// Descriptor for `ViewInfo`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List viewInfoDescriptor = $convert.base64Decode('CghWaWV3SW5mbxIOCgJpZBgBIAEoCVICaWQSIAoMYmVsb25nX3RvX2lkGAIgASgJUgpiZWxvbmdUb0lkEhIKBG5hbWUYAyABKAlSBG5hbWUSEgoEZGVzYxgEIAEoCVIEZGVzYxIqCglkYXRhX3R5cGUYBSABKA4yDS5WaWV3RGF0YVR5cGVSCGRhdGFUeXBlEi0KCmJlbG9uZ2luZ3MYBiABKAsyDS5SZXBlYXRlZFZpZXdSCmJlbG9uZ2luZ3MSJwoIZXh0X2RhdGEYByABKAsyDC5WaWV3RXh0RGF0YVIHZXh0RGF0YQ==');
-@$core.Deprecated('Use viewExtDataDescriptor instead')
-const ViewExtData$json = const {
-  '1': 'ViewExtData',
-  '2': const [
-    const {'1': 'filter', '3': 1, '4': 1, '5': 11, '6': '.ViewFilter', '10': 'filter'},
-    const {'1': 'group', '3': 2, '4': 1, '5': 11, '6': '.ViewGroup', '10': 'group'},
-    const {'1': 'sort', '3': 3, '4': 1, '5': 11, '6': '.ViewSort', '10': 'sort'},
-  ],
-};
-
-/// Descriptor for `ViewExtData`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List viewExtDataDescriptor = $convert.base64Decode('CgtWaWV3RXh0RGF0YRIjCgZmaWx0ZXIYASABKAsyCy5WaWV3RmlsdGVyUgZmaWx0ZXISIAoFZ3JvdXAYAiABKAsyCi5WaWV3R3JvdXBSBWdyb3VwEh0KBHNvcnQYAyABKAsyCS5WaWV3U29ydFIEc29ydA==');
-@$core.Deprecated('Use viewFilterDescriptor instead')
-const ViewFilter$json = const {
-  '1': 'ViewFilter',
-  '2': const [
-    const {'1': 'object_id', '3': 1, '4': 1, '5': 9, '10': 'objectId'},
-  ],
-};
-
-/// Descriptor for `ViewFilter`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List viewFilterDescriptor = $convert.base64Decode('CgpWaWV3RmlsdGVyEhsKCW9iamVjdF9pZBgBIAEoCVIIb2JqZWN0SWQ=');
-@$core.Deprecated('Use viewGroupDescriptor instead')
-const ViewGroup$json = const {
-  '1': 'ViewGroup',
-  '2': const [
-    const {'1': 'group_object_id', '3': 1, '4': 1, '5': 9, '10': 'groupObjectId'},
-    const {'1': 'sub_group_object_id', '3': 2, '4': 1, '5': 9, '9': 0, '10': 'subGroupObjectId'},
-  ],
-  '8': const [
-    const {'1': 'one_of_sub_group_object_id'},
-  ],
-};
-
-/// Descriptor for `ViewGroup`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List viewGroupDescriptor = $convert.base64Decode('CglWaWV3R3JvdXASJgoPZ3JvdXBfb2JqZWN0X2lkGAEgASgJUg1ncm91cE9iamVjdElkEi8KE3N1Yl9ncm91cF9vYmplY3RfaWQYAiABKAlIAFIQc3ViR3JvdXBPYmplY3RJZEIcChpvbmVfb2Zfc3ViX2dyb3VwX29iamVjdF9pZA==');
-@$core.Deprecated('Use viewSortDescriptor instead')
-const ViewSort$json = const {
-  '1': 'ViewSort',
-  '2': const [
-    const {'1': 'object_id', '3': 1, '4': 1, '5': 9, '10': 'objectId'},
-  ],
-};
-
-/// Descriptor for `ViewSort`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List viewSortDescriptor = $convert.base64Decode('CghWaWV3U29ydBIbCglvYmplY3RfaWQYASABKAlSCG9iamVjdElk');
-@$core.Deprecated('Use updateViewInfoPayloadDescriptor instead')
-const UpdateViewInfoPayload$json = const {
-  '1': 'UpdateViewInfoPayload',
-  '2': const [
-    const {'1': 'view_id', '3': 1, '4': 1, '5': 9, '10': 'viewId'},
-    const {'1': 'filter', '3': 2, '4': 1, '5': 11, '6': '.ViewFilter', '9': 0, '10': 'filter'},
-    const {'1': 'group', '3': 3, '4': 1, '5': 11, '6': '.ViewGroup', '9': 1, '10': 'group'},
-    const {'1': 'sort', '3': 4, '4': 1, '5': 11, '6': '.ViewSort', '9': 2, '10': 'sort'},
-  ],
-  '8': const [
-    const {'1': 'one_of_filter'},
-    const {'1': 'one_of_group'},
-    const {'1': 'one_of_sort'},
-  ],
-};
-
-/// Descriptor for `UpdateViewInfoPayload`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List updateViewInfoPayloadDescriptor = $convert.base64Decode('ChVVcGRhdGVWaWV3SW5mb1BheWxvYWQSFwoHdmlld19pZBgBIAEoCVIGdmlld0lkEiUKBmZpbHRlchgCIAEoCzILLlZpZXdGaWx0ZXJIAFIGZmlsdGVyEiIKBWdyb3VwGAMgASgLMgouVmlld0dyb3VwSAFSBWdyb3VwEh8KBHNvcnQYBCABKAsyCS5WaWV3U29ydEgCUgRzb3J0Qg8KDW9uZV9vZl9maWx0ZXJCDgoMb25lX29mX2dyb3VwQg0KC29uZV9vZl9zb3J0');
+final $typed_data.Uint8List viewInfoDescriptor = $convert.base64Decode('CghWaWV3SW5mbxIOCgJpZBgBIAEoCVICaWQSIAoMYmVsb25nX3RvX2lkGAIgASgJUgpiZWxvbmdUb0lkEhIKBG5hbWUYAyABKAlSBG5hbWUSEgoEZGVzYxgEIAEoCVIEZGVzYxIqCglkYXRhX3R5cGUYBSABKA4yDS5WaWV3RGF0YVR5cGVSCGRhdGFUeXBlEi0KCmJlbG9uZ2luZ3MYBiABKAsyDS5SZXBlYXRlZFZpZXdSCmJlbG9uZ2luZ3MSGQoIZXh0X2RhdGEYByABKAlSB2V4dERhdGE=');

+ 0 - 2
frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder/event_map.pbenum.dart

@@ -27,7 +27,6 @@ class FolderEvent extends $pb.ProtobufEnum {
   static const FolderEvent DuplicateView = FolderEvent._(205, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DuplicateView');
   static const FolderEvent CloseView = FolderEvent._(206, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CloseView');
   static const FolderEvent ReadViewInfo = FolderEvent._(207, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ReadViewInfo');
-  static const FolderEvent UpdateViewInfo = FolderEvent._(208, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateViewInfo');
   static const FolderEvent CopyLink = FolderEvent._(220, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CopyLink');
   static const FolderEvent SetLatestView = FolderEvent._(221, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'SetLatestView');
   static const FolderEvent MoveFolderItem = FolderEvent._(230, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'MoveFolderItem');
@@ -55,7 +54,6 @@ class FolderEvent extends $pb.ProtobufEnum {
     DuplicateView,
     CloseView,
     ReadViewInfo,
-    UpdateViewInfo,
     CopyLink,
     SetLatestView,
     MoveFolderItem,

+ 1 - 2
frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder/event_map.pbjson.dart

@@ -29,7 +29,6 @@ const FolderEvent$json = const {
     const {'1': 'DuplicateView', '2': 205},
     const {'1': 'CloseView', '2': 206},
     const {'1': 'ReadViewInfo', '2': 207},
-    const {'1': 'UpdateViewInfo', '2': 208},
     const {'1': 'CopyLink', '2': 220},
     const {'1': 'SetLatestView', '2': 221},
     const {'1': 'MoveFolderItem', '2': 230},
@@ -42,4 +41,4 @@ const FolderEvent$json = const {
 };
 
 /// Descriptor for `FolderEvent`. Decode as a `google.protobuf.EnumDescriptorProto`.
-final $typed_data.Uint8List folderEventDescriptor = $convert.base64Decode('CgtGb2xkZXJFdmVudBITCg9DcmVhdGVXb3Jrc3BhY2UQABIUChBSZWFkQ3VyV29ya3NwYWNlEAESEgoOUmVhZFdvcmtzcGFjZXMQAhITCg9EZWxldGVXb3Jrc3BhY2UQAxIRCg1PcGVuV29ya3NwYWNlEAQSFQoRUmVhZFdvcmtzcGFjZUFwcHMQBRINCglDcmVhdGVBcHAQZRINCglEZWxldGVBcHAQZhILCgdSZWFkQXBwEGcSDQoJVXBkYXRlQXBwEGgSDwoKQ3JlYXRlVmlldxDJARINCghSZWFkVmlldxDKARIPCgpVcGRhdGVWaWV3EMsBEg8KCkRlbGV0ZVZpZXcQzAESEgoNRHVwbGljYXRlVmlldxDNARIOCglDbG9zZVZpZXcQzgESEQoMUmVhZFZpZXdJbmZvEM8BEhMKDlVwZGF0ZVZpZXdJbmZvENABEg0KCENvcHlMaW5rENwBEhIKDVNldExhdGVzdFZpZXcQ3QESEwoOTW92ZUZvbGRlckl0ZW0Q5gESDgoJUmVhZFRyYXNoEKwCEhEKDFB1dGJhY2tUcmFzaBCtAhIQCgtEZWxldGVUcmFzaBCuAhIUCg9SZXN0b3JlQWxsVHJhc2gQrwISEwoORGVsZXRlQWxsVHJhc2gQsAI=');
+final $typed_data.Uint8List folderEventDescriptor = $convert.base64Decode('CgtGb2xkZXJFdmVudBITCg9DcmVhdGVXb3Jrc3BhY2UQABIUChBSZWFkQ3VyV29ya3NwYWNlEAESEgoOUmVhZFdvcmtzcGFjZXMQAhITCg9EZWxldGVXb3Jrc3BhY2UQAxIRCg1PcGVuV29ya3NwYWNlEAQSFQoRUmVhZFdvcmtzcGFjZUFwcHMQBRINCglDcmVhdGVBcHAQZRINCglEZWxldGVBcHAQZhILCgdSZWFkQXBwEGcSDQoJVXBkYXRlQXBwEGgSDwoKQ3JlYXRlVmlldxDJARINCghSZWFkVmlldxDKARIPCgpVcGRhdGVWaWV3EMsBEg8KCkRlbGV0ZVZpZXcQzAESEgoNRHVwbGljYXRlVmlldxDNARIOCglDbG9zZVZpZXcQzgESEQoMUmVhZFZpZXdJbmZvEM8BEg0KCENvcHlMaW5rENwBEhIKDVNldExhdGVzdFZpZXcQ3QESEwoOTW92ZUZvbGRlckl0ZW0Q5gESDgoJUmVhZFRyYXNoEKwCEhEKDFB1dGJhY2tUcmFzaBCtAhIQCgtEZWxldGVUcmFzaBCuAhIUCg9SZXN0b3JlQWxsVHJhc2gQrwISEwoORGVsZXRlQWxsVHJhc2gQsAI=');

+ 433 - 0
frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid_info.pb.dart

@@ -0,0 +1,433 @@
+///
+//  Generated code. Do not modify.
+//  source: grid_info.proto
+//
+// @dart = 2.12
+// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields
+
+import 'dart:core' as $core;
+
+import 'package:protobuf/protobuf.dart' as $pb;
+
+class ViewExtData extends $pb.GeneratedMessage {
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ViewExtData', createEmptyInstance: create)
+    ..aOM<ViewFilter>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'filter', subBuilder: ViewFilter.create)
+    ..aOM<ViewGroup>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'group', subBuilder: ViewGroup.create)
+    ..aOM<ViewSort>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'sort', subBuilder: ViewSort.create)
+    ..hasRequiredFields = false
+  ;
+
+  ViewExtData._() : super();
+  factory ViewExtData({
+    ViewFilter? filter,
+    ViewGroup? group,
+    ViewSort? sort,
+  }) {
+    final _result = create();
+    if (filter != null) {
+      _result.filter = filter;
+    }
+    if (group != null) {
+      _result.group = group;
+    }
+    if (sort != null) {
+      _result.sort = sort;
+    }
+    return _result;
+  }
+  factory ViewExtData.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory ViewExtData.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')
+  ViewExtData clone() => ViewExtData()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  ViewExtData copyWith(void Function(ViewExtData) updates) => super.copyWith((message) => updates(message as ViewExtData)) as ViewExtData; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static ViewExtData create() => ViewExtData._();
+  ViewExtData createEmptyInstance() => create();
+  static $pb.PbList<ViewExtData> createRepeated() => $pb.PbList<ViewExtData>();
+  @$core.pragma('dart2js:noInline')
+  static ViewExtData getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ViewExtData>(create);
+  static ViewExtData? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  ViewFilter get filter => $_getN(0);
+  @$pb.TagNumber(1)
+  set filter(ViewFilter v) { setField(1, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasFilter() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearFilter() => clearField(1);
+  @$pb.TagNumber(1)
+  ViewFilter ensureFilter() => $_ensure(0);
+
+  @$pb.TagNumber(2)
+  ViewGroup get group => $_getN(1);
+  @$pb.TagNumber(2)
+  set group(ViewGroup v) { setField(2, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasGroup() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearGroup() => clearField(2);
+  @$pb.TagNumber(2)
+  ViewGroup ensureGroup() => $_ensure(1);
+
+  @$pb.TagNumber(3)
+  ViewSort get sort => $_getN(2);
+  @$pb.TagNumber(3)
+  set sort(ViewSort v) { setField(3, v); }
+  @$pb.TagNumber(3)
+  $core.bool hasSort() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearSort() => clearField(3);
+  @$pb.TagNumber(3)
+  ViewSort ensureSort() => $_ensure(2);
+}
+
+enum ViewFilter_OneOfFieldId {
+  fieldId, 
+  notSet
+}
+
+class ViewFilter extends $pb.GeneratedMessage {
+  static const $core.Map<$core.int, ViewFilter_OneOfFieldId> _ViewFilter_OneOfFieldIdByTag = {
+    1 : ViewFilter_OneOfFieldId.fieldId,
+    0 : ViewFilter_OneOfFieldId.notSet
+  };
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ViewFilter', createEmptyInstance: create)
+    ..oo(0, [1])
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId')
+    ..hasRequiredFields = false
+  ;
+
+  ViewFilter._() : super();
+  factory ViewFilter({
+    $core.String? fieldId,
+  }) {
+    final _result = create();
+    if (fieldId != null) {
+      _result.fieldId = fieldId;
+    }
+    return _result;
+  }
+  factory ViewFilter.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory ViewFilter.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')
+  ViewFilter clone() => ViewFilter()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  ViewFilter copyWith(void Function(ViewFilter) updates) => super.copyWith((message) => updates(message as ViewFilter)) as ViewFilter; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static ViewFilter create() => ViewFilter._();
+  ViewFilter createEmptyInstance() => create();
+  static $pb.PbList<ViewFilter> createRepeated() => $pb.PbList<ViewFilter>();
+  @$core.pragma('dart2js:noInline')
+  static ViewFilter getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ViewFilter>(create);
+  static ViewFilter? _defaultInstance;
+
+  ViewFilter_OneOfFieldId whichOneOfFieldId() => _ViewFilter_OneOfFieldIdByTag[$_whichOneof(0)]!;
+  void clearOneOfFieldId() => clearField($_whichOneof(0));
+
+  @$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);
+}
+
+enum ViewGroup_OneOfGroupFieldId {
+  groupFieldId, 
+  notSet
+}
+
+enum ViewGroup_OneOfSubGroupFieldId {
+  subGroupFieldId, 
+  notSet
+}
+
+class ViewGroup extends $pb.GeneratedMessage {
+  static const $core.Map<$core.int, ViewGroup_OneOfGroupFieldId> _ViewGroup_OneOfGroupFieldIdByTag = {
+    1 : ViewGroup_OneOfGroupFieldId.groupFieldId,
+    0 : ViewGroup_OneOfGroupFieldId.notSet
+  };
+  static const $core.Map<$core.int, ViewGroup_OneOfSubGroupFieldId> _ViewGroup_OneOfSubGroupFieldIdByTag = {
+    2 : ViewGroup_OneOfSubGroupFieldId.subGroupFieldId,
+    0 : ViewGroup_OneOfSubGroupFieldId.notSet
+  };
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ViewGroup', createEmptyInstance: create)
+    ..oo(0, [1])
+    ..oo(1, [2])
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'groupFieldId')
+    ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'subGroupFieldId')
+    ..hasRequiredFields = false
+  ;
+
+  ViewGroup._() : super();
+  factory ViewGroup({
+    $core.String? groupFieldId,
+    $core.String? subGroupFieldId,
+  }) {
+    final _result = create();
+    if (groupFieldId != null) {
+      _result.groupFieldId = groupFieldId;
+    }
+    if (subGroupFieldId != null) {
+      _result.subGroupFieldId = subGroupFieldId;
+    }
+    return _result;
+  }
+  factory ViewGroup.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory ViewGroup.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')
+  ViewGroup clone() => ViewGroup()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  ViewGroup copyWith(void Function(ViewGroup) updates) => super.copyWith((message) => updates(message as ViewGroup)) as ViewGroup; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static ViewGroup create() => ViewGroup._();
+  ViewGroup createEmptyInstance() => create();
+  static $pb.PbList<ViewGroup> createRepeated() => $pb.PbList<ViewGroup>();
+  @$core.pragma('dart2js:noInline')
+  static ViewGroup getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ViewGroup>(create);
+  static ViewGroup? _defaultInstance;
+
+  ViewGroup_OneOfGroupFieldId whichOneOfGroupFieldId() => _ViewGroup_OneOfGroupFieldIdByTag[$_whichOneof(0)]!;
+  void clearOneOfGroupFieldId() => clearField($_whichOneof(0));
+
+  ViewGroup_OneOfSubGroupFieldId whichOneOfSubGroupFieldId() => _ViewGroup_OneOfSubGroupFieldIdByTag[$_whichOneof(1)]!;
+  void clearOneOfSubGroupFieldId() => clearField($_whichOneof(1));
+
+  @$pb.TagNumber(1)
+  $core.String get groupFieldId => $_getSZ(0);
+  @$pb.TagNumber(1)
+  set groupFieldId($core.String v) { $_setString(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasGroupFieldId() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearGroupFieldId() => clearField(1);
+
+  @$pb.TagNumber(2)
+  $core.String get subGroupFieldId => $_getSZ(1);
+  @$pb.TagNumber(2)
+  set subGroupFieldId($core.String v) { $_setString(1, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasSubGroupFieldId() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearSubGroupFieldId() => clearField(2);
+}
+
+enum ViewSort_OneOfFieldId {
+  fieldId, 
+  notSet
+}
+
+class ViewSort extends $pb.GeneratedMessage {
+  static const $core.Map<$core.int, ViewSort_OneOfFieldId> _ViewSort_OneOfFieldIdByTag = {
+    1 : ViewSort_OneOfFieldId.fieldId,
+    0 : ViewSort_OneOfFieldId.notSet
+  };
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ViewSort', createEmptyInstance: create)
+    ..oo(0, [1])
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId')
+    ..hasRequiredFields = false
+  ;
+
+  ViewSort._() : super();
+  factory ViewSort({
+    $core.String? fieldId,
+  }) {
+    final _result = create();
+    if (fieldId != null) {
+      _result.fieldId = fieldId;
+    }
+    return _result;
+  }
+  factory ViewSort.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory ViewSort.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')
+  ViewSort clone() => ViewSort()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  ViewSort copyWith(void Function(ViewSort) updates) => super.copyWith((message) => updates(message as ViewSort)) as ViewSort; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static ViewSort create() => ViewSort._();
+  ViewSort createEmptyInstance() => create();
+  static $pb.PbList<ViewSort> createRepeated() => $pb.PbList<ViewSort>();
+  @$core.pragma('dart2js:noInline')
+  static ViewSort getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ViewSort>(create);
+  static ViewSort? _defaultInstance;
+
+  ViewSort_OneOfFieldId whichOneOfFieldId() => _ViewSort_OneOfFieldIdByTag[$_whichOneof(0)]!;
+  void clearOneOfFieldId() => clearField($_whichOneof(0));
+
+  @$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);
+}
+
+enum GridInfoChangesetPayload_OneOfFilter {
+  filter, 
+  notSet
+}
+
+enum GridInfoChangesetPayload_OneOfGroup {
+  group, 
+  notSet
+}
+
+enum GridInfoChangesetPayload_OneOfSort {
+  sort, 
+  notSet
+}
+
+class GridInfoChangesetPayload extends $pb.GeneratedMessage {
+  static const $core.Map<$core.int, GridInfoChangesetPayload_OneOfFilter> _GridInfoChangesetPayload_OneOfFilterByTag = {
+    2 : GridInfoChangesetPayload_OneOfFilter.filter,
+    0 : GridInfoChangesetPayload_OneOfFilter.notSet
+  };
+  static const $core.Map<$core.int, GridInfoChangesetPayload_OneOfGroup> _GridInfoChangesetPayload_OneOfGroupByTag = {
+    3 : GridInfoChangesetPayload_OneOfGroup.group,
+    0 : GridInfoChangesetPayload_OneOfGroup.notSet
+  };
+  static const $core.Map<$core.int, GridInfoChangesetPayload_OneOfSort> _GridInfoChangesetPayload_OneOfSortByTag = {
+    4 : GridInfoChangesetPayload_OneOfSort.sort,
+    0 : GridInfoChangesetPayload_OneOfSort.notSet
+  };
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridInfoChangesetPayload', createEmptyInstance: create)
+    ..oo(0, [2])
+    ..oo(1, [3])
+    ..oo(2, [4])
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId')
+    ..aOM<ViewFilter>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'filter', subBuilder: ViewFilter.create)
+    ..aOM<ViewGroup>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'group', subBuilder: ViewGroup.create)
+    ..aOM<ViewSort>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'sort', subBuilder: ViewSort.create)
+    ..hasRequiredFields = false
+  ;
+
+  GridInfoChangesetPayload._() : super();
+  factory GridInfoChangesetPayload({
+    $core.String? gridId,
+    ViewFilter? filter,
+    ViewGroup? group,
+    ViewSort? sort,
+  }) {
+    final _result = create();
+    if (gridId != null) {
+      _result.gridId = gridId;
+    }
+    if (filter != null) {
+      _result.filter = filter;
+    }
+    if (group != null) {
+      _result.group = group;
+    }
+    if (sort != null) {
+      _result.sort = sort;
+    }
+    return _result;
+  }
+  factory GridInfoChangesetPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory GridInfoChangesetPayload.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')
+  GridInfoChangesetPayload clone() => GridInfoChangesetPayload()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  GridInfoChangesetPayload copyWith(void Function(GridInfoChangesetPayload) updates) => super.copyWith((message) => updates(message as GridInfoChangesetPayload)) as GridInfoChangesetPayload; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static GridInfoChangesetPayload create() => GridInfoChangesetPayload._();
+  GridInfoChangesetPayload createEmptyInstance() => create();
+  static $pb.PbList<GridInfoChangesetPayload> createRepeated() => $pb.PbList<GridInfoChangesetPayload>();
+  @$core.pragma('dart2js:noInline')
+  static GridInfoChangesetPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<GridInfoChangesetPayload>(create);
+  static GridInfoChangesetPayload? _defaultInstance;
+
+  GridInfoChangesetPayload_OneOfFilter whichOneOfFilter() => _GridInfoChangesetPayload_OneOfFilterByTag[$_whichOneof(0)]!;
+  void clearOneOfFilter() => clearField($_whichOneof(0));
+
+  GridInfoChangesetPayload_OneOfGroup whichOneOfGroup() => _GridInfoChangesetPayload_OneOfGroupByTag[$_whichOneof(1)]!;
+  void clearOneOfGroup() => clearField($_whichOneof(1));
+
+  GridInfoChangesetPayload_OneOfSort whichOneOfSort() => _GridInfoChangesetPayload_OneOfSortByTag[$_whichOneof(2)]!;
+  void clearOneOfSort() => clearField($_whichOneof(2));
+
+  @$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)
+  ViewFilter get filter => $_getN(1);
+  @$pb.TagNumber(2)
+  set filter(ViewFilter v) { setField(2, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasFilter() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearFilter() => clearField(2);
+  @$pb.TagNumber(2)
+  ViewFilter ensureFilter() => $_ensure(1);
+
+  @$pb.TagNumber(3)
+  ViewGroup get group => $_getN(2);
+  @$pb.TagNumber(3)
+  set group(ViewGroup v) { setField(3, v); }
+  @$pb.TagNumber(3)
+  $core.bool hasGroup() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearGroup() => clearField(3);
+  @$pb.TagNumber(3)
+  ViewGroup ensureGroup() => $_ensure(2);
+
+  @$pb.TagNumber(4)
+  ViewSort get sort => $_getN(3);
+  @$pb.TagNumber(4)
+  set sort(ViewSort v) { setField(4, v); }
+  @$pb.TagNumber(4)
+  $core.bool hasSort() => $_has(3);
+  @$pb.TagNumber(4)
+  void clearSort() => clearField(4);
+  @$pb.TagNumber(4)
+  ViewSort ensureSort() => $_ensure(3);
+}
+

+ 7 - 0
frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid_info.pbenum.dart

@@ -0,0 +1,7 @@
+///
+//  Generated code. Do not modify.
+//  source: grid_info.proto
+//
+// @dart = 2.12
+// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields
+

+ 81 - 0
frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid_info.pbjson.dart

@@ -0,0 +1,81 @@
+///
+//  Generated code. Do not modify.
+//  source: grid_info.proto
+//
+// @dart = 2.12
+// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package
+
+import 'dart:core' as $core;
+import 'dart:convert' as $convert;
+import 'dart:typed_data' as $typed_data;
+@$core.Deprecated('Use viewExtDataDescriptor instead')
+const ViewExtData$json = const {
+  '1': 'ViewExtData',
+  '2': const [
+    const {'1': 'filter', '3': 1, '4': 1, '5': 11, '6': '.ViewFilter', '10': 'filter'},
+    const {'1': 'group', '3': 2, '4': 1, '5': 11, '6': '.ViewGroup', '10': 'group'},
+    const {'1': 'sort', '3': 3, '4': 1, '5': 11, '6': '.ViewSort', '10': 'sort'},
+  ],
+};
+
+/// Descriptor for `ViewExtData`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List viewExtDataDescriptor = $convert.base64Decode('CgtWaWV3RXh0RGF0YRIjCgZmaWx0ZXIYASABKAsyCy5WaWV3RmlsdGVyUgZmaWx0ZXISIAoFZ3JvdXAYAiABKAsyCi5WaWV3R3JvdXBSBWdyb3VwEh0KBHNvcnQYAyABKAsyCS5WaWV3U29ydFIEc29ydA==');
+@$core.Deprecated('Use viewFilterDescriptor instead')
+const ViewFilter$json = const {
+  '1': 'ViewFilter',
+  '2': const [
+    const {'1': 'field_id', '3': 1, '4': 1, '5': 9, '9': 0, '10': 'fieldId'},
+  ],
+  '8': const [
+    const {'1': 'one_of_field_id'},
+  ],
+};
+
+/// Descriptor for `ViewFilter`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List viewFilterDescriptor = $convert.base64Decode('CgpWaWV3RmlsdGVyEhsKCGZpZWxkX2lkGAEgASgJSABSB2ZpZWxkSWRCEQoPb25lX29mX2ZpZWxkX2lk');
+@$core.Deprecated('Use viewGroupDescriptor instead')
+const ViewGroup$json = const {
+  '1': 'ViewGroup',
+  '2': const [
+    const {'1': 'group_field_id', '3': 1, '4': 1, '5': 9, '9': 0, '10': 'groupFieldId'},
+    const {'1': 'sub_group_field_id', '3': 2, '4': 1, '5': 9, '9': 1, '10': 'subGroupFieldId'},
+  ],
+  '8': const [
+    const {'1': 'one_of_group_field_id'},
+    const {'1': 'one_of_sub_group_field_id'},
+  ],
+};
+
+/// Descriptor for `ViewGroup`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List viewGroupDescriptor = $convert.base64Decode('CglWaWV3R3JvdXASJgoOZ3JvdXBfZmllbGRfaWQYASABKAlIAFIMZ3JvdXBGaWVsZElkEi0KEnN1Yl9ncm91cF9maWVsZF9pZBgCIAEoCUgBUg9zdWJHcm91cEZpZWxkSWRCFwoVb25lX29mX2dyb3VwX2ZpZWxkX2lkQhsKGW9uZV9vZl9zdWJfZ3JvdXBfZmllbGRfaWQ=');
+@$core.Deprecated('Use viewSortDescriptor instead')
+const ViewSort$json = const {
+  '1': 'ViewSort',
+  '2': const [
+    const {'1': 'field_id', '3': 1, '4': 1, '5': 9, '9': 0, '10': 'fieldId'},
+  ],
+  '8': const [
+    const {'1': 'one_of_field_id'},
+  ],
+};
+
+/// Descriptor for `ViewSort`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List viewSortDescriptor = $convert.base64Decode('CghWaWV3U29ydBIbCghmaWVsZF9pZBgBIAEoCUgAUgdmaWVsZElkQhEKD29uZV9vZl9maWVsZF9pZA==');
+@$core.Deprecated('Use gridInfoChangesetPayloadDescriptor instead')
+const GridInfoChangesetPayload$json = const {
+  '1': 'GridInfoChangesetPayload',
+  '2': const [
+    const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'},
+    const {'1': 'filter', '3': 2, '4': 1, '5': 11, '6': '.ViewFilter', '9': 0, '10': 'filter'},
+    const {'1': 'group', '3': 3, '4': 1, '5': 11, '6': '.ViewGroup', '9': 1, '10': 'group'},
+    const {'1': 'sort', '3': 4, '4': 1, '5': 11, '6': '.ViewSort', '9': 2, '10': 'sort'},
+  ],
+  '8': const [
+    const {'1': 'one_of_filter'},
+    const {'1': 'one_of_group'},
+    const {'1': 'one_of_sort'},
+  ],
+};
+
+/// Descriptor for `GridInfoChangesetPayload`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List gridInfoChangesetPayloadDescriptor = $convert.base64Decode('ChhHcmlkSW5mb0NoYW5nZXNldFBheWxvYWQSFwoHZ3JpZF9pZBgBIAEoCVIGZ3JpZElkEiUKBmZpbHRlchgCIAEoCzILLlZpZXdGaWx0ZXJIAFIGZmlsdGVyEiIKBWdyb3VwGAMgASgLMgouVmlld0dyb3VwSAFSBWdyb3VwEh8KBHNvcnQYBCABKAsyCS5WaWV3U29ydEgCUgRzb3J0Qg8KDW9uZV9vZl9maWx0ZXJCDgoMb25lX29mX2dyb3VwQg0KC29uZV9vZl9zb3J0');

+ 9 - 0
frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid_info.pbserver.dart

@@ -0,0 +1,9 @@
+///
+//  Generated code. Do not modify.
+//  source: grid_info.proto
+//
+// @dart = 2.12
+// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package
+
+export 'grid_info.pb.dart';
+

+ 1 - 0
frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/protobuf.dart

@@ -1,3 +1,4 @@
 // Auto-generated, do not edit 
 export './grid.pb.dart';
+export './grid_info.pb.dart';
 export './field.pb.dart';

+ 0 - 4
frontend/rust-lib/flowy-folder/src/event_map.rs

@@ -64,7 +64,6 @@ pub fn create(folder: Arc<FolderManager>) -> Module {
         .event(FolderEvent::ReadView, read_view_handler)
         .event(FolderEvent::UpdateView, update_view_handler)
         .event(FolderEvent::ReadViewInfo, read_view_info_handler)
-        .event(FolderEvent::UpdateViewInfo, update_view_info_handler)
         .event(FolderEvent::DeleteView, delete_view_handler)
         .event(FolderEvent::DuplicateView, duplicate_view_handler)
         .event(FolderEvent::SetLatestView, set_latest_view_handler)
@@ -136,9 +135,6 @@ pub enum FolderEvent {
     #[event(input = "ViewId", output = "ViewInfo")]
     ReadViewInfo = 207,
 
-    #[event(input = "UpdateViewInfoPayload", output = "ViewInfo")]
-    UpdateViewInfo = 208,
-
     #[event()]
     CopyLink = 220,
 

+ 1 - 6
frontend/rust-lib/flowy-folder/src/manager.rs

@@ -9,15 +9,12 @@ use crate::{
     },
 };
 use bytes::Bytes;
-use flowy_sync::client_document::default::{initial_quill_delta_string, initial_read_me};
-
 use flowy_error::FlowyError;
 use flowy_folder_data_model::entities::view::ViewDataType;
-
-use flowy_folder_data_model::entities::UpdateViewInfoParams;
 use flowy_folder_data_model::user_default;
 use flowy_revision::disk::SQLiteTextBlockRevisionPersistence;
 use flowy_revision::{RevisionManager, RevisionPersistence, RevisionWebSocket};
+use flowy_sync::client_document::default::{initial_quill_delta_string, initial_read_me};
 use flowy_sync::{client_folder::FolderPad, entities::ws_data::ServerRevisionWSData};
 use lazy_static::lazy_static;
 use lib_infra::future::FutureResult;
@@ -256,8 +253,6 @@ pub trait ViewDataProcessor {
         data: Vec<u8>,
     ) -> FutureResult<Bytes, FlowyError>;
 
-    fn handle_view_info_updated(&self, params: UpdateViewInfoParams) -> FutureResult<(), FlowyError>;
-
     fn data_type(&self) -> ViewDataType;
 }
 

+ 6 - 10
frontend/rust-lib/flowy-folder/src/protobuf/model/event_map.rs

@@ -42,7 +42,6 @@ pub enum FolderEvent {
     DuplicateView = 205,
     CloseView = 206,
     ReadViewInfo = 207,
-    UpdateViewInfo = 208,
     CopyLink = 220,
     SetLatestView = 221,
     MoveFolderItem = 230,
@@ -77,7 +76,6 @@ impl ::protobuf::ProtobufEnum for FolderEvent {
             205 => ::std::option::Option::Some(FolderEvent::DuplicateView),
             206 => ::std::option::Option::Some(FolderEvent::CloseView),
             207 => ::std::option::Option::Some(FolderEvent::ReadViewInfo),
-            208 => ::std::option::Option::Some(FolderEvent::UpdateViewInfo),
             220 => ::std::option::Option::Some(FolderEvent::CopyLink),
             221 => ::std::option::Option::Some(FolderEvent::SetLatestView),
             230 => ::std::option::Option::Some(FolderEvent::MoveFolderItem),
@@ -109,7 +107,6 @@ impl ::protobuf::ProtobufEnum for FolderEvent {
             FolderEvent::DuplicateView,
             FolderEvent::CloseView,
             FolderEvent::ReadViewInfo,
-            FolderEvent::UpdateViewInfo,
             FolderEvent::CopyLink,
             FolderEvent::SetLatestView,
             FolderEvent::MoveFolderItem,
@@ -146,7 +143,7 @@ impl ::protobuf::reflect::ProtobufValue for FolderEvent {
 }
 
 static file_descriptor_proto_data: &'static [u8] = b"\
-    \n\x0fevent_map.proto*\xeb\x03\n\x0bFolderEvent\x12\x13\n\x0fCreateWorks\
+    \n\x0fevent_map.proto*\xd6\x03\n\x0bFolderEvent\x12\x13\n\x0fCreateWorks\
     pace\x10\0\x12\x14\n\x10ReadCurWorkspace\x10\x01\x12\x12\n\x0eReadWorksp\
     aces\x10\x02\x12\x13\n\x0fDeleteWorkspace\x10\x03\x12\x11\n\rOpenWorkspa\
     ce\x10\x04\x12\x15\n\x11ReadWorkspaceApps\x10\x05\x12\r\n\tCreateApp\x10\
@@ -154,12 +151,11 @@ static file_descriptor_proto_data: &'static [u8] = b"\
     \x10h\x12\x0f\n\nCreateView\x10\xc9\x01\x12\r\n\x08ReadView\x10\xca\x01\
     \x12\x0f\n\nUpdateView\x10\xcb\x01\x12\x0f\n\nDeleteView\x10\xcc\x01\x12\
     \x12\n\rDuplicateView\x10\xcd\x01\x12\x0e\n\tCloseView\x10\xce\x01\x12\
-    \x11\n\x0cReadViewInfo\x10\xcf\x01\x12\x13\n\x0eUpdateViewInfo\x10\xd0\
-    \x01\x12\r\n\x08CopyLink\x10\xdc\x01\x12\x12\n\rSetLatestView\x10\xdd\
-    \x01\x12\x13\n\x0eMoveFolderItem\x10\xe6\x01\x12\x0e\n\tReadTrash\x10\
-    \xac\x02\x12\x11\n\x0cPutbackTrash\x10\xad\x02\x12\x10\n\x0bDeleteTrash\
-    \x10\xae\x02\x12\x14\n\x0fRestoreAllTrash\x10\xaf\x02\x12\x13\n\x0eDelet\
-    eAllTrash\x10\xb0\x02b\x06proto3\
+    \x11\n\x0cReadViewInfo\x10\xcf\x01\x12\r\n\x08CopyLink\x10\xdc\x01\x12\
+    \x12\n\rSetLatestView\x10\xdd\x01\x12\x13\n\x0eMoveFolderItem\x10\xe6\
+    \x01\x12\x0e\n\tReadTrash\x10\xac\x02\x12\x11\n\x0cPutbackTrash\x10\xad\
+    \x02\x12\x10\n\x0bDeleteTrash\x10\xae\x02\x12\x14\n\x0fRestoreAllTrash\
+    \x10\xaf\x02\x12\x13\n\x0eDeleteAllTrash\x10\xb0\x02b\x06proto3\
 ";
 
 static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

+ 0 - 1
frontend/rust-lib/flowy-folder/src/protobuf/proto/event_map.proto

@@ -18,7 +18,6 @@ enum FolderEvent {
     DuplicateView = 205;
     CloseView = 206;
     ReadViewInfo = 207;
-    UpdateViewInfo = 208;
     CopyLink = 220;
     SetLatestView = 221;
     MoveFolderItem = 230;

+ 5 - 7
frontend/rust-lib/flowy-folder/src/services/folder_editor.rs

@@ -1,16 +1,14 @@
-use flowy_sync::{
-    client_folder::{FolderChange, FolderPad},
-    entities::{revision::Revision, ws_data::ServerRevisionWSData},
-};
-
 use crate::manager::FolderId;
 use bytes::Bytes;
 use flowy_error::{FlowyError, FlowyResult};
-use flowy_sync::util::make_delta_from_revisions;
-
 use flowy_revision::{
     RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder, RevisionWebSocket,
 };
+use flowy_sync::util::make_delta_from_revisions;
+use flowy_sync::{
+    client_folder::{FolderChange, FolderPad},
+    entities::{revision::Revision, ws_data::ServerRevisionWSData},
+};
 use lib_infra::future::FutureResult;
 use lib_ot::core::PlainTextAttributes;
 

+ 2 - 8
frontend/rust-lib/flowy-folder/src/services/view/controller.rs

@@ -15,7 +15,7 @@ use crate::{
 use bytes::Bytes;
 use flowy_database::kv::KV;
 use flowy_folder_data_model::entities::view::{gen_view_id, ViewDataType};
-use flowy_folder_data_model::entities::{UpdateViewInfoParams, ViewExtData, ViewInfo};
+use flowy_folder_data_model::entities::ViewInfo;
 use flowy_folder_data_model::revision::ViewRevision;
 use flowy_sync::entities::text_block_info::TextBlockId;
 use futures::{FutureExt, StreamExt};
@@ -135,7 +135,6 @@ impl ViewController {
                     .map(|view_rev| view_rev.into())
                     .collect();
 
-                let ext_data = ViewExtData::from(view_rev.ext_data);
                 let view_info = ViewInfo {
                     id: view_rev.id,
                     belong_to_id: view_rev.belong_to_id,
@@ -143,7 +142,7 @@ impl ViewController {
                     desc: view_rev.desc,
                     data_type: view_rev.data_type,
                     belongings: RepeatedView { items },
-                    ext_data,
+                    ext_data: view_rev.ext_data,
                 };
                 Ok(view_info)
             })
@@ -259,11 +258,6 @@ impl ViewController {
         Ok(view_rev)
     }
 
-    #[tracing::instrument(level = "debug", skip(self, _params), err)]
-    pub(crate) async fn update_view_info(&self, _params: UpdateViewInfoParams) -> Result<(), FlowyError> {
-        todo!()
-    }
-
     pub(crate) async fn latest_visit_view(&self) -> FlowyResult<Option<ViewRevision>> {
         match KV::get_str(LATEST_VIEW_ID) {
             None => Ok(None),

+ 1 - 12
frontend/rust-lib/flowy-folder/src/services/view/event_handler.rs

@@ -11,7 +11,7 @@ use crate::{
     services::{TrashController, ViewController},
 };
 use flowy_folder_data_model::entities::view::{MoveFolderItemParams, MoveFolderItemPayload, MoveFolderItemType};
-use flowy_folder_data_model::entities::{UpdateViewInfoParams, UpdateViewInfoPayload, ViewInfo};
+use flowy_folder_data_model::entities::ViewInfo;
 use flowy_folder_data_model::revision::TrashRevision;
 use lib_dispatch::prelude::{data_result, AppData, Data, DataResult};
 use std::{convert::TryInto, sync::Arc};
@@ -54,17 +54,6 @@ pub(crate) async fn update_view_handler(
     Ok(())
 }
 
-#[tracing::instrument(level = "debug", skip(data, controller), err)]
-pub(crate) async fn update_view_info_handler(
-    data: Data<UpdateViewInfoPayload>,
-    controller: AppData<Arc<ViewController>>,
-) -> Result<(), FlowyError> {
-    let params: UpdateViewInfoParams = data.into_inner().try_into()?;
-    let _ = controller.update_view_info(params).await?;
-
-    Ok(())
-}
-
 pub(crate) async fn delete_view_handler(
     data: Data<RepeatedViewId>,
     view_controller: AppData<Arc<ViewController>>,

+ 2 - 1
frontend/rust-lib/flowy-grid/src/manager.rs

@@ -6,7 +6,7 @@ use bytes::Bytes;
 use dashmap::DashMap;
 use flowy_database::ConnectionPool;
 use flowy_error::{FlowyError, FlowyResult};
-use flowy_grid_data_model::revision::{BuildGridContext, GridRevision};
+use flowy_grid_data_model::revision::{BuildGridContext, GridInfoRevision, GridRevision};
 use flowy_revision::disk::{SQLiteGridBlockMetaRevisionPersistence, SQLiteGridRevisionPersistence};
 use flowy_revision::{RevisionManager, RevisionPersistence, RevisionWebSocket};
 use flowy_sync::client_grid::{make_block_meta_delta, make_grid_delta};
@@ -160,6 +160,7 @@ pub async fn make_grid_view_data(
         grid_id: view_id.to_string(),
         fields: build_context.field_revs,
         blocks: build_context.blocks,
+        info: GridInfoRevision::default(),
     };
 
     // Create grid

+ 1 - 1
frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs

@@ -45,7 +45,7 @@ impl CellDataOperation<String> for CheckboxTypeOption {
         &self,
         encoded_data: T,
         decoded_field_type: &FieldType,
-        field_rev: &FieldRevision,
+        _field_rev: &FieldRevision,
     ) -> FlowyResult<DecodedCellData>
     where
         T: Into<String>,

+ 1 - 1
frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs

@@ -120,7 +120,7 @@ impl CellDataOperation<String> for DateTypeOption {
         &self,
         encoded_data: T,
         decoded_field_type: &FieldType,
-        field_rev: &FieldRevision,
+        _field_rev: &FieldRevision,
     ) -> FlowyResult<DecodedCellData>
     where
         T: Into<String>,

+ 1 - 1
frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option/number_type_option.rs

@@ -144,7 +144,7 @@ impl CellDataOperation<String> for NumberTypeOption {
         &self,
         encoded_data: T,
         decoded_field_type: &FieldType,
-        field_rev: &FieldRevision,
+        _field_rev: &FieldRevision,
     ) -> FlowyResult<DecodedCellData>
     where
         T: Into<String>,

+ 2 - 2
frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs

@@ -99,7 +99,7 @@ impl CellDataOperation<String> for SingleSelectTypeOption {
         &self,
         encoded_data: T,
         decoded_field_type: &FieldType,
-        field_rev: &FieldRevision,
+        _field_rev: &FieldRevision,
     ) -> FlowyResult<DecodedCellData>
     where
         T: Into<String>,
@@ -197,7 +197,7 @@ impl CellDataOperation<String> for MultiSelectTypeOption {
         &self,
         encoded_data: T,
         decoded_field_type: &FieldType,
-        field_rev: &FieldRevision,
+        _field_rev: &FieldRevision,
     ) -> FlowyResult<DecodedCellData>
     where
         T: Into<String>,

+ 1 - 1
frontend/rust-lib/flowy-grid/src/services/field/type_options/url_type_option.rs

@@ -38,7 +38,7 @@ impl CellDataOperation<EncodedCellData<URLCellData>> for URLTypeOption {
         &self,
         encoded_data: T,
         decoded_field_type: &FieldType,
-        field_rev: &FieldRevision,
+        _field_rev: &FieldRevision,
     ) -> FlowyResult<DecodedCellData>
     where
         T: Into<EncodedCellData<URLCellData>>,

+ 1 - 4
frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs

@@ -24,10 +24,7 @@ impl<'a> CreateRowMetaBuilder<'a> {
             visibility: true,
         };
 
-        Self {
-            field_rev_map: field_rev_map,
-            payload,
-        }
+        Self { field_rev_map, payload }
     }
 
     pub fn add_cell(&mut self, field_id: &str, data: String) -> FlowyResult<()> {

+ 0 - 10
frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs

@@ -1,6 +1,5 @@
 use bytes::Bytes;
 use flowy_database::ConnectionPool;
-use flowy_folder::entities::UpdateViewInfoParams;
 use flowy_folder::manager::{ViewDataProcessor, ViewDataProcessorMap};
 use flowy_folder::prelude::ViewDataType;
 use flowy_folder::{
@@ -204,11 +203,6 @@ impl ViewDataProcessor for TextBlockViewDataProcessor {
         FutureResult::new(async move { Ok(Bytes::from(data)) })
     }
 
-    fn handle_view_info_updated(&self, _params: UpdateViewInfoParams) -> FutureResult<(), FlowyError> {
-        tracing::warn!("Unimplemented the handle_view_info_updated in TextBlock");
-        FutureResult::new(async { Ok(()) })
-    }
-
     fn data_type(&self) -> ViewDataType {
         ViewDataType::TextBlock
     }
@@ -284,10 +278,6 @@ impl ViewDataProcessor for GridViewDataProcessor {
         })
     }
 
-    fn handle_view_info_updated(&self, params: UpdateViewInfoParams) -> FutureResult<(), FlowyError> {
-        todo!()
-    }
-
     fn data_type(&self) -> ViewDataType {
         ViewDataType::Grid
     }

+ 1 - 90
shared-lib/flowy-folder-data-model/src/entities/view_info.rs

@@ -1,9 +1,5 @@
 use crate::entities::{RepeatedView, ViewDataType};
-use crate::parser::view::ViewIdentify;
-use crate::parser::view_info::{ViewFilterParser, ViewGroupParser, ViewSortParser};
 use flowy_derive::ProtoBuf;
-use flowy_error_code::ErrorCode;
-use std::convert::TryInto;
 
 #[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
 pub struct ViewInfo {
@@ -26,90 +22,5 @@ pub struct ViewInfo {
     pub belongings: RepeatedView,
 
     #[pb(index = 7)]
-    pub ext_data: ViewExtData,
-}
-
-#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
-pub struct ViewExtData {
-    #[pb(index = 1)]
-    pub filter: ViewFilter,
-
-    #[pb(index = 2)]
-    pub group: ViewGroup,
-
-    #[pb(index = 3)]
-    pub sort: ViewSort,
-}
-
-#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
-pub struct ViewFilter {
-    #[pb(index = 1)]
-    pub object_id: String,
-}
-
-#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
-pub struct ViewGroup {
-    #[pb(index = 1)]
-    pub group_object_id: String,
-
-    #[pb(index = 2, one_of)]
-    pub sub_group_object_id: Option<String>,
-}
-
-#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
-pub struct ViewSort {
-    #[pb(index = 1)]
-    pub object_id: String,
-}
-
-#[derive(Default, ProtoBuf)]
-pub struct UpdateViewInfoPayload {
-    #[pb(index = 1)]
-    pub view_id: String,
-
-    #[pb(index = 2, one_of)]
-    pub filter: Option<ViewFilter>,
-
-    #[pb(index = 3, one_of)]
-    pub group: Option<ViewGroup>,
-
-    #[pb(index = 4, one_of)]
-    pub sort: Option<ViewSort>,
-}
-
-pub struct UpdateViewInfoParams {
-    pub view_id: String,
-    pub filter: Option<ViewFilter>,
-    pub group: Option<ViewGroup>,
-    pub sort: Option<ViewSort>,
-}
-
-impl TryInto<UpdateViewInfoParams> for UpdateViewInfoPayload {
-    type Error = ErrorCode;
-
-    fn try_into(self) -> Result<UpdateViewInfoParams, Self::Error> {
-        let view_id = ViewIdentify::parse(self.view_id)?.0;
-
-        let filter = match self.filter {
-            None => None,
-            Some(filter) => Some(ViewFilterParser::parse(filter)?),
-        };
-
-        let group = match self.group {
-            None => None,
-            Some(group) => Some(ViewGroupParser::parse(group)?),
-        };
-
-        let sort = match self.sort {
-            None => None,
-            Some(sort) => Some(ViewSortParser::parse(sort)?),
-        };
-
-        Ok(UpdateViewInfoParams {
-            view_id,
-            filter,
-            group,
-            sort,
-        })
-    }
+    pub ext_data: String,
 }

+ 0 - 1
shared-lib/flowy-folder-data-model/src/parser/mod.rs

@@ -1,5 +1,4 @@
 pub mod app;
 pub mod trash;
 pub mod view;
-pub mod view_info;
 pub mod workspace;

+ 0 - 5
shared-lib/flowy-folder-data-model/src/parser/view_info/mod.rs

@@ -1,5 +0,0 @@
-mod object_id;
-mod view_ext;
-
-pub use object_id::*;
-pub use view_ext::*;

+ 0 - 19
shared-lib/flowy-folder-data-model/src/parser/view_info/object_id.rs

@@ -1,19 +0,0 @@
-use crate::errors::ErrorCode;
-
-#[derive(Debug)]
-pub struct ObjectId(pub String);
-
-impl ObjectId {
-    pub fn parse(s: String) -> Result<ObjectId, ErrorCode> {
-        if s.trim().is_empty() {
-            return Err(ErrorCode::UnexpectedEmptyString);
-        }
-        Ok(Self(s))
-    }
-}
-
-impl AsRef<str> for ObjectId {
-    fn as_ref(&self) -> &str {
-        &self.0
-    }
-}

+ 0 - 40
shared-lib/flowy-folder-data-model/src/parser/view_info/view_ext.rs

@@ -1,40 +0,0 @@
-use crate::entities::{ViewFilter, ViewGroup, ViewSort};
-use crate::errors::ErrorCode;
-use crate::parser::view_info::ObjectId;
-
-pub struct ViewFilterParser(pub ViewFilter);
-
-impl ViewFilterParser {
-    pub fn parse(value: ViewFilter) -> Result<ViewFilter, ErrorCode> {
-        let object_id = ObjectId::parse(value.object_id)?.0;
-        Ok(ViewFilter { object_id })
-    }
-}
-
-pub struct ViewGroupParser(pub ViewGroup);
-
-impl ViewGroupParser {
-    pub fn parse(value: ViewGroup) -> Result<ViewGroup, ErrorCode> {
-        let group_object_id = ObjectId::parse(value.group_object_id)?.0;
-
-        let sub_group_object_id = match value.sub_group_object_id {
-            None => None,
-            Some(object_id) => Some(ObjectId::parse(object_id)?.0),
-        };
-
-        Ok(ViewGroup {
-            group_object_id,
-            sub_group_object_id,
-        })
-    }
-}
-
-pub struct ViewSortParser(pub ViewSort);
-
-impl ViewSortParser {
-    pub fn parse(value: ViewSort) -> Result<ViewSort, ErrorCode> {
-        let object_id = ObjectId::parse(value.object_id)?.0;
-
-        Ok(ViewSort { object_id })
-    }
-}

+ 19 - 1321
shared-lib/flowy-folder-data-model/src/protobuf/model/view_info.rs

@@ -32,7 +32,7 @@ pub struct ViewInfo {
     pub desc: ::std::string::String,
     pub data_type: super::view::ViewDataType,
     pub belongings: ::protobuf::SingularPtrField<super::view::RepeatedView>,
-    pub ext_data: ::protobuf::SingularPtrField<ViewExtData>,
+    pub ext_data: ::std::string::String,
     // special fields
     pub unknown_fields: ::protobuf::UnknownFields,
     pub cached_size: ::protobuf::CachedSize,
@@ -201,37 +201,30 @@ impl ViewInfo {
         self.belongings.take().unwrap_or_else(|| super::view::RepeatedView::new())
     }
 
-    // .ViewExtData ext_data = 7;
+    // string ext_data = 7;
 
 
-    pub fn get_ext_data(&self) -> &ViewExtData {
-        self.ext_data.as_ref().unwrap_or_else(|| <ViewExtData as ::protobuf::Message>::default_instance())
+    pub fn get_ext_data(&self) -> &str {
+        &self.ext_data
     }
     pub fn clear_ext_data(&mut self) {
         self.ext_data.clear();
     }
 
-    pub fn has_ext_data(&self) -> bool {
-        self.ext_data.is_some()
-    }
-
     // Param is passed by value, moved
-    pub fn set_ext_data(&mut self, v: ViewExtData) {
-        self.ext_data = ::protobuf::SingularPtrField::some(v);
+    pub fn set_ext_data(&mut self, v: ::std::string::String) {
+        self.ext_data = v;
     }
 
     // Mutable pointer to the field.
     // If field is not initialized, it is initialized with default value first.
-    pub fn mut_ext_data(&mut self) -> &mut ViewExtData {
-        if self.ext_data.is_none() {
-            self.ext_data.set_default();
-        }
-        self.ext_data.as_mut().unwrap()
+    pub fn mut_ext_data(&mut self) -> &mut ::std::string::String {
+        &mut self.ext_data
     }
 
     // Take field
-    pub fn take_ext_data(&mut self) -> ViewExtData {
-        self.ext_data.take().unwrap_or_else(|| ViewExtData::new())
+    pub fn take_ext_data(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.ext_data, ::std::string::String::new())
     }
 }
 
@@ -242,11 +235,6 @@ impl ::protobuf::Message for ViewInfo {
                 return false;
             }
         };
-        for v in &self.ext_data {
-            if !v.is_initialized() {
-                return false;
-            }
-        };
         true
     }
 
@@ -273,7 +261,7 @@ impl ::protobuf::Message for ViewInfo {
                     ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.belongings)?;
                 },
                 7 => {
-                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.ext_data)?;
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.ext_data)?;
                 },
                 _ => {
                     ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
@@ -306,9 +294,8 @@ impl ::protobuf::Message for ViewInfo {
             let len = v.compute_size();
             my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
         }
-        if let Some(ref v) = self.ext_data.as_ref() {
-            let len = v.compute_size();
-            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        if !self.ext_data.is_empty() {
+            my_size += ::protobuf::rt::string_size(7, &self.ext_data);
         }
         my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
         self.cached_size.set(my_size);
@@ -336,10 +323,8 @@ impl ::protobuf::Message for ViewInfo {
             os.write_raw_varint32(v.get_cached_size())?;
             v.write_to_with_cached_sizes(os)?;
         }
-        if let Some(ref v) = self.ext_data.as_ref() {
-            os.write_tag(7, ::protobuf::wire_format::WireTypeLengthDelimited)?;
-            os.write_raw_varint32(v.get_cached_size())?;
-            v.write_to_with_cached_sizes(os)?;
+        if !self.ext_data.is_empty() {
+            os.write_string(7, &self.ext_data)?;
         }
         os.write_unknown_fields(self.get_unknown_fields())?;
         ::std::result::Result::Ok(())
@@ -409,7 +394,7 @@ impl ::protobuf::Message for ViewInfo {
                 |m: &ViewInfo| { &m.belongings },
                 |m: &mut ViewInfo| { &mut m.belongings },
             ));
-            fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<ViewExtData>>(
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
                 "ext_data",
                 |m: &ViewInfo| { &m.ext_data },
                 |m: &mut ViewInfo| { &mut m.ext_data },
@@ -453,1301 +438,14 @@ impl ::protobuf::reflect::ProtobufValue for ViewInfo {
     }
 }
 
-#[derive(PartialEq,Clone,Default)]
-pub struct ViewExtData {
-    // message fields
-    pub filter: ::protobuf::SingularPtrField<ViewFilter>,
-    pub group: ::protobuf::SingularPtrField<ViewGroup>,
-    pub sort: ::protobuf::SingularPtrField<ViewSort>,
-    // special fields
-    pub unknown_fields: ::protobuf::UnknownFields,
-    pub cached_size: ::protobuf::CachedSize,
-}
-
-impl<'a> ::std::default::Default for &'a ViewExtData {
-    fn default() -> &'a ViewExtData {
-        <ViewExtData as ::protobuf::Message>::default_instance()
-    }
-}
-
-impl ViewExtData {
-    pub fn new() -> ViewExtData {
-        ::std::default::Default::default()
-    }
-
-    // .ViewFilter filter = 1;
-
-
-    pub fn get_filter(&self) -> &ViewFilter {
-        self.filter.as_ref().unwrap_or_else(|| <ViewFilter as ::protobuf::Message>::default_instance())
-    }
-    pub fn clear_filter(&mut self) {
-        self.filter.clear();
-    }
-
-    pub fn has_filter(&self) -> bool {
-        self.filter.is_some()
-    }
-
-    // Param is passed by value, moved
-    pub fn set_filter(&mut self, v: ViewFilter) {
-        self.filter = ::protobuf::SingularPtrField::some(v);
-    }
-
-    // Mutable pointer to the field.
-    // If field is not initialized, it is initialized with default value first.
-    pub fn mut_filter(&mut self) -> &mut ViewFilter {
-        if self.filter.is_none() {
-            self.filter.set_default();
-        }
-        self.filter.as_mut().unwrap()
-    }
-
-    // Take field
-    pub fn take_filter(&mut self) -> ViewFilter {
-        self.filter.take().unwrap_or_else(|| ViewFilter::new())
-    }
-
-    // .ViewGroup group = 2;
-
-
-    pub fn get_group(&self) -> &ViewGroup {
-        self.group.as_ref().unwrap_or_else(|| <ViewGroup as ::protobuf::Message>::default_instance())
-    }
-    pub fn clear_group(&mut self) {
-        self.group.clear();
-    }
-
-    pub fn has_group(&self) -> bool {
-        self.group.is_some()
-    }
-
-    // Param is passed by value, moved
-    pub fn set_group(&mut self, v: ViewGroup) {
-        self.group = ::protobuf::SingularPtrField::some(v);
-    }
-
-    // Mutable pointer to the field.
-    // If field is not initialized, it is initialized with default value first.
-    pub fn mut_group(&mut self) -> &mut ViewGroup {
-        if self.group.is_none() {
-            self.group.set_default();
-        }
-        self.group.as_mut().unwrap()
-    }
-
-    // Take field
-    pub fn take_group(&mut self) -> ViewGroup {
-        self.group.take().unwrap_or_else(|| ViewGroup::new())
-    }
-
-    // .ViewSort sort = 3;
-
-
-    pub fn get_sort(&self) -> &ViewSort {
-        self.sort.as_ref().unwrap_or_else(|| <ViewSort as ::protobuf::Message>::default_instance())
-    }
-    pub fn clear_sort(&mut self) {
-        self.sort.clear();
-    }
-
-    pub fn has_sort(&self) -> bool {
-        self.sort.is_some()
-    }
-
-    // Param is passed by value, moved
-    pub fn set_sort(&mut self, v: ViewSort) {
-        self.sort = ::protobuf::SingularPtrField::some(v);
-    }
-
-    // Mutable pointer to the field.
-    // If field is not initialized, it is initialized with default value first.
-    pub fn mut_sort(&mut self) -> &mut ViewSort {
-        if self.sort.is_none() {
-            self.sort.set_default();
-        }
-        self.sort.as_mut().unwrap()
-    }
-
-    // Take field
-    pub fn take_sort(&mut self) -> ViewSort {
-        self.sort.take().unwrap_or_else(|| ViewSort::new())
-    }
-}
-
-impl ::protobuf::Message for ViewExtData {
-    fn is_initialized(&self) -> bool {
-        for v in &self.filter {
-            if !v.is_initialized() {
-                return false;
-            }
-        };
-        for v in &self.group {
-            if !v.is_initialized() {
-                return false;
-            }
-        };
-        for v in &self.sort {
-            if !v.is_initialized() {
-                return false;
-            }
-        };
-        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_message_into(wire_type, is, &mut self.filter)?;
-                },
-                2 => {
-                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.group)?;
-                },
-                3 => {
-                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.sort)?;
-                },
-                _ => {
-                    ::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 let Some(ref v) = self.filter.as_ref() {
-            let len = v.compute_size();
-            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
-        }
-        if let Some(ref v) = self.group.as_ref() {
-            let len = v.compute_size();
-            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
-        }
-        if let Some(ref v) = self.sort.as_ref() {
-            let len = v.compute_size();
-            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
-        }
-        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 let Some(ref v) = self.filter.as_ref() {
-            os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?;
-            os.write_raw_varint32(v.get_cached_size())?;
-            v.write_to_with_cached_sizes(os)?;
-        }
-        if let Some(ref v) = self.group.as_ref() {
-            os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?;
-            os.write_raw_varint32(v.get_cached_size())?;
-            v.write_to_with_cached_sizes(os)?;
-        }
-        if let Some(ref v) = self.sort.as_ref() {
-            os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?;
-            os.write_raw_varint32(v.get_cached_size())?;
-            v.write_to_with_cached_sizes(os)?;
-        }
-        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<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
-        self
-    }
-
-    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
-        Self::descriptor_static()
-    }
-
-    fn new() -> ViewExtData {
-        ViewExtData::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_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<ViewFilter>>(
-                "filter",
-                |m: &ViewExtData| { &m.filter },
-                |m: &mut ViewExtData| { &mut m.filter },
-            ));
-            fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<ViewGroup>>(
-                "group",
-                |m: &ViewExtData| { &m.group },
-                |m: &mut ViewExtData| { &mut m.group },
-            ));
-            fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<ViewSort>>(
-                "sort",
-                |m: &ViewExtData| { &m.sort },
-                |m: &mut ViewExtData| { &mut m.sort },
-            ));
-            ::protobuf::reflect::MessageDescriptor::new_pb_name::<ViewExtData>(
-                "ViewExtData",
-                fields,
-                file_descriptor_proto()
-            )
-        })
-    }
-
-    fn default_instance() -> &'static ViewExtData {
-        static instance: ::protobuf::rt::LazyV2<ViewExtData> = ::protobuf::rt::LazyV2::INIT;
-        instance.get(ViewExtData::new)
-    }
-}
-
-impl ::protobuf::Clear for ViewExtData {
-    fn clear(&mut self) {
-        self.filter.clear();
-        self.group.clear();
-        self.sort.clear();
-        self.unknown_fields.clear();
-    }
-}
-
-impl ::std::fmt::Debug for ViewExtData {
-    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
-        ::protobuf::text_format::fmt(self, f)
-    }
-}
-
-impl ::protobuf::reflect::ProtobufValue for ViewExtData {
-    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
-        ::protobuf::reflect::ReflectValueRef::Message(self)
-    }
-}
-
-#[derive(PartialEq,Clone,Default)]
-pub struct ViewFilter {
-    // message fields
-    pub object_id: ::std::string::String,
-    // special fields
-    pub unknown_fields: ::protobuf::UnknownFields,
-    pub cached_size: ::protobuf::CachedSize,
-}
-
-impl<'a> ::std::default::Default for &'a ViewFilter {
-    fn default() -> &'a ViewFilter {
-        <ViewFilter as ::protobuf::Message>::default_instance()
-    }
-}
-
-impl ViewFilter {
-    pub fn new() -> ViewFilter {
-        ::std::default::Default::default()
-    }
-
-    // string object_id = 1;
-
-
-    pub fn get_object_id(&self) -> &str {
-        &self.object_id
-    }
-    pub fn clear_object_id(&mut self) {
-        self.object_id.clear();
-    }
-
-    // Param is passed by value, moved
-    pub fn set_object_id(&mut self, v: ::std::string::String) {
-        self.object_id = v;
-    }
-
-    // Mutable pointer to the field.
-    // If field is not initialized, it is initialized with default value first.
-    pub fn mut_object_id(&mut self) -> &mut ::std::string::String {
-        &mut self.object_id
-    }
-
-    // Take field
-    pub fn take_object_id(&mut self) -> ::std::string::String {
-        ::std::mem::replace(&mut self.object_id, ::std::string::String::new())
-    }
-}
-
-impl ::protobuf::Message for ViewFilter {
-    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.object_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.object_id.is_empty() {
-            my_size += ::protobuf::rt::string_size(1, &self.object_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.object_id.is_empty() {
-            os.write_string(1, &self.object_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<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
-        self
-    }
-
-    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
-        Self::descriptor_static()
-    }
-
-    fn new() -> ViewFilter {
-        ViewFilter::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>(
-                "object_id",
-                |m: &ViewFilter| { &m.object_id },
-                |m: &mut ViewFilter| { &mut m.object_id },
-            ));
-            ::protobuf::reflect::MessageDescriptor::new_pb_name::<ViewFilter>(
-                "ViewFilter",
-                fields,
-                file_descriptor_proto()
-            )
-        })
-    }
-
-    fn default_instance() -> &'static ViewFilter {
-        static instance: ::protobuf::rt::LazyV2<ViewFilter> = ::protobuf::rt::LazyV2::INIT;
-        instance.get(ViewFilter::new)
-    }
-}
-
-impl ::protobuf::Clear for ViewFilter {
-    fn clear(&mut self) {
-        self.object_id.clear();
-        self.unknown_fields.clear();
-    }
-}
-
-impl ::std::fmt::Debug for ViewFilter {
-    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
-        ::protobuf::text_format::fmt(self, f)
-    }
-}
-
-impl ::protobuf::reflect::ProtobufValue for ViewFilter {
-    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
-        ::protobuf::reflect::ReflectValueRef::Message(self)
-    }
-}
-
-#[derive(PartialEq,Clone,Default)]
-pub struct ViewGroup {
-    // message fields
-    pub group_object_id: ::std::string::String,
-    // message oneof groups
-    pub one_of_sub_group_object_id: ::std::option::Option<ViewGroup_oneof_one_of_sub_group_object_id>,
-    // special fields
-    pub unknown_fields: ::protobuf::UnknownFields,
-    pub cached_size: ::protobuf::CachedSize,
-}
-
-impl<'a> ::std::default::Default for &'a ViewGroup {
-    fn default() -> &'a ViewGroup {
-        <ViewGroup as ::protobuf::Message>::default_instance()
-    }
-}
-
-#[derive(Clone,PartialEq,Debug)]
-pub enum ViewGroup_oneof_one_of_sub_group_object_id {
-    sub_group_object_id(::std::string::String),
-}
-
-impl ViewGroup {
-    pub fn new() -> ViewGroup {
-        ::std::default::Default::default()
-    }
-
-    // string group_object_id = 1;
-
-
-    pub fn get_group_object_id(&self) -> &str {
-        &self.group_object_id
-    }
-    pub fn clear_group_object_id(&mut self) {
-        self.group_object_id.clear();
-    }
-
-    // Param is passed by value, moved
-    pub fn set_group_object_id(&mut self, v: ::std::string::String) {
-        self.group_object_id = v;
-    }
-
-    // Mutable pointer to the field.
-    // If field is not initialized, it is initialized with default value first.
-    pub fn mut_group_object_id(&mut self) -> &mut ::std::string::String {
-        &mut self.group_object_id
-    }
-
-    // Take field
-    pub fn take_group_object_id(&mut self) -> ::std::string::String {
-        ::std::mem::replace(&mut self.group_object_id, ::std::string::String::new())
-    }
-
-    // string sub_group_object_id = 2;
-
-
-    pub fn get_sub_group_object_id(&self) -> &str {
-        match self.one_of_sub_group_object_id {
-            ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_object_id::sub_group_object_id(ref v)) => v,
-            _ => "",
-        }
-    }
-    pub fn clear_sub_group_object_id(&mut self) {
-        self.one_of_sub_group_object_id = ::std::option::Option::None;
-    }
-
-    pub fn has_sub_group_object_id(&self) -> bool {
-        match self.one_of_sub_group_object_id {
-            ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_object_id::sub_group_object_id(..)) => true,
-            _ => false,
-        }
-    }
-
-    // Param is passed by value, moved
-    pub fn set_sub_group_object_id(&mut self, v: ::std::string::String) {
-        self.one_of_sub_group_object_id = ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_object_id::sub_group_object_id(v))
-    }
-
-    // Mutable pointer to the field.
-    pub fn mut_sub_group_object_id(&mut self) -> &mut ::std::string::String {
-        if let ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_object_id::sub_group_object_id(_)) = self.one_of_sub_group_object_id {
-        } else {
-            self.one_of_sub_group_object_id = ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_object_id::sub_group_object_id(::std::string::String::new()));
-        }
-        match self.one_of_sub_group_object_id {
-            ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_object_id::sub_group_object_id(ref mut v)) => v,
-            _ => panic!(),
-        }
-    }
-
-    // Take field
-    pub fn take_sub_group_object_id(&mut self) -> ::std::string::String {
-        if self.has_sub_group_object_id() {
-            match self.one_of_sub_group_object_id.take() {
-                ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_object_id::sub_group_object_id(v)) => v,
-                _ => panic!(),
-            }
-        } else {
-            ::std::string::String::new()
-        }
-    }
-}
-
-impl ::protobuf::Message for ViewGroup {
-    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.group_object_id)?;
-                },
-                2 => {
-                    if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
-                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
-                    }
-                    self.one_of_sub_group_object_id = ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_object_id::sub_group_object_id(is.read_string()?));
-                },
-                _ => {
-                    ::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.group_object_id.is_empty() {
-            my_size += ::protobuf::rt::string_size(1, &self.group_object_id);
-        }
-        if let ::std::option::Option::Some(ref v) = self.one_of_sub_group_object_id {
-            match v {
-                &ViewGroup_oneof_one_of_sub_group_object_id::sub_group_object_id(ref v) => {
-                    my_size += ::protobuf::rt::string_size(2, &v);
-                },
-            };
-        }
-        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.group_object_id.is_empty() {
-            os.write_string(1, &self.group_object_id)?;
-        }
-        if let ::std::option::Option::Some(ref v) = self.one_of_sub_group_object_id {
-            match v {
-                &ViewGroup_oneof_one_of_sub_group_object_id::sub_group_object_id(ref v) => {
-                    os.write_string(2, v)?;
-                },
-            };
-        }
-        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<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
-        self
-    }
-
-    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
-        Self::descriptor_static()
-    }
-
-    fn new() -> ViewGroup {
-        ViewGroup::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>(
-                "group_object_id",
-                |m: &ViewGroup| { &m.group_object_id },
-                |m: &mut ViewGroup| { &mut m.group_object_id },
-            ));
-            fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>(
-                "sub_group_object_id",
-                ViewGroup::has_sub_group_object_id,
-                ViewGroup::get_sub_group_object_id,
-            ));
-            ::protobuf::reflect::MessageDescriptor::new_pb_name::<ViewGroup>(
-                "ViewGroup",
-                fields,
-                file_descriptor_proto()
-            )
-        })
-    }
-
-    fn default_instance() -> &'static ViewGroup {
-        static instance: ::protobuf::rt::LazyV2<ViewGroup> = ::protobuf::rt::LazyV2::INIT;
-        instance.get(ViewGroup::new)
-    }
-}
-
-impl ::protobuf::Clear for ViewGroup {
-    fn clear(&mut self) {
-        self.group_object_id.clear();
-        self.one_of_sub_group_object_id = ::std::option::Option::None;
-        self.unknown_fields.clear();
-    }
-}
-
-impl ::std::fmt::Debug for ViewGroup {
-    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
-        ::protobuf::text_format::fmt(self, f)
-    }
-}
-
-impl ::protobuf::reflect::ProtobufValue for ViewGroup {
-    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
-        ::protobuf::reflect::ReflectValueRef::Message(self)
-    }
-}
-
-#[derive(PartialEq,Clone,Default)]
-pub struct ViewSort {
-    // message fields
-    pub object_id: ::std::string::String,
-    // special fields
-    pub unknown_fields: ::protobuf::UnknownFields,
-    pub cached_size: ::protobuf::CachedSize,
-}
-
-impl<'a> ::std::default::Default for &'a ViewSort {
-    fn default() -> &'a ViewSort {
-        <ViewSort as ::protobuf::Message>::default_instance()
-    }
-}
-
-impl ViewSort {
-    pub fn new() -> ViewSort {
-        ::std::default::Default::default()
-    }
-
-    // string object_id = 1;
-
-
-    pub fn get_object_id(&self) -> &str {
-        &self.object_id
-    }
-    pub fn clear_object_id(&mut self) {
-        self.object_id.clear();
-    }
-
-    // Param is passed by value, moved
-    pub fn set_object_id(&mut self, v: ::std::string::String) {
-        self.object_id = v;
-    }
-
-    // Mutable pointer to the field.
-    // If field is not initialized, it is initialized with default value first.
-    pub fn mut_object_id(&mut self) -> &mut ::std::string::String {
-        &mut self.object_id
-    }
-
-    // Take field
-    pub fn take_object_id(&mut self) -> ::std::string::String {
-        ::std::mem::replace(&mut self.object_id, ::std::string::String::new())
-    }
-}
-
-impl ::protobuf::Message for ViewSort {
-    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.object_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.object_id.is_empty() {
-            my_size += ::protobuf::rt::string_size(1, &self.object_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.object_id.is_empty() {
-            os.write_string(1, &self.object_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<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
-        self
-    }
-
-    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
-        Self::descriptor_static()
-    }
-
-    fn new() -> ViewSort {
-        ViewSort::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>(
-                "object_id",
-                |m: &ViewSort| { &m.object_id },
-                |m: &mut ViewSort| { &mut m.object_id },
-            ));
-            ::protobuf::reflect::MessageDescriptor::new_pb_name::<ViewSort>(
-                "ViewSort",
-                fields,
-                file_descriptor_proto()
-            )
-        })
-    }
-
-    fn default_instance() -> &'static ViewSort {
-        static instance: ::protobuf::rt::LazyV2<ViewSort> = ::protobuf::rt::LazyV2::INIT;
-        instance.get(ViewSort::new)
-    }
-}
-
-impl ::protobuf::Clear for ViewSort {
-    fn clear(&mut self) {
-        self.object_id.clear();
-        self.unknown_fields.clear();
-    }
-}
-
-impl ::std::fmt::Debug for ViewSort {
-    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
-        ::protobuf::text_format::fmt(self, f)
-    }
-}
-
-impl ::protobuf::reflect::ProtobufValue for ViewSort {
-    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
-        ::protobuf::reflect::ReflectValueRef::Message(self)
-    }
-}
-
-#[derive(PartialEq,Clone,Default)]
-pub struct UpdateViewInfoPayload {
-    // message fields
-    pub view_id: ::std::string::String,
-    // message oneof groups
-    pub one_of_filter: ::std::option::Option<UpdateViewInfoPayload_oneof_one_of_filter>,
-    pub one_of_group: ::std::option::Option<UpdateViewInfoPayload_oneof_one_of_group>,
-    pub one_of_sort: ::std::option::Option<UpdateViewInfoPayload_oneof_one_of_sort>,
-    // special fields
-    pub unknown_fields: ::protobuf::UnknownFields,
-    pub cached_size: ::protobuf::CachedSize,
-}
-
-impl<'a> ::std::default::Default for &'a UpdateViewInfoPayload {
-    fn default() -> &'a UpdateViewInfoPayload {
-        <UpdateViewInfoPayload as ::protobuf::Message>::default_instance()
-    }
-}
-
-#[derive(Clone,PartialEq,Debug)]
-pub enum UpdateViewInfoPayload_oneof_one_of_filter {
-    filter(ViewFilter),
-}
-
-#[derive(Clone,PartialEq,Debug)]
-pub enum UpdateViewInfoPayload_oneof_one_of_group {
-    group(ViewGroup),
-}
-
-#[derive(Clone,PartialEq,Debug)]
-pub enum UpdateViewInfoPayload_oneof_one_of_sort {
-    sort(ViewSort),
-}
-
-impl UpdateViewInfoPayload {
-    pub fn new() -> UpdateViewInfoPayload {
-        ::std::default::Default::default()
-    }
-
-    // string view_id = 1;
-
-
-    pub fn get_view_id(&self) -> &str {
-        &self.view_id
-    }
-    pub fn clear_view_id(&mut self) {
-        self.view_id.clear();
-    }
-
-    // Param is passed by value, moved
-    pub fn set_view_id(&mut self, v: ::std::string::String) {
-        self.view_id = v;
-    }
-
-    // Mutable pointer to the field.
-    // If field is not initialized, it is initialized with default value first.
-    pub fn mut_view_id(&mut self) -> &mut ::std::string::String {
-        &mut self.view_id
-    }
-
-    // Take field
-    pub fn take_view_id(&mut self) -> ::std::string::String {
-        ::std::mem::replace(&mut self.view_id, ::std::string::String::new())
-    }
-
-    // .ViewFilter filter = 2;
-
-
-    pub fn get_filter(&self) -> &ViewFilter {
-        match self.one_of_filter {
-            ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_filter::filter(ref v)) => v,
-            _ => <ViewFilter as ::protobuf::Message>::default_instance(),
-        }
-    }
-    pub fn clear_filter(&mut self) {
-        self.one_of_filter = ::std::option::Option::None;
-    }
-
-    pub fn has_filter(&self) -> bool {
-        match self.one_of_filter {
-            ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_filter::filter(..)) => true,
-            _ => false,
-        }
-    }
-
-    // Param is passed by value, moved
-    pub fn set_filter(&mut self, v: ViewFilter) {
-        self.one_of_filter = ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_filter::filter(v))
-    }
-
-    // Mutable pointer to the field.
-    pub fn mut_filter(&mut self) -> &mut ViewFilter {
-        if let ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_filter::filter(_)) = self.one_of_filter {
-        } else {
-            self.one_of_filter = ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_filter::filter(ViewFilter::new()));
-        }
-        match self.one_of_filter {
-            ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_filter::filter(ref mut v)) => v,
-            _ => panic!(),
-        }
-    }
-
-    // Take field
-    pub fn take_filter(&mut self) -> ViewFilter {
-        if self.has_filter() {
-            match self.one_of_filter.take() {
-                ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_filter::filter(v)) => v,
-                _ => panic!(),
-            }
-        } else {
-            ViewFilter::new()
-        }
-    }
-
-    // .ViewGroup group = 3;
-
-
-    pub fn get_group(&self) -> &ViewGroup {
-        match self.one_of_group {
-            ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_group::group(ref v)) => v,
-            _ => <ViewGroup as ::protobuf::Message>::default_instance(),
-        }
-    }
-    pub fn clear_group(&mut self) {
-        self.one_of_group = ::std::option::Option::None;
-    }
-
-    pub fn has_group(&self) -> bool {
-        match self.one_of_group {
-            ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_group::group(..)) => true,
-            _ => false,
-        }
-    }
-
-    // Param is passed by value, moved
-    pub fn set_group(&mut self, v: ViewGroup) {
-        self.one_of_group = ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_group::group(v))
-    }
-
-    // Mutable pointer to the field.
-    pub fn mut_group(&mut self) -> &mut ViewGroup {
-        if let ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_group::group(_)) = self.one_of_group {
-        } else {
-            self.one_of_group = ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_group::group(ViewGroup::new()));
-        }
-        match self.one_of_group {
-            ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_group::group(ref mut v)) => v,
-            _ => panic!(),
-        }
-    }
-
-    // Take field
-    pub fn take_group(&mut self) -> ViewGroup {
-        if self.has_group() {
-            match self.one_of_group.take() {
-                ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_group::group(v)) => v,
-                _ => panic!(),
-            }
-        } else {
-            ViewGroup::new()
-        }
-    }
-
-    // .ViewSort sort = 4;
-
-
-    pub fn get_sort(&self) -> &ViewSort {
-        match self.one_of_sort {
-            ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_sort::sort(ref v)) => v,
-            _ => <ViewSort as ::protobuf::Message>::default_instance(),
-        }
-    }
-    pub fn clear_sort(&mut self) {
-        self.one_of_sort = ::std::option::Option::None;
-    }
-
-    pub fn has_sort(&self) -> bool {
-        match self.one_of_sort {
-            ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_sort::sort(..)) => true,
-            _ => false,
-        }
-    }
-
-    // Param is passed by value, moved
-    pub fn set_sort(&mut self, v: ViewSort) {
-        self.one_of_sort = ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_sort::sort(v))
-    }
-
-    // Mutable pointer to the field.
-    pub fn mut_sort(&mut self) -> &mut ViewSort {
-        if let ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_sort::sort(_)) = self.one_of_sort {
-        } else {
-            self.one_of_sort = ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_sort::sort(ViewSort::new()));
-        }
-        match self.one_of_sort {
-            ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_sort::sort(ref mut v)) => v,
-            _ => panic!(),
-        }
-    }
-
-    // Take field
-    pub fn take_sort(&mut self) -> ViewSort {
-        if self.has_sort() {
-            match self.one_of_sort.take() {
-                ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_sort::sort(v)) => v,
-                _ => panic!(),
-            }
-        } else {
-            ViewSort::new()
-        }
-    }
-}
-
-impl ::protobuf::Message for UpdateViewInfoPayload {
-    fn is_initialized(&self) -> bool {
-        if let Some(UpdateViewInfoPayload_oneof_one_of_filter::filter(ref v)) = self.one_of_filter {
-            if !v.is_initialized() {
-                return false;
-            }
-        }
-        if let Some(UpdateViewInfoPayload_oneof_one_of_group::group(ref v)) = self.one_of_group {
-            if !v.is_initialized() {
-                return false;
-            }
-        }
-        if let Some(UpdateViewInfoPayload_oneof_one_of_sort::sort(ref v)) = self.one_of_sort {
-            if !v.is_initialized() {
-                return false;
-            }
-        }
-        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.view_id)?;
-                },
-                2 => {
-                    if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
-                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
-                    }
-                    self.one_of_filter = ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_filter::filter(is.read_message()?));
-                },
-                3 => {
-                    if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
-                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
-                    }
-                    self.one_of_group = ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_group::group(is.read_message()?));
-                },
-                4 => {
-                    if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
-                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
-                    }
-                    self.one_of_sort = ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_sort::sort(is.read_message()?));
-                },
-                _ => {
-                    ::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.view_id.is_empty() {
-            my_size += ::protobuf::rt::string_size(1, &self.view_id);
-        }
-        if let ::std::option::Option::Some(ref v) = self.one_of_filter {
-            match v {
-                &UpdateViewInfoPayload_oneof_one_of_filter::filter(ref v) => {
-                    let len = v.compute_size();
-                    my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
-                },
-            };
-        }
-        if let ::std::option::Option::Some(ref v) = self.one_of_group {
-            match v {
-                &UpdateViewInfoPayload_oneof_one_of_group::group(ref v) => {
-                    let len = v.compute_size();
-                    my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
-                },
-            };
-        }
-        if let ::std::option::Option::Some(ref v) = self.one_of_sort {
-            match v {
-                &UpdateViewInfoPayload_oneof_one_of_sort::sort(ref v) => {
-                    let len = v.compute_size();
-                    my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
-                },
-            };
-        }
-        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.view_id.is_empty() {
-            os.write_string(1, &self.view_id)?;
-        }
-        if let ::std::option::Option::Some(ref v) = self.one_of_filter {
-            match v {
-                &UpdateViewInfoPayload_oneof_one_of_filter::filter(ref v) => {
-                    os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?;
-                    os.write_raw_varint32(v.get_cached_size())?;
-                    v.write_to_with_cached_sizes(os)?;
-                },
-            };
-        }
-        if let ::std::option::Option::Some(ref v) = self.one_of_group {
-            match v {
-                &UpdateViewInfoPayload_oneof_one_of_group::group(ref v) => {
-                    os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?;
-                    os.write_raw_varint32(v.get_cached_size())?;
-                    v.write_to_with_cached_sizes(os)?;
-                },
-            };
-        }
-        if let ::std::option::Option::Some(ref v) = self.one_of_sort {
-            match v {
-                &UpdateViewInfoPayload_oneof_one_of_sort::sort(ref v) => {
-                    os.write_tag(4, ::protobuf::wire_format::WireTypeLengthDelimited)?;
-                    os.write_raw_varint32(v.get_cached_size())?;
-                    v.write_to_with_cached_sizes(os)?;
-                },
-            };
-        }
-        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<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
-        self
-    }
-
-    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
-        Self::descriptor_static()
-    }
-
-    fn new() -> UpdateViewInfoPayload {
-        UpdateViewInfoPayload::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>(
-                "view_id",
-                |m: &UpdateViewInfoPayload| { &m.view_id },
-                |m: &mut UpdateViewInfoPayload| { &mut m.view_id },
-            ));
-            fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, ViewFilter>(
-                "filter",
-                UpdateViewInfoPayload::has_filter,
-                UpdateViewInfoPayload::get_filter,
-            ));
-            fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, ViewGroup>(
-                "group",
-                UpdateViewInfoPayload::has_group,
-                UpdateViewInfoPayload::get_group,
-            ));
-            fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, ViewSort>(
-                "sort",
-                UpdateViewInfoPayload::has_sort,
-                UpdateViewInfoPayload::get_sort,
-            ));
-            ::protobuf::reflect::MessageDescriptor::new_pb_name::<UpdateViewInfoPayload>(
-                "UpdateViewInfoPayload",
-                fields,
-                file_descriptor_proto()
-            )
-        })
-    }
-
-    fn default_instance() -> &'static UpdateViewInfoPayload {
-        static instance: ::protobuf::rt::LazyV2<UpdateViewInfoPayload> = ::protobuf::rt::LazyV2::INIT;
-        instance.get(UpdateViewInfoPayload::new)
-    }
-}
-
-impl ::protobuf::Clear for UpdateViewInfoPayload {
-    fn clear(&mut self) {
-        self.view_id.clear();
-        self.one_of_filter = ::std::option::Option::None;
-        self.one_of_group = ::std::option::Option::None;
-        self.one_of_sort = ::std::option::Option::None;
-        self.unknown_fields.clear();
-    }
-}
-
-impl ::std::fmt::Debug for UpdateViewInfoPayload {
-    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
-        ::protobuf::text_format::fmt(self, f)
-    }
-}
-
-impl ::protobuf::reflect::ProtobufValue for UpdateViewInfoPayload {
-    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
-        ::protobuf::reflect::ReflectValueRef::Message(self)
-    }
-}
-
 static file_descriptor_proto_data: &'static [u8] = b"\
-    \n\x0fview_info.proto\x1a\nview.proto\"\xe8\x01\n\x08ViewInfo\x12\x0e\n\
+    \n\x0fview_info.proto\x1a\nview.proto\"\xda\x01\n\x08ViewInfo\x12\x0e\n\
     \x02id\x18\x01\x20\x01(\tR\x02id\x12\x20\n\x0cbelong_to_id\x18\x02\x20\
     \x01(\tR\nbelongToId\x12\x12\n\x04name\x18\x03\x20\x01(\tR\x04name\x12\
     \x12\n\x04desc\x18\x04\x20\x01(\tR\x04desc\x12*\n\tdata_type\x18\x05\x20\
     \x01(\x0e2\r.ViewDataTypeR\x08dataType\x12-\n\nbelongings\x18\x06\x20\
-    \x01(\x0b2\r.RepeatedViewR\nbelongings\x12'\n\x08ext_data\x18\x07\x20\
-    \x01(\x0b2\x0c.ViewExtDataR\x07extData\"s\n\x0bViewExtData\x12#\n\x06fil\
-    ter\x18\x01\x20\x01(\x0b2\x0b.ViewFilterR\x06filter\x12\x20\n\x05group\
-    \x18\x02\x20\x01(\x0b2\n.ViewGroupR\x05group\x12\x1d\n\x04sort\x18\x03\
-    \x20\x01(\x0b2\t.ViewSortR\x04sort\")\n\nViewFilter\x12\x1b\n\tobject_id\
-    \x18\x01\x20\x01(\tR\x08objectId\"\x82\x01\n\tViewGroup\x12&\n\x0fgroup_\
-    object_id\x18\x01\x20\x01(\tR\rgroupObjectId\x12/\n\x13sub_group_object_\
-    id\x18\x02\x20\x01(\tH\0R\x10subGroupObjectIdB\x1c\n\x1aone_of_sub_group\
-    _object_id\"'\n\x08ViewSort\x12\x1b\n\tobject_id\x18\x01\x20\x01(\tR\x08\
-    objectId\"\xcc\x01\n\x15UpdateViewInfoPayload\x12\x17\n\x07view_id\x18\
-    \x01\x20\x01(\tR\x06viewId\x12%\n\x06filter\x18\x02\x20\x01(\x0b2\x0b.Vi\
-    ewFilterH\0R\x06filter\x12\"\n\x05group\x18\x03\x20\x01(\x0b2\n.ViewGrou\
-    pH\x01R\x05group\x12\x1f\n\x04sort\x18\x04\x20\x01(\x0b2\t.ViewSortH\x02\
-    R\x04sortB\x0f\n\rone_of_filterB\x0e\n\x0cone_of_groupB\r\n\x0bone_of_so\
-    rtb\x06proto3\
+    \x01(\x0b2\r.RepeatedViewR\nbelongings\x12\x19\n\x08ext_data\x18\x07\x20\
+    \x01(\tR\x07extDatab\x06proto3\
 ";
 
 static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

+ 1 - 22
shared-lib/flowy-folder-data-model/src/protobuf/proto/view_info.proto

@@ -8,26 +8,5 @@ message ViewInfo {
     string desc = 4;
     ViewDataType data_type = 5;
     RepeatedView belongings = 6;
-    ViewExtData ext_data = 7;
-}
-message ViewExtData {
-    ViewFilter filter = 1;
-    ViewGroup group = 2;
-    ViewSort sort = 3;
-}
-message ViewFilter {
-    string object_id = 1;
-}
-message ViewGroup {
-    string group_object_id = 1;
-    oneof one_of_sub_group_object_id { string sub_group_object_id = 2; };
-}
-message ViewSort {
-    string object_id = 1;
-}
-message UpdateViewInfoPayload {
-    string view_id = 1;
-    oneof one_of_filter { ViewFilter filter = 2; };
-    oneof one_of_group { ViewGroup group = 3; };
-    oneof one_of_sort { ViewSort sort = 4; };
+    string ext_data = 7;
 }

+ 0 - 0
shared-lib/flowy-folder-data-model/src/revision/app.rs → shared-lib/flowy-folder-data-model/src/revision/app_rev.rs


+ 8 - 8
shared-lib/flowy-folder-data-model/src/revision/mod.rs

@@ -1,9 +1,9 @@
-mod app;
-mod trash;
-mod view;
-mod workspace;
+mod app_rev;
+mod trash_rev;
+mod view_rev;
+mod workspace_rev;
 
-pub use app::*;
-pub use trash::*;
-pub use view::*;
-pub use workspace::*;
+pub use app_rev::*;
+pub use trash_rev::*;
+pub use view_rev::*;
+pub use workspace_rev::*;

+ 0 - 0
shared-lib/flowy-folder-data-model/src/revision/trash.rs → shared-lib/flowy-folder-data-model/src/revision/trash_rev.rs


+ 0 - 142
shared-lib/flowy-folder-data-model/src/revision/view.rs

@@ -1,142 +0,0 @@
-use crate::entities::view::{View, ViewDataType};
-use crate::entities::{RepeatedView, TrashType, ViewExtData, ViewFilter, ViewGroup, ViewSort};
-use crate::revision::TrashRevision;
-use serde::{Deserialize, Serialize};
-
-#[derive(Default, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
-pub struct ViewRevision {
-    pub id: String,
-
-    pub belong_to_id: String,
-
-    pub name: String,
-
-    pub desc: String,
-
-    #[serde(default)]
-    pub data_type: ViewDataType,
-
-    pub version: i64,
-
-    pub belongings: Vec<ViewRevision>,
-
-    pub modified_time: i64,
-
-    pub create_time: i64,
-
-    #[serde(default)]
-    pub ext_data: String,
-
-    #[serde(default)]
-    pub thumbnail: String,
-
-    #[serde(default = "default_plugin_type")]
-    pub plugin_type: i32,
-}
-
-fn default_plugin_type() -> i32 {
-    0
-}
-
-impl std::convert::From<ViewRevision> for View {
-    fn from(view_serde: ViewRevision) -> Self {
-        View {
-            id: view_serde.id,
-            belong_to_id: view_serde.belong_to_id,
-            name: view_serde.name,
-            data_type: view_serde.data_type,
-            modified_time: view_serde.modified_time,
-            create_time: view_serde.create_time,
-            plugin_type: view_serde.plugin_type,
-        }
-    }
-}
-
-impl std::convert::From<ViewRevision> for TrashRevision {
-    fn from(view_rev: ViewRevision) -> Self {
-        TrashRevision {
-            id: view_rev.id,
-            name: view_rev.name,
-            modified_time: view_rev.modified_time,
-            create_time: view_rev.create_time,
-            ty: TrashType::TrashView,
-        }
-    }
-}
-
-#[derive(Serialize, Deserialize)]
-pub struct ViewExtDataRevision {
-    pub filter: ViewFilterRevision,
-    pub group: ViewGroupRevision,
-    pub sort: ViewSortRevision,
-}
-
-#[derive(Serialize, Deserialize)]
-pub struct ViewFilterRevision {
-    pub field_id: String,
-}
-
-#[derive(Serialize, Deserialize)]
-pub struct ViewGroupRevision {
-    pub group_field_id: String,
-    pub sub_group_field_id: Option<String>,
-}
-
-#[derive(Serialize, Deserialize)]
-pub struct ViewSortRevision {
-    field_id: String,
-}
-
-impl std::convert::From<String> for ViewExtData {
-    fn from(s: String) -> Self {
-        match serde_json::from_str::<ViewExtDataRevision>(&s) {
-            Ok(data) => data.into(),
-            Err(err) => {
-                log::error!("{:?}", err);
-                ViewExtData::default()
-            }
-        }
-    }
-}
-
-impl std::convert::From<ViewExtDataRevision> for ViewExtData {
-    fn from(rev: ViewExtDataRevision) -> Self {
-        ViewExtData {
-            filter: rev.filter.into(),
-            group: rev.group.into(),
-            sort: rev.sort.into(),
-        }
-    }
-}
-
-impl std::convert::From<ViewFilterRevision> for ViewFilter {
-    fn from(rev: ViewFilterRevision) -> Self {
-        ViewFilter {
-            object_id: rev.field_id,
-        }
-    }
-}
-
-impl std::convert::From<ViewGroupRevision> for ViewGroup {
-    fn from(rev: ViewGroupRevision) -> Self {
-        ViewGroup {
-            group_object_id: rev.group_field_id,
-            sub_group_object_id: rev.sub_group_field_id,
-        }
-    }
-}
-
-impl std::convert::From<ViewSortRevision> for ViewSort {
-    fn from(rev: ViewSortRevision) -> Self {
-        ViewSort {
-            object_id: rev.field_id,
-        }
-    }
-}
-
-impl std::convert::From<Vec<ViewRevision>> for RepeatedView {
-    fn from(values: Vec<ViewRevision>) -> Self {
-        let items = values.into_iter().map(|value| value.into()).collect::<Vec<View>>();
-        RepeatedView { items }
-    }
-}

+ 71 - 0
shared-lib/flowy-folder-data-model/src/revision/view_rev.rs

@@ -0,0 +1,71 @@
+use crate::entities::view::{View, ViewDataType};
+use crate::entities::{RepeatedView, TrashType};
+use crate::revision::TrashRevision;
+use serde::{Deserialize, Serialize};
+
+#[derive(Default, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
+pub struct ViewRevision {
+    pub id: String,
+
+    pub belong_to_id: String,
+
+    pub name: String,
+
+    pub desc: String,
+
+    #[serde(default)]
+    pub data_type: ViewDataType,
+
+    pub version: i64,
+
+    pub belongings: Vec<ViewRevision>,
+
+    pub modified_time: i64,
+
+    pub create_time: i64,
+
+    #[serde(default)]
+    pub ext_data: String,
+
+    #[serde(default)]
+    pub thumbnail: String,
+
+    #[serde(default = "default_plugin_type")]
+    pub plugin_type: i32,
+}
+
+fn default_plugin_type() -> i32 {
+    0
+}
+
+impl std::convert::From<ViewRevision> for View {
+    fn from(view_serde: ViewRevision) -> Self {
+        View {
+            id: view_serde.id,
+            belong_to_id: view_serde.belong_to_id,
+            name: view_serde.name,
+            data_type: view_serde.data_type,
+            modified_time: view_serde.modified_time,
+            create_time: view_serde.create_time,
+            plugin_type: view_serde.plugin_type,
+        }
+    }
+}
+
+impl std::convert::From<ViewRevision> for TrashRevision {
+    fn from(view_rev: ViewRevision) -> Self {
+        TrashRevision {
+            id: view_rev.id,
+            name: view_rev.name,
+            modified_time: view_rev.modified_time,
+            create_time: view_rev.create_time,
+            ty: TrashType::TrashView,
+        }
+    }
+}
+impl std::convert::From<Vec<ViewRevision>> for RepeatedView {
+    fn from(values: Vec<ViewRevision>) -> Self {
+        let items = values.into_iter().map(|value| value.into()).collect::<Vec<View>>();
+        RepeatedView { items }
+    }
+}

+ 0 - 0
shared-lib/flowy-folder-data-model/src/revision/workspace.rs → shared-lib/flowy-folder-data-model/src/revision/workspace_rev.rs


+ 1 - 3
shared-lib/flowy-grid-data-model/src/entities/field.rs

@@ -1,10 +1,8 @@
 use crate::parser::NotEmptyStr;
-use crate::revision::{CellRevision, FieldRevision, RowMetaChangeset, RowRevision};
+use crate::revision::FieldRevision;
 use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
 use flowy_error_code::ErrorCode;
-
 use serde_repr::*;
-
 use strum_macros::{Display, EnumCount as EnumCountMacro, EnumIter, EnumString};
 
 #[derive(Debug, Clone, Default, ProtoBuf)]

+ 1 - 1
shared-lib/flowy-grid-data-model/src/entities/grid.rs

@@ -1,6 +1,6 @@
 use crate::entities::FieldOrder;
 use crate::parser::NotEmptyStr;
-use crate::revision::{CellRevision, FieldRevision, RowMetaChangeset, RowRevision};
+use crate::revision::RowRevision;
 use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
 use flowy_error_code::ErrorCode;
 

+ 91 - 0
shared-lib/flowy-grid-data-model/src/entities/grid_info.rs

@@ -0,0 +1,91 @@
+use crate::parser::{NotEmptyStr, ViewFilterParser, ViewGroupParser, ViewSortParser};
+use flowy_derive::ProtoBuf;
+use flowy_error_code::ErrorCode;
+use std::convert::TryInto;
+
+#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
+pub struct ViewExtData {
+    #[pb(index = 1)]
+    pub filter: ViewFilter,
+
+    #[pb(index = 2)]
+    pub group: ViewGroup,
+
+    #[pb(index = 3)]
+    pub sort: ViewSort,
+}
+
+#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
+pub struct ViewFilter {
+    #[pb(index = 1, one_of)]
+    pub field_id: Option<String>,
+}
+
+#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
+pub struct ViewGroup {
+    #[pb(index = 1, one_of)]
+    pub group_field_id: Option<String>,
+
+    #[pb(index = 2, one_of)]
+    pub sub_group_field_id: Option<String>,
+}
+
+#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
+pub struct ViewSort {
+    #[pb(index = 1, one_of)]
+    pub field_id: Option<String>,
+}
+
+#[derive(Default, ProtoBuf)]
+pub struct GridInfoChangesetPayload {
+    #[pb(index = 1)]
+    pub grid_id: String,
+
+    #[pb(index = 2, one_of)]
+    pub filter: Option<ViewFilter>,
+
+    #[pb(index = 3, one_of)]
+    pub group: Option<ViewGroup>,
+
+    #[pb(index = 4, one_of)]
+    pub sort: Option<ViewSort>,
+}
+
+pub struct GridInfoChangesetParams {
+    pub view_id: String,
+    pub filter: Option<ViewFilter>,
+    pub group: Option<ViewGroup>,
+    pub sort: Option<ViewSort>,
+}
+
+impl TryInto<GridInfoChangesetParams> for GridInfoChangesetPayload {
+    type Error = ErrorCode;
+
+    fn try_into(self) -> Result<GridInfoChangesetParams, Self::Error> {
+        let view_id = NotEmptyStr::parse(self.grid_id)
+            .map_err(|_| ErrorCode::FieldIdIsEmpty)?
+            .0;
+
+        let filter = match self.filter {
+            None => None,
+            Some(filter) => Some(ViewFilterParser::parse(filter)?),
+        };
+
+        let group = match self.group {
+            None => None,
+            Some(group) => Some(ViewGroupParser::parse(group)?),
+        };
+
+        let sort = match self.sort {
+            None => None,
+            Some(sort) => Some(ViewSortParser::parse(sort)?),
+        };
+
+        Ok(GridInfoChangesetParams {
+            view_id,
+            filter,
+            group,
+            sort,
+        })
+    }
+}

+ 2 - 0
shared-lib/flowy-grid-data-model/src/entities/mod.rs

@@ -1,5 +1,7 @@
 mod field;
 mod grid;
+mod grid_info;
 
 pub use field::*;
 pub use grid::*;
+pub use grid_info::*;

+ 58 - 0
shared-lib/flowy-grid-data-model/src/parser/grid_info_parser.rs

@@ -0,0 +1,58 @@
+use crate::entities::{ViewFilter, ViewGroup, ViewSort};
+use crate::parser::NotEmptyStr;
+use flowy_error_code::ErrorCode;
+
+pub struct ViewFilterParser(pub ViewFilter);
+
+impl ViewFilterParser {
+    pub fn parse(value: ViewFilter) -> Result<ViewFilter, ErrorCode> {
+        let field_id = match value.field_id {
+            None => None,
+            Some(field_id) => Some(NotEmptyStr::parse(field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?.0),
+        };
+
+        Ok(ViewFilter { field_id })
+    }
+}
+
+pub struct ViewGroupParser(pub ViewGroup);
+
+impl ViewGroupParser {
+    pub fn parse(value: ViewGroup) -> Result<ViewGroup, ErrorCode> {
+        let group_field_id = match value.group_field_id {
+            None => None,
+            Some(group_field_id) => Some(
+                NotEmptyStr::parse(group_field_id)
+                    .map_err(|_| ErrorCode::FieldIdIsEmpty)?
+                    .0,
+            ),
+        };
+
+        let sub_group_field_id = match value.sub_group_field_id {
+            None => None,
+            Some(sub_group_field_id) => Some(
+                NotEmptyStr::parse(sub_group_field_id)
+                    .map_err(|_| ErrorCode::FieldIdIsEmpty)?
+                    .0,
+            ),
+        };
+
+        Ok(ViewGroup {
+            group_field_id,
+            sub_group_field_id,
+        })
+    }
+}
+
+pub struct ViewSortParser(pub ViewSort);
+
+impl ViewSortParser {
+    pub fn parse(value: ViewSort) -> Result<ViewSort, ErrorCode> {
+        let field_id = match value.field_id {
+            None => None,
+            Some(field_id) => Some(NotEmptyStr::parse(field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?.0),
+        };
+
+        Ok(ViewSort { field_id })
+    }
+}

+ 2 - 0
shared-lib/flowy-grid-data-model/src/parser/mod.rs

@@ -1,3 +1,5 @@
+mod grid_info_parser;
 mod str_parser;
 
+pub use grid_info_parser::*;
 pub use str_parser::*;

+ 1444 - 0
shared-lib/flowy-grid-data-model/src/protobuf/model/grid_info.rs

@@ -0,0 +1,1444 @@
+// This file is generated by rust-protobuf 2.25.2. Do not edit
+// @generated
+
+// https://github.com/rust-lang/rust-clippy/issues/702
+#![allow(unknown_lints)]
+#![allow(clippy::all)]
+
+#![allow(unused_attributes)]
+#![cfg_attr(rustfmt, rustfmt::skip)]
+
+#![allow(box_pointers)]
+#![allow(dead_code)]
+#![allow(missing_docs)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+#![allow(non_upper_case_globals)]
+#![allow(trivial_casts)]
+#![allow(unused_imports)]
+#![allow(unused_results)]
+//! Generated file from `grid_info.proto`
+
+/// Generated files are compatible only with the same version
+/// of protobuf runtime.
+// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_25_2;
+
+#[derive(PartialEq,Clone,Default)]
+pub struct ViewExtData {
+    // message fields
+    pub filter: ::protobuf::SingularPtrField<ViewFilter>,
+    pub group: ::protobuf::SingularPtrField<ViewGroup>,
+    pub sort: ::protobuf::SingularPtrField<ViewSort>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a ViewExtData {
+    fn default() -> &'a ViewExtData {
+        <ViewExtData as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl ViewExtData {
+    pub fn new() -> ViewExtData {
+        ::std::default::Default::default()
+    }
+
+    // .ViewFilter filter = 1;
+
+
+    pub fn get_filter(&self) -> &ViewFilter {
+        self.filter.as_ref().unwrap_or_else(|| <ViewFilter as ::protobuf::Message>::default_instance())
+    }
+    pub fn clear_filter(&mut self) {
+        self.filter.clear();
+    }
+
+    pub fn has_filter(&self) -> bool {
+        self.filter.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_filter(&mut self, v: ViewFilter) {
+        self.filter = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_filter(&mut self) -> &mut ViewFilter {
+        if self.filter.is_none() {
+            self.filter.set_default();
+        }
+        self.filter.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_filter(&mut self) -> ViewFilter {
+        self.filter.take().unwrap_or_else(|| ViewFilter::new())
+    }
+
+    // .ViewGroup group = 2;
+
+
+    pub fn get_group(&self) -> &ViewGroup {
+        self.group.as_ref().unwrap_or_else(|| <ViewGroup as ::protobuf::Message>::default_instance())
+    }
+    pub fn clear_group(&mut self) {
+        self.group.clear();
+    }
+
+    pub fn has_group(&self) -> bool {
+        self.group.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_group(&mut self, v: ViewGroup) {
+        self.group = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_group(&mut self) -> &mut ViewGroup {
+        if self.group.is_none() {
+            self.group.set_default();
+        }
+        self.group.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_group(&mut self) -> ViewGroup {
+        self.group.take().unwrap_or_else(|| ViewGroup::new())
+    }
+
+    // .ViewSort sort = 3;
+
+
+    pub fn get_sort(&self) -> &ViewSort {
+        self.sort.as_ref().unwrap_or_else(|| <ViewSort as ::protobuf::Message>::default_instance())
+    }
+    pub fn clear_sort(&mut self) {
+        self.sort.clear();
+    }
+
+    pub fn has_sort(&self) -> bool {
+        self.sort.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_sort(&mut self, v: ViewSort) {
+        self.sort = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_sort(&mut self) -> &mut ViewSort {
+        if self.sort.is_none() {
+            self.sort.set_default();
+        }
+        self.sort.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_sort(&mut self) -> ViewSort {
+        self.sort.take().unwrap_or_else(|| ViewSort::new())
+    }
+}
+
+impl ::protobuf::Message for ViewExtData {
+    fn is_initialized(&self) -> bool {
+        for v in &self.filter {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        for v in &self.group {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        for v in &self.sort {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        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_message_into(wire_type, is, &mut self.filter)?;
+                },
+                2 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.group)?;
+                },
+                3 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.sort)?;
+                },
+                _ => {
+                    ::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 let Some(ref v) = self.filter.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        if let Some(ref v) = self.group.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        if let Some(ref v) = self.sort.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        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 let Some(ref v) = self.filter.as_ref() {
+            os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        if let Some(ref v) = self.group.as_ref() {
+            os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        if let Some(ref v) = self.sort.as_ref() {
+            os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        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<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> ViewExtData {
+        ViewExtData::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_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<ViewFilter>>(
+                "filter",
+                |m: &ViewExtData| { &m.filter },
+                |m: &mut ViewExtData| { &mut m.filter },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<ViewGroup>>(
+                "group",
+                |m: &ViewExtData| { &m.group },
+                |m: &mut ViewExtData| { &mut m.group },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<ViewSort>>(
+                "sort",
+                |m: &ViewExtData| { &m.sort },
+                |m: &mut ViewExtData| { &mut m.sort },
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<ViewExtData>(
+                "ViewExtData",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static ViewExtData {
+        static instance: ::protobuf::rt::LazyV2<ViewExtData> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(ViewExtData::new)
+    }
+}
+
+impl ::protobuf::Clear for ViewExtData {
+    fn clear(&mut self) {
+        self.filter.clear();
+        self.group.clear();
+        self.sort.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for ViewExtData {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for ViewExtData {
+    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+        ::protobuf::reflect::ReflectValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct ViewFilter {
+    // message oneof groups
+    pub one_of_field_id: ::std::option::Option<ViewFilter_oneof_one_of_field_id>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a ViewFilter {
+    fn default() -> &'a ViewFilter {
+        <ViewFilter as ::protobuf::Message>::default_instance()
+    }
+}
+
+#[derive(Clone,PartialEq,Debug)]
+pub enum ViewFilter_oneof_one_of_field_id {
+    field_id(::std::string::String),
+}
+
+impl ViewFilter {
+    pub fn new() -> ViewFilter {
+        ::std::default::Default::default()
+    }
+
+    // string field_id = 1;
+
+
+    pub fn get_field_id(&self) -> &str {
+        match self.one_of_field_id {
+            ::std::option::Option::Some(ViewFilter_oneof_one_of_field_id::field_id(ref v)) => v,
+            _ => "",
+        }
+    }
+    pub fn clear_field_id(&mut self) {
+        self.one_of_field_id = ::std::option::Option::None;
+    }
+
+    pub fn has_field_id(&self) -> bool {
+        match self.one_of_field_id {
+            ::std::option::Option::Some(ViewFilter_oneof_one_of_field_id::field_id(..)) => true,
+            _ => false,
+        }
+    }
+
+    // Param is passed by value, moved
+    pub fn set_field_id(&mut self, v: ::std::string::String) {
+        self.one_of_field_id = ::std::option::Option::Some(ViewFilter_oneof_one_of_field_id::field_id(v))
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_field_id(&mut self) -> &mut ::std::string::String {
+        if let ::std::option::Option::Some(ViewFilter_oneof_one_of_field_id::field_id(_)) = self.one_of_field_id {
+        } else {
+            self.one_of_field_id = ::std::option::Option::Some(ViewFilter_oneof_one_of_field_id::field_id(::std::string::String::new()));
+        }
+        match self.one_of_field_id {
+            ::std::option::Option::Some(ViewFilter_oneof_one_of_field_id::field_id(ref mut v)) => v,
+            _ => panic!(),
+        }
+    }
+
+    // Take field
+    pub fn take_field_id(&mut self) -> ::std::string::String {
+        if self.has_field_id() {
+            match self.one_of_field_id.take() {
+                ::std::option::Option::Some(ViewFilter_oneof_one_of_field_id::field_id(v)) => v,
+                _ => panic!(),
+            }
+        } else {
+            ::std::string::String::new()
+        }
+    }
+}
+
+impl ::protobuf::Message for ViewFilter {
+    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 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    self.one_of_field_id = ::std::option::Option::Some(ViewFilter_oneof_one_of_field_id::field_id(is.read_string()?));
+                },
+                _ => {
+                    ::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 let ::std::option::Option::Some(ref v) = self.one_of_field_id {
+            match v {
+                &ViewFilter_oneof_one_of_field_id::field_id(ref v) => {
+                    my_size += ::protobuf::rt::string_size(1, &v);
+                },
+            };
+        }
+        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 let ::std::option::Option::Some(ref v) = self.one_of_field_id {
+            match v {
+                &ViewFilter_oneof_one_of_field_id::field_id(ref v) => {
+                    os.write_string(1, v)?;
+                },
+            };
+        }
+        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<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> ViewFilter {
+        ViewFilter::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_singular_string_accessor::<_>(
+                "field_id",
+                ViewFilter::has_field_id,
+                ViewFilter::get_field_id,
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<ViewFilter>(
+                "ViewFilter",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static ViewFilter {
+        static instance: ::protobuf::rt::LazyV2<ViewFilter> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(ViewFilter::new)
+    }
+}
+
+impl ::protobuf::Clear for ViewFilter {
+    fn clear(&mut self) {
+        self.one_of_field_id = ::std::option::Option::None;
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for ViewFilter {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for ViewFilter {
+    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+        ::protobuf::reflect::ReflectValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct ViewGroup {
+    // message oneof groups
+    pub one_of_group_field_id: ::std::option::Option<ViewGroup_oneof_one_of_group_field_id>,
+    pub one_of_sub_group_field_id: ::std::option::Option<ViewGroup_oneof_one_of_sub_group_field_id>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a ViewGroup {
+    fn default() -> &'a ViewGroup {
+        <ViewGroup as ::protobuf::Message>::default_instance()
+    }
+}
+
+#[derive(Clone,PartialEq,Debug)]
+pub enum ViewGroup_oneof_one_of_group_field_id {
+    group_field_id(::std::string::String),
+}
+
+#[derive(Clone,PartialEq,Debug)]
+pub enum ViewGroup_oneof_one_of_sub_group_field_id {
+    sub_group_field_id(::std::string::String),
+}
+
+impl ViewGroup {
+    pub fn new() -> ViewGroup {
+        ::std::default::Default::default()
+    }
+
+    // string group_field_id = 1;
+
+
+    pub fn get_group_field_id(&self) -> &str {
+        match self.one_of_group_field_id {
+            ::std::option::Option::Some(ViewGroup_oneof_one_of_group_field_id::group_field_id(ref v)) => v,
+            _ => "",
+        }
+    }
+    pub fn clear_group_field_id(&mut self) {
+        self.one_of_group_field_id = ::std::option::Option::None;
+    }
+
+    pub fn has_group_field_id(&self) -> bool {
+        match self.one_of_group_field_id {
+            ::std::option::Option::Some(ViewGroup_oneof_one_of_group_field_id::group_field_id(..)) => true,
+            _ => false,
+        }
+    }
+
+    // Param is passed by value, moved
+    pub fn set_group_field_id(&mut self, v: ::std::string::String) {
+        self.one_of_group_field_id = ::std::option::Option::Some(ViewGroup_oneof_one_of_group_field_id::group_field_id(v))
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_group_field_id(&mut self) -> &mut ::std::string::String {
+        if let ::std::option::Option::Some(ViewGroup_oneof_one_of_group_field_id::group_field_id(_)) = self.one_of_group_field_id {
+        } else {
+            self.one_of_group_field_id = ::std::option::Option::Some(ViewGroup_oneof_one_of_group_field_id::group_field_id(::std::string::String::new()));
+        }
+        match self.one_of_group_field_id {
+            ::std::option::Option::Some(ViewGroup_oneof_one_of_group_field_id::group_field_id(ref mut v)) => v,
+            _ => panic!(),
+        }
+    }
+
+    // Take field
+    pub fn take_group_field_id(&mut self) -> ::std::string::String {
+        if self.has_group_field_id() {
+            match self.one_of_group_field_id.take() {
+                ::std::option::Option::Some(ViewGroup_oneof_one_of_group_field_id::group_field_id(v)) => v,
+                _ => panic!(),
+            }
+        } else {
+            ::std::string::String::new()
+        }
+    }
+
+    // string sub_group_field_id = 2;
+
+
+    pub fn get_sub_group_field_id(&self) -> &str {
+        match self.one_of_sub_group_field_id {
+            ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_field_id::sub_group_field_id(ref v)) => v,
+            _ => "",
+        }
+    }
+    pub fn clear_sub_group_field_id(&mut self) {
+        self.one_of_sub_group_field_id = ::std::option::Option::None;
+    }
+
+    pub fn has_sub_group_field_id(&self) -> bool {
+        match self.one_of_sub_group_field_id {
+            ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_field_id::sub_group_field_id(..)) => true,
+            _ => false,
+        }
+    }
+
+    // Param is passed by value, moved
+    pub fn set_sub_group_field_id(&mut self, v: ::std::string::String) {
+        self.one_of_sub_group_field_id = ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_field_id::sub_group_field_id(v))
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_sub_group_field_id(&mut self) -> &mut ::std::string::String {
+        if let ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_field_id::sub_group_field_id(_)) = self.one_of_sub_group_field_id {
+        } else {
+            self.one_of_sub_group_field_id = ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_field_id::sub_group_field_id(::std::string::String::new()));
+        }
+        match self.one_of_sub_group_field_id {
+            ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_field_id::sub_group_field_id(ref mut v)) => v,
+            _ => panic!(),
+        }
+    }
+
+    // Take field
+    pub fn take_sub_group_field_id(&mut self) -> ::std::string::String {
+        if self.has_sub_group_field_id() {
+            match self.one_of_sub_group_field_id.take() {
+                ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_field_id::sub_group_field_id(v)) => v,
+                _ => panic!(),
+            }
+        } else {
+            ::std::string::String::new()
+        }
+    }
+}
+
+impl ::protobuf::Message for ViewGroup {
+    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 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    self.one_of_group_field_id = ::std::option::Option::Some(ViewGroup_oneof_one_of_group_field_id::group_field_id(is.read_string()?));
+                },
+                2 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    self.one_of_sub_group_field_id = ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_field_id::sub_group_field_id(is.read_string()?));
+                },
+                _ => {
+                    ::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 let ::std::option::Option::Some(ref v) = self.one_of_group_field_id {
+            match v {
+                &ViewGroup_oneof_one_of_group_field_id::group_field_id(ref v) => {
+                    my_size += ::protobuf::rt::string_size(1, &v);
+                },
+            };
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_sub_group_field_id {
+            match v {
+                &ViewGroup_oneof_one_of_sub_group_field_id::sub_group_field_id(ref v) => {
+                    my_size += ::protobuf::rt::string_size(2, &v);
+                },
+            };
+        }
+        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 let ::std::option::Option::Some(ref v) = self.one_of_group_field_id {
+            match v {
+                &ViewGroup_oneof_one_of_group_field_id::group_field_id(ref v) => {
+                    os.write_string(1, v)?;
+                },
+            };
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_sub_group_field_id {
+            match v {
+                &ViewGroup_oneof_one_of_sub_group_field_id::sub_group_field_id(ref v) => {
+                    os.write_string(2, v)?;
+                },
+            };
+        }
+        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<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> ViewGroup {
+        ViewGroup::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_singular_string_accessor::<_>(
+                "group_field_id",
+                ViewGroup::has_group_field_id,
+                ViewGroup::get_group_field_id,
+            ));
+            fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>(
+                "sub_group_field_id",
+                ViewGroup::has_sub_group_field_id,
+                ViewGroup::get_sub_group_field_id,
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<ViewGroup>(
+                "ViewGroup",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static ViewGroup {
+        static instance: ::protobuf::rt::LazyV2<ViewGroup> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(ViewGroup::new)
+    }
+}
+
+impl ::protobuf::Clear for ViewGroup {
+    fn clear(&mut self) {
+        self.one_of_group_field_id = ::std::option::Option::None;
+        self.one_of_sub_group_field_id = ::std::option::Option::None;
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for ViewGroup {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for ViewGroup {
+    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+        ::protobuf::reflect::ReflectValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct ViewSort {
+    // message oneof groups
+    pub one_of_field_id: ::std::option::Option<ViewSort_oneof_one_of_field_id>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a ViewSort {
+    fn default() -> &'a ViewSort {
+        <ViewSort as ::protobuf::Message>::default_instance()
+    }
+}
+
+#[derive(Clone,PartialEq,Debug)]
+pub enum ViewSort_oneof_one_of_field_id {
+    field_id(::std::string::String),
+}
+
+impl ViewSort {
+    pub fn new() -> ViewSort {
+        ::std::default::Default::default()
+    }
+
+    // string field_id = 1;
+
+
+    pub fn get_field_id(&self) -> &str {
+        match self.one_of_field_id {
+            ::std::option::Option::Some(ViewSort_oneof_one_of_field_id::field_id(ref v)) => v,
+            _ => "",
+        }
+    }
+    pub fn clear_field_id(&mut self) {
+        self.one_of_field_id = ::std::option::Option::None;
+    }
+
+    pub fn has_field_id(&self) -> bool {
+        match self.one_of_field_id {
+            ::std::option::Option::Some(ViewSort_oneof_one_of_field_id::field_id(..)) => true,
+            _ => false,
+        }
+    }
+
+    // Param is passed by value, moved
+    pub fn set_field_id(&mut self, v: ::std::string::String) {
+        self.one_of_field_id = ::std::option::Option::Some(ViewSort_oneof_one_of_field_id::field_id(v))
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_field_id(&mut self) -> &mut ::std::string::String {
+        if let ::std::option::Option::Some(ViewSort_oneof_one_of_field_id::field_id(_)) = self.one_of_field_id {
+        } else {
+            self.one_of_field_id = ::std::option::Option::Some(ViewSort_oneof_one_of_field_id::field_id(::std::string::String::new()));
+        }
+        match self.one_of_field_id {
+            ::std::option::Option::Some(ViewSort_oneof_one_of_field_id::field_id(ref mut v)) => v,
+            _ => panic!(),
+        }
+    }
+
+    // Take field
+    pub fn take_field_id(&mut self) -> ::std::string::String {
+        if self.has_field_id() {
+            match self.one_of_field_id.take() {
+                ::std::option::Option::Some(ViewSort_oneof_one_of_field_id::field_id(v)) => v,
+                _ => panic!(),
+            }
+        } else {
+            ::std::string::String::new()
+        }
+    }
+}
+
+impl ::protobuf::Message for ViewSort {
+    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 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    self.one_of_field_id = ::std::option::Option::Some(ViewSort_oneof_one_of_field_id::field_id(is.read_string()?));
+                },
+                _ => {
+                    ::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 let ::std::option::Option::Some(ref v) = self.one_of_field_id {
+            match v {
+                &ViewSort_oneof_one_of_field_id::field_id(ref v) => {
+                    my_size += ::protobuf::rt::string_size(1, &v);
+                },
+            };
+        }
+        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 let ::std::option::Option::Some(ref v) = self.one_of_field_id {
+            match v {
+                &ViewSort_oneof_one_of_field_id::field_id(ref v) => {
+                    os.write_string(1, v)?;
+                },
+            };
+        }
+        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<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> ViewSort {
+        ViewSort::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_singular_string_accessor::<_>(
+                "field_id",
+                ViewSort::has_field_id,
+                ViewSort::get_field_id,
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<ViewSort>(
+                "ViewSort",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static ViewSort {
+        static instance: ::protobuf::rt::LazyV2<ViewSort> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(ViewSort::new)
+    }
+}
+
+impl ::protobuf::Clear for ViewSort {
+    fn clear(&mut self) {
+        self.one_of_field_id = ::std::option::Option::None;
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for ViewSort {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for ViewSort {
+    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+        ::protobuf::reflect::ReflectValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct GridInfoChangesetPayload {
+    // message fields
+    pub grid_id: ::std::string::String,
+    // message oneof groups
+    pub one_of_filter: ::std::option::Option<GridInfoChangesetPayload_oneof_one_of_filter>,
+    pub one_of_group: ::std::option::Option<GridInfoChangesetPayload_oneof_one_of_group>,
+    pub one_of_sort: ::std::option::Option<GridInfoChangesetPayload_oneof_one_of_sort>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a GridInfoChangesetPayload {
+    fn default() -> &'a GridInfoChangesetPayload {
+        <GridInfoChangesetPayload as ::protobuf::Message>::default_instance()
+    }
+}
+
+#[derive(Clone,PartialEq,Debug)]
+pub enum GridInfoChangesetPayload_oneof_one_of_filter {
+    filter(ViewFilter),
+}
+
+#[derive(Clone,PartialEq,Debug)]
+pub enum GridInfoChangesetPayload_oneof_one_of_group {
+    group(ViewGroup),
+}
+
+#[derive(Clone,PartialEq,Debug)]
+pub enum GridInfoChangesetPayload_oneof_one_of_sort {
+    sort(ViewSort),
+}
+
+impl GridInfoChangesetPayload {
+    pub fn new() -> GridInfoChangesetPayload {
+        ::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())
+    }
+
+    // .ViewFilter filter = 2;
+
+
+    pub fn get_filter(&self) -> &ViewFilter {
+        match self.one_of_filter {
+            ::std::option::Option::Some(GridInfoChangesetPayload_oneof_one_of_filter::filter(ref v)) => v,
+            _ => <ViewFilter as ::protobuf::Message>::default_instance(),
+        }
+    }
+    pub fn clear_filter(&mut self) {
+        self.one_of_filter = ::std::option::Option::None;
+    }
+
+    pub fn has_filter(&self) -> bool {
+        match self.one_of_filter {
+            ::std::option::Option::Some(GridInfoChangesetPayload_oneof_one_of_filter::filter(..)) => true,
+            _ => false,
+        }
+    }
+
+    // Param is passed by value, moved
+    pub fn set_filter(&mut self, v: ViewFilter) {
+        self.one_of_filter = ::std::option::Option::Some(GridInfoChangesetPayload_oneof_one_of_filter::filter(v))
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_filter(&mut self) -> &mut ViewFilter {
+        if let ::std::option::Option::Some(GridInfoChangesetPayload_oneof_one_of_filter::filter(_)) = self.one_of_filter {
+        } else {
+            self.one_of_filter = ::std::option::Option::Some(GridInfoChangesetPayload_oneof_one_of_filter::filter(ViewFilter::new()));
+        }
+        match self.one_of_filter {
+            ::std::option::Option::Some(GridInfoChangesetPayload_oneof_one_of_filter::filter(ref mut v)) => v,
+            _ => panic!(),
+        }
+    }
+
+    // Take field
+    pub fn take_filter(&mut self) -> ViewFilter {
+        if self.has_filter() {
+            match self.one_of_filter.take() {
+                ::std::option::Option::Some(GridInfoChangesetPayload_oneof_one_of_filter::filter(v)) => v,
+                _ => panic!(),
+            }
+        } else {
+            ViewFilter::new()
+        }
+    }
+
+    // .ViewGroup group = 3;
+
+
+    pub fn get_group(&self) -> &ViewGroup {
+        match self.one_of_group {
+            ::std::option::Option::Some(GridInfoChangesetPayload_oneof_one_of_group::group(ref v)) => v,
+            _ => <ViewGroup as ::protobuf::Message>::default_instance(),
+        }
+    }
+    pub fn clear_group(&mut self) {
+        self.one_of_group = ::std::option::Option::None;
+    }
+
+    pub fn has_group(&self) -> bool {
+        match self.one_of_group {
+            ::std::option::Option::Some(GridInfoChangesetPayload_oneof_one_of_group::group(..)) => true,
+            _ => false,
+        }
+    }
+
+    // Param is passed by value, moved
+    pub fn set_group(&mut self, v: ViewGroup) {
+        self.one_of_group = ::std::option::Option::Some(GridInfoChangesetPayload_oneof_one_of_group::group(v))
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_group(&mut self) -> &mut ViewGroup {
+        if let ::std::option::Option::Some(GridInfoChangesetPayload_oneof_one_of_group::group(_)) = self.one_of_group {
+        } else {
+            self.one_of_group = ::std::option::Option::Some(GridInfoChangesetPayload_oneof_one_of_group::group(ViewGroup::new()));
+        }
+        match self.one_of_group {
+            ::std::option::Option::Some(GridInfoChangesetPayload_oneof_one_of_group::group(ref mut v)) => v,
+            _ => panic!(),
+        }
+    }
+
+    // Take field
+    pub fn take_group(&mut self) -> ViewGroup {
+        if self.has_group() {
+            match self.one_of_group.take() {
+                ::std::option::Option::Some(GridInfoChangesetPayload_oneof_one_of_group::group(v)) => v,
+                _ => panic!(),
+            }
+        } else {
+            ViewGroup::new()
+        }
+    }
+
+    // .ViewSort sort = 4;
+
+
+    pub fn get_sort(&self) -> &ViewSort {
+        match self.one_of_sort {
+            ::std::option::Option::Some(GridInfoChangesetPayload_oneof_one_of_sort::sort(ref v)) => v,
+            _ => <ViewSort as ::protobuf::Message>::default_instance(),
+        }
+    }
+    pub fn clear_sort(&mut self) {
+        self.one_of_sort = ::std::option::Option::None;
+    }
+
+    pub fn has_sort(&self) -> bool {
+        match self.one_of_sort {
+            ::std::option::Option::Some(GridInfoChangesetPayload_oneof_one_of_sort::sort(..)) => true,
+            _ => false,
+        }
+    }
+
+    // Param is passed by value, moved
+    pub fn set_sort(&mut self, v: ViewSort) {
+        self.one_of_sort = ::std::option::Option::Some(GridInfoChangesetPayload_oneof_one_of_sort::sort(v))
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_sort(&mut self) -> &mut ViewSort {
+        if let ::std::option::Option::Some(GridInfoChangesetPayload_oneof_one_of_sort::sort(_)) = self.one_of_sort {
+        } else {
+            self.one_of_sort = ::std::option::Option::Some(GridInfoChangesetPayload_oneof_one_of_sort::sort(ViewSort::new()));
+        }
+        match self.one_of_sort {
+            ::std::option::Option::Some(GridInfoChangesetPayload_oneof_one_of_sort::sort(ref mut v)) => v,
+            _ => panic!(),
+        }
+    }
+
+    // Take field
+    pub fn take_sort(&mut self) -> ViewSort {
+        if self.has_sort() {
+            match self.one_of_sort.take() {
+                ::std::option::Option::Some(GridInfoChangesetPayload_oneof_one_of_sort::sort(v)) => v,
+                _ => panic!(),
+            }
+        } else {
+            ViewSort::new()
+        }
+    }
+}
+
+impl ::protobuf::Message for GridInfoChangesetPayload {
+    fn is_initialized(&self) -> bool {
+        if let Some(GridInfoChangesetPayload_oneof_one_of_filter::filter(ref v)) = self.one_of_filter {
+            if !v.is_initialized() {
+                return false;
+            }
+        }
+        if let Some(GridInfoChangesetPayload_oneof_one_of_group::group(ref v)) = self.one_of_group {
+            if !v.is_initialized() {
+                return false;
+            }
+        }
+        if let Some(GridInfoChangesetPayload_oneof_one_of_sort::sort(ref v)) = self.one_of_sort {
+            if !v.is_initialized() {
+                return false;
+            }
+        }
+        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 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    self.one_of_filter = ::std::option::Option::Some(GridInfoChangesetPayload_oneof_one_of_filter::filter(is.read_message()?));
+                },
+                3 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    self.one_of_group = ::std::option::Option::Some(GridInfoChangesetPayload_oneof_one_of_group::group(is.read_message()?));
+                },
+                4 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    self.one_of_sort = ::std::option::Option::Some(GridInfoChangesetPayload_oneof_one_of_sort::sort(is.read_message()?));
+                },
+                _ => {
+                    ::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 let ::std::option::Option::Some(ref v) = self.one_of_filter {
+            match v {
+                &GridInfoChangesetPayload_oneof_one_of_filter::filter(ref v) => {
+                    let len = v.compute_size();
+                    my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+                },
+            };
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_group {
+            match v {
+                &GridInfoChangesetPayload_oneof_one_of_group::group(ref v) => {
+                    let len = v.compute_size();
+                    my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+                },
+            };
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_sort {
+            match v {
+                &GridInfoChangesetPayload_oneof_one_of_sort::sort(ref v) => {
+                    let len = v.compute_size();
+                    my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+                },
+            };
+        }
+        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 let ::std::option::Option::Some(ref v) = self.one_of_filter {
+            match v {
+                &GridInfoChangesetPayload_oneof_one_of_filter::filter(ref v) => {
+                    os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+                    os.write_raw_varint32(v.get_cached_size())?;
+                    v.write_to_with_cached_sizes(os)?;
+                },
+            };
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_group {
+            match v {
+                &GridInfoChangesetPayload_oneof_one_of_group::group(ref v) => {
+                    os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+                    os.write_raw_varint32(v.get_cached_size())?;
+                    v.write_to_with_cached_sizes(os)?;
+                },
+            };
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_sort {
+            match v {
+                &GridInfoChangesetPayload_oneof_one_of_sort::sort(ref v) => {
+                    os.write_tag(4, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+                    os.write_raw_varint32(v.get_cached_size())?;
+                    v.write_to_with_cached_sizes(os)?;
+                },
+            };
+        }
+        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<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> GridInfoChangesetPayload {
+        GridInfoChangesetPayload::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: &GridInfoChangesetPayload| { &m.grid_id },
+                |m: &mut GridInfoChangesetPayload| { &mut m.grid_id },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, ViewFilter>(
+                "filter",
+                GridInfoChangesetPayload::has_filter,
+                GridInfoChangesetPayload::get_filter,
+            ));
+            fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, ViewGroup>(
+                "group",
+                GridInfoChangesetPayload::has_group,
+                GridInfoChangesetPayload::get_group,
+            ));
+            fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, ViewSort>(
+                "sort",
+                GridInfoChangesetPayload::has_sort,
+                GridInfoChangesetPayload::get_sort,
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<GridInfoChangesetPayload>(
+                "GridInfoChangesetPayload",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static GridInfoChangesetPayload {
+        static instance: ::protobuf::rt::LazyV2<GridInfoChangesetPayload> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(GridInfoChangesetPayload::new)
+    }
+}
+
+impl ::protobuf::Clear for GridInfoChangesetPayload {
+    fn clear(&mut self) {
+        self.grid_id.clear();
+        self.one_of_filter = ::std::option::Option::None;
+        self.one_of_group = ::std::option::Option::None;
+        self.one_of_sort = ::std::option::Option::None;
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for GridInfoChangesetPayload {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for GridInfoChangesetPayload {
+    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+        ::protobuf::reflect::ReflectValueRef::Message(self)
+    }
+}
+
+static file_descriptor_proto_data: &'static [u8] = b"\
+    \n\x0fgrid_info.proto\"s\n\x0bViewExtData\x12#\n\x06filter\x18\x01\x20\
+    \x01(\x0b2\x0b.ViewFilterR\x06filter\x12\x20\n\x05group\x18\x02\x20\x01(\
+    \x0b2\n.ViewGroupR\x05group\x12\x1d\n\x04sort\x18\x03\x20\x01(\x0b2\t.Vi\
+    ewSortR\x04sort\"<\n\nViewFilter\x12\x1b\n\x08field_id\x18\x01\x20\x01(\
+    \tH\0R\x07fieldIdB\x11\n\x0fone_of_field_id\"\x98\x01\n\tViewGroup\x12&\
+    \n\x0egroup_field_id\x18\x01\x20\x01(\tH\0R\x0cgroupFieldId\x12-\n\x12su\
+    b_group_field_id\x18\x02\x20\x01(\tH\x01R\x0fsubGroupFieldIdB\x17\n\x15o\
+    ne_of_group_field_idB\x1b\n\x19one_of_sub_group_field_id\":\n\x08ViewSor\
+    t\x12\x1b\n\x08field_id\x18\x01\x20\x01(\tH\0R\x07fieldIdB\x11\n\x0fone_\
+    of_field_id\"\xcf\x01\n\x18GridInfoChangesetPayload\x12\x17\n\x07grid_id\
+    \x18\x01\x20\x01(\tR\x06gridId\x12%\n\x06filter\x18\x02\x20\x01(\x0b2\
+    \x0b.ViewFilterH\0R\x06filter\x12\"\n\x05group\x18\x03\x20\x01(\x0b2\n.V\
+    iewGroupH\x01R\x05group\x12\x1f\n\x04sort\x18\x04\x20\x01(\x0b2\t.ViewSo\
+    rtH\x02R\x04sortB\x0f\n\rone_of_filterB\x0e\n\x0cone_of_groupB\r\n\x0bon\
+    e_of_sortb\x06proto3\
+";
+
+static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
+
+fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto {
+    ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap()
+}
+
+pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto {
+    file_descriptor_proto_lazy.get(|| {
+        parse_descriptor_proto()
+    })
+}

+ 3 - 0
shared-lib/flowy-grid-data-model/src/protobuf/model/mod.rs

@@ -4,5 +4,8 @@
 mod grid;
 pub use grid::*;
 
+mod grid_info;
+pub use grid_info::*;
+
 mod field;
 pub use field::*;

+ 23 - 0
shared-lib/flowy-grid-data-model/src/protobuf/proto/grid_info.proto

@@ -0,0 +1,23 @@
+syntax = "proto3";
+
+message ViewExtData {
+    ViewFilter filter = 1;
+    ViewGroup group = 2;
+    ViewSort sort = 3;
+}
+message ViewFilter {
+    oneof one_of_field_id { string field_id = 1; };
+}
+message ViewGroup {
+    oneof one_of_group_field_id { string group_field_id = 1; };
+    oneof one_of_sub_group_field_id { string sub_group_field_id = 2; };
+}
+message ViewSort {
+    oneof one_of_field_id { string field_id = 1; };
+}
+message GridInfoChangesetPayload {
+    string grid_id = 1;
+    oneof one_of_filter { ViewFilter filter = 2; };
+    oneof one_of_group { ViewGroup group = 3; };
+    oneof one_of_sort { ViewSort sort = 4; };
+}

+ 66 - 0
shared-lib/flowy-grid-data-model/src/revision/grid_info_rev.rs

@@ -0,0 +1,66 @@
+use crate::entities::{ViewFilter, ViewGroup, ViewSort};
+use serde::{Deserialize, Serialize};
+use serde_repr::*;
+
+#[derive(Debug, Clone, Serialize, Deserialize, Default)]
+pub struct GridInfoRevision {
+    pub filter: GridFilterRevision,
+    pub group: GridGroupRevision,
+    pub sort: GridSortRevision,
+    pub layout: GridLayoutRevision,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, Default)]
+pub struct GridLayoutRevision {
+    pub ty: GridLayoutType,
+}
+
+#[derive(Debug, Clone, Serialize_repr, Deserialize_repr)]
+#[repr(u8)]
+pub enum GridLayoutType {
+    Table = 0,
+    Board = 1,
+}
+
+impl std::default::Default for GridLayoutType {
+    fn default() -> Self {
+        GridLayoutType::Table
+    }
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, Default)]
+pub struct GridFilterRevision {
+    pub field_id: Option<String>,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, Default)]
+pub struct GridGroupRevision {
+    pub group_field_id: Option<String>,
+    pub sub_group_field_id: Option<String>,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, Default)]
+pub struct GridSortRevision {
+    field_id: Option<String>,
+}
+
+impl std::convert::From<GridFilterRevision> for ViewFilter {
+    fn from(rev: GridFilterRevision) -> Self {
+        ViewFilter { field_id: rev.field_id }
+    }
+}
+
+impl std::convert::From<GridGroupRevision> for ViewGroup {
+    fn from(rev: GridGroupRevision) -> Self {
+        ViewGroup {
+            group_field_id: rev.group_field_id,
+            sub_group_field_id: rev.sub_group_field_id,
+        }
+    }
+}
+
+impl std::convert::From<GridSortRevision> for ViewSort {
+    fn from(rev: GridSortRevision) -> Self {
+        ViewSort { field_id: rev.field_id }
+    }
+}

+ 310 - 0
shared-lib/flowy-grid-data-model/src/revision/grid_rev.rs

@@ -0,0 +1,310 @@
+use crate::entities::{CellChangeset, Field, FieldOrder, FieldType, RowOrder};
+use crate::revision::GridInfoRevision;
+use bytes::Bytes;
+use indexmap::IndexMap;
+use nanoid::nanoid;
+use serde::{Deserialize, Serialize};
+use std::collections::HashMap;
+use std::sync::Arc;
+
+pub const DEFAULT_ROW_HEIGHT: i32 = 42;
+
+pub fn gen_grid_id() -> String {
+    // nanoid calculator https://zelark.github.io/nano-id-cc/
+    nanoid!(10)
+}
+
+pub fn gen_block_id() -> String {
+    nanoid!(10)
+}
+
+pub fn gen_row_id() -> String {
+    nanoid!(6)
+}
+
+pub fn gen_field_id() -> String {
+    nanoid!(6)
+}
+
+#[derive(Debug, Clone, Default, Serialize, Deserialize)]
+pub struct GridRevision {
+    pub grid_id: String,
+    pub fields: Vec<FieldRevision>,
+    pub blocks: Vec<GridBlockRevision>,
+
+    #[serde(default, skip)]
+    pub info: GridInfoRevision,
+}
+
+impl GridRevision {
+    pub fn new(grid_id: &str) -> Self {
+        Self {
+            grid_id: grid_id.to_owned(),
+            fields: vec![],
+            blocks: vec![],
+            info: GridInfoRevision::default(),
+        }
+    }
+}
+
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
+pub struct GridBlockRevision {
+    pub block_id: String,
+    pub start_row_index: i32,
+    pub row_count: i32,
+}
+
+impl GridBlockRevision {
+    pub fn len(&self) -> i32 {
+        self.row_count
+    }
+
+    pub fn is_empty(&self) -> bool {
+        self.row_count == 0
+    }
+}
+
+impl GridBlockRevision {
+    pub fn new() -> Self {
+        GridBlockRevision {
+            block_id: gen_block_id(),
+            ..Default::default()
+        }
+    }
+}
+
+pub struct GridBlockRevisionChangeset {
+    pub block_id: String,
+    pub start_row_index: Option<i32>,
+    pub row_count: Option<i32>,
+}
+
+impl GridBlockRevisionChangeset {
+    pub fn from_row_count(block_id: &str, row_count: i32) -> Self {
+        Self {
+            block_id: block_id.to_string(),
+            start_row_index: None,
+            row_count: Some(row_count),
+        }
+    }
+}
+
+#[derive(Debug, Clone, Default, Serialize, Deserialize)]
+pub struct GridBlockRevisionData {
+    pub block_id: String,
+    pub rows: Vec<RowRevision>,
+}
+
+#[derive(Debug, Clone, Default, Serialize, Deserialize, Eq, PartialEq)]
+pub struct FieldRevision {
+    pub id: String,
+
+    pub name: String,
+
+    pub desc: String,
+
+    pub field_type: FieldType,
+
+    pub frozen: bool,
+
+    pub visibility: bool,
+
+    pub width: i32,
+
+    /// type_options contains key/value pairs
+    /// key: id of the FieldType
+    /// value: type option data that can be parsed into specified TypeOptionStruct.
+    /// For example, CheckboxTypeOption, MultiSelectTypeOption etc.
+    #[serde(with = "indexmap::serde_seq")]
+    pub type_options: IndexMap<String, String>,
+
+    #[serde(default = "default_is_primary")]
+    pub is_primary: bool,
+}
+
+fn default_is_primary() -> bool {
+    false
+}
+
+impl FieldRevision {
+    pub fn new(name: &str, desc: &str, field_type: FieldType, is_primary: bool) -> Self {
+        let width = field_type.default_cell_width();
+        Self {
+            id: gen_field_id(),
+            name: name.to_string(),
+            desc: desc.to_string(),
+            field_type,
+            frozen: false,
+            visibility: true,
+            width,
+            type_options: Default::default(),
+            is_primary,
+        }
+    }
+
+    pub fn insert_type_option_entry<T>(&mut self, entry: &T)
+    where
+        T: TypeOptionDataEntry + ?Sized,
+    {
+        self.type_options.insert(entry.field_type().type_id(), entry.json_str());
+    }
+
+    pub fn get_type_option_entry<T: TypeOptionDataDeserializer>(&self, field_type: &FieldType) -> Option<T> {
+        self.type_options
+            .get(&field_type.type_id())
+            .map(|s| T::from_json_str(s))
+    }
+
+    pub fn insert_type_option_str(&mut self, field_type: &FieldType, json_str: String) {
+        self.type_options.insert(field_type.type_id(), json_str);
+    }
+
+    pub fn get_type_option_str(&self, field_type: &FieldType) -> Option<String> {
+        self.type_options.get(&field_type.type_id()).map(|s| s.to_owned())
+    }
+}
+
+impl std::convert::From<FieldRevision> for Field {
+    fn from(field_rev: FieldRevision) -> Self {
+        Self {
+            id: field_rev.id,
+            name: field_rev.name,
+            desc: field_rev.desc,
+            field_type: field_rev.field_type,
+            frozen: field_rev.frozen,
+            visibility: field_rev.visibility,
+            width: field_rev.width,
+            is_primary: field_rev.is_primary,
+        }
+    }
+}
+
+impl std::convert::From<&FieldRevision> for FieldOrder {
+    fn from(field_rev: &FieldRevision) -> Self {
+        Self {
+            field_id: field_rev.id.clone(),
+        }
+    }
+}
+
+pub trait TypeOptionDataEntry {
+    fn field_type(&self) -> FieldType;
+    fn json_str(&self) -> String;
+    fn protobuf_bytes(&self) -> Bytes;
+}
+
+pub trait TypeOptionDataDeserializer {
+    fn from_json_str(s: &str) -> Self;
+    fn from_protobuf_bytes(bytes: Bytes) -> Self;
+}
+
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
+pub struct RowRevision {
+    pub id: String,
+    pub block_id: String,
+    /// cells contains key/value pairs.
+    /// key: field id,
+    /// value: CellMeta
+    #[serde(with = "indexmap::serde_seq")]
+    pub cells: IndexMap<String, CellRevision>,
+    pub height: i32,
+    pub visibility: bool,
+}
+
+impl RowRevision {
+    pub fn new(block_id: &str) -> Self {
+        Self {
+            id: gen_row_id(),
+            block_id: block_id.to_owned(),
+            cells: Default::default(),
+            height: DEFAULT_ROW_HEIGHT,
+            visibility: true,
+        }
+    }
+}
+
+impl std::convert::From<&RowRevision> for RowOrder {
+    fn from(row: &RowRevision) -> Self {
+        Self {
+            row_id: row.id.clone(),
+            block_id: row.block_id.clone(),
+            height: row.height,
+        }
+    }
+}
+
+impl std::convert::From<&Arc<RowRevision>> for RowOrder {
+    fn from(row: &Arc<RowRevision>) -> Self {
+        Self {
+            row_id: row.id.clone(),
+            block_id: row.block_id.clone(),
+            height: row.height,
+        }
+    }
+}
+
+#[derive(Debug, Clone, Default)]
+pub struct RowMetaChangeset {
+    pub row_id: String,
+    pub height: Option<i32>,
+    pub visibility: Option<bool>,
+    pub cell_by_field_id: HashMap<String, CellRevision>,
+}
+
+impl std::convert::From<CellChangeset> for RowMetaChangeset {
+    fn from(changeset: CellChangeset) -> Self {
+        let mut cell_by_field_id = HashMap::with_capacity(1);
+        let field_id = changeset.field_id;
+        let cell_rev = CellRevision {
+            data: changeset.cell_content_changeset.unwrap_or_else(|| "".to_owned()),
+        };
+        cell_by_field_id.insert(field_id, cell_rev);
+
+        RowMetaChangeset {
+            row_id: changeset.row_id,
+            height: None,
+            visibility: None,
+            cell_by_field_id,
+        }
+    }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
+pub struct CellRevision {
+    pub data: String,
+}
+
+impl CellRevision {
+    pub fn new(data: String) -> Self {
+        Self { data }
+    }
+}
+
+#[derive(Clone, Default, Deserialize, Serialize)]
+pub struct BuildGridContext {
+    pub field_revs: Vec<FieldRevision>,
+    pub blocks: Vec<GridBlockRevision>,
+    pub blocks_meta_data: Vec<GridBlockRevisionData>,
+}
+
+impl BuildGridContext {
+    pub fn new() -> Self {
+        Self::default()
+    }
+}
+
+impl std::convert::From<BuildGridContext> for Bytes {
+    fn from(ctx: BuildGridContext) -> Self {
+        let bytes = serde_json::to_vec(&ctx).unwrap_or_else(|_| vec![]);
+        Bytes::from(bytes)
+    }
+}
+
+impl std::convert::TryFrom<Bytes> for BuildGridContext {
+    type Error = serde_json::Error;
+
+    fn try_from(bytes: Bytes) -> Result<Self, Self::Error> {
+        let ctx: BuildGridContext = serde_json::from_slice(&bytes)?;
+        Ok(ctx)
+    }
+}

+ 4 - 295
shared-lib/flowy-grid-data-model/src/revision/mod.rs

@@ -1,296 +1,5 @@
-use crate::entities::{CellChangeset, Field, FieldOrder, FieldType, RowOrder};
-use bytes::Bytes;
-use indexmap::IndexMap;
-use nanoid::nanoid;
-use serde::{Deserialize, Serialize};
-use std::any::Any;
-use std::collections::HashMap;
-use std::sync::Arc;
+mod grid_info_rev;
+mod grid_rev;
 
-pub const DEFAULT_ROW_HEIGHT: i32 = 42;
-
-pub fn gen_grid_id() -> String {
-    // nanoid calculator https://zelark.github.io/nano-id-cc/
-    nanoid!(10)
-}
-
-pub fn gen_block_id() -> String {
-    nanoid!(10)
-}
-
-pub fn gen_row_id() -> String {
-    nanoid!(6)
-}
-
-pub fn gen_field_id() -> String {
-    nanoid!(6)
-}
-
-#[derive(Debug, Clone, Default, Serialize, Deserialize)]
-pub struct GridRevision {
-    pub grid_id: String,
-    pub fields: Vec<FieldRevision>,
-    pub blocks: Vec<GridBlockRevision>,
-}
-
-#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
-pub struct GridBlockRevision {
-    pub block_id: String,
-    pub start_row_index: i32,
-    pub row_count: i32,
-}
-
-impl GridBlockRevision {
-    pub fn len(&self) -> i32 {
-        self.row_count
-    }
-
-    pub fn is_empty(&self) -> bool {
-        self.row_count == 0
-    }
-}
-
-impl GridBlockRevision {
-    pub fn new() -> Self {
-        GridBlockRevision {
-            block_id: gen_block_id(),
-            ..Default::default()
-        }
-    }
-}
-
-pub struct GridBlockRevisionChangeset {
-    pub block_id: String,
-    pub start_row_index: Option<i32>,
-    pub row_count: Option<i32>,
-}
-
-impl GridBlockRevisionChangeset {
-    pub fn from_row_count(block_id: &str, row_count: i32) -> Self {
-        Self {
-            block_id: block_id.to_string(),
-            start_row_index: None,
-            row_count: Some(row_count),
-        }
-    }
-}
-
-#[derive(Debug, Clone, Default, Serialize, Deserialize)]
-pub struct GridBlockRevisionData {
-    pub block_id: String,
-    pub rows: Vec<RowRevision>,
-}
-
-#[derive(Debug, Clone, Default, Serialize, Deserialize, Eq, PartialEq)]
-pub struct FieldRevision {
-    pub id: String,
-
-    pub name: String,
-
-    pub desc: String,
-
-    pub field_type: FieldType,
-
-    pub frozen: bool,
-
-    pub visibility: bool,
-
-    pub width: i32,
-
-    /// type_options contains key/value pairs
-    /// key: id of the FieldType
-    /// value: type option data that can be parsed into specified TypeOptionStruct.
-    /// For example, CheckboxTypeOption, MultiSelectTypeOption etc.
-    #[serde(with = "indexmap::serde_seq")]
-    pub type_options: IndexMap<String, String>,
-
-    #[serde(default = "default_is_primary")]
-    pub is_primary: bool,
-}
-
-fn default_is_primary() -> bool {
-    false
-}
-
-impl FieldRevision {
-    pub fn new(name: &str, desc: &str, field_type: FieldType, is_primary: bool) -> Self {
-        let width = field_type.default_cell_width();
-        Self {
-            id: gen_field_id(),
-            name: name.to_string(),
-            desc: desc.to_string(),
-            field_type,
-            frozen: false,
-            visibility: true,
-            width,
-            type_options: Default::default(),
-            is_primary,
-        }
-    }
-
-    pub fn insert_type_option_entry<T>(&mut self, entry: &T)
-    where
-        T: TypeOptionDataEntry + ?Sized,
-    {
-        self.type_options.insert(entry.field_type().type_id(), entry.json_str());
-    }
-
-    pub fn get_type_option_entry<T: TypeOptionDataDeserializer>(&self, field_type: &FieldType) -> Option<T> {
-        self.type_options
-            .get(&field_type.type_id())
-            .map(|s| T::from_json_str(s))
-    }
-
-    pub fn insert_type_option_str(&mut self, field_type: &FieldType, json_str: String) {
-        self.type_options.insert(field_type.type_id(), json_str);
-    }
-
-    pub fn get_type_option_str(&self, field_type: &FieldType) -> Option<String> {
-        self.type_options.get(&field_type.type_id()).map(|s| s.to_owned())
-    }
-}
-
-impl std::convert::From<FieldRevision> for Field {
-    fn from(field_rev: FieldRevision) -> Self {
-        Self {
-            id: field_rev.id,
-            name: field_rev.name,
-            desc: field_rev.desc,
-            field_type: field_rev.field_type,
-            frozen: field_rev.frozen,
-            visibility: field_rev.visibility,
-            width: field_rev.width,
-            is_primary: field_rev.is_primary,
-        }
-    }
-}
-
-impl std::convert::From<&FieldRevision> for FieldOrder {
-    fn from(field_rev: &FieldRevision) -> Self {
-        Self {
-            field_id: field_rev.id.clone(),
-        }
-    }
-}
-
-pub trait TypeOptionDataEntry {
-    fn field_type(&self) -> FieldType;
-    fn json_str(&self) -> String;
-    fn protobuf_bytes(&self) -> Bytes;
-}
-
-pub trait TypeOptionDataDeserializer {
-    fn from_json_str(s: &str) -> Self;
-    fn from_protobuf_bytes(bytes: Bytes) -> Self;
-}
-
-#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
-pub struct RowRevision {
-    pub id: String,
-    pub block_id: String,
-    /// cells contains key/value pairs.
-    /// key: field id,
-    /// value: CellMeta
-    #[serde(with = "indexmap::serde_seq")]
-    pub cells: IndexMap<String, CellRevision>,
-    pub height: i32,
-    pub visibility: bool,
-}
-
-impl RowRevision {
-    pub fn new(block_id: &str) -> Self {
-        Self {
-            id: gen_row_id(),
-            block_id: block_id.to_owned(),
-            cells: Default::default(),
-            height: DEFAULT_ROW_HEIGHT,
-            visibility: true,
-        }
-    }
-}
-
-impl std::convert::From<&RowRevision> for RowOrder {
-    fn from(row: &RowRevision) -> Self {
-        Self {
-            row_id: row.id.clone(),
-            block_id: row.block_id.clone(),
-            height: row.height,
-        }
-    }
-}
-
-impl std::convert::From<&Arc<RowRevision>> for RowOrder {
-    fn from(row: &Arc<RowRevision>) -> Self {
-        Self {
-            row_id: row.id.clone(),
-            block_id: row.block_id.clone(),
-            height: row.height,
-        }
-    }
-}
-
-#[derive(Debug, Clone, Default)]
-pub struct RowMetaChangeset {
-    pub row_id: String,
-    pub height: Option<i32>,
-    pub visibility: Option<bool>,
-    pub cell_by_field_id: HashMap<String, CellRevision>,
-}
-
-impl std::convert::From<CellChangeset> for RowMetaChangeset {
-    fn from(changeset: CellChangeset) -> Self {
-        let mut cell_by_field_id = HashMap::with_capacity(1);
-        let field_id = changeset.field_id;
-        let cell_rev = CellRevision {
-            data: changeset.cell_content_changeset.unwrap_or_else(|| "".to_owned()),
-        };
-        cell_by_field_id.insert(field_id, cell_rev);
-
-        RowMetaChangeset {
-            row_id: changeset.row_id,
-            height: None,
-            visibility: None,
-            cell_by_field_id,
-        }
-    }
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
-pub struct CellRevision {
-    pub data: String,
-}
-
-impl CellRevision {
-    pub fn new(data: String) -> Self {
-        Self { data }
-    }
-}
-
-#[derive(Clone, Default, Deserialize, Serialize)]
-pub struct BuildGridContext {
-    pub field_revs: Vec<FieldRevision>,
-    pub blocks: Vec<GridBlockRevision>,
-    pub blocks_meta_data: Vec<GridBlockRevisionData>,
-}
-
-impl BuildGridContext {
-    pub fn new() -> Self {
-        Self::default()
-    }
-}
-
-impl std::convert::From<BuildGridContext> for Bytes {
-    fn from(ctx: BuildGridContext) -> Self {
-        let bytes = serde_json::to_vec(&ctx).unwrap_or_else(|_| vec![]);
-        Bytes::from(bytes)
-    }
-}
-
-impl std::convert::TryFrom<Bytes> for BuildGridContext {
-    type Error = serde_json::Error;
-
-    fn try_from(bytes: Bytes) -> Result<Self, Self::Error> {
-        let ctx: BuildGridContext = serde_json::from_slice(&bytes)?;
-        Ok(ctx)
-    }
-}
+pub use grid_info_rev::*;
+pub use grid_rev::*;

+ 1 - 5
shared-lib/flowy-grid-data-model/tests/serde_test.rs

@@ -3,11 +3,7 @@ use flowy_grid_data_model::revision::*;
 #[test]
 fn grid_default_serde_test() {
     let grid_id = "1".to_owned();
-    let grid = GridRevision {
-        grid_id,
-        fields: vec![],
-        blocks: vec![],
-    };
+    let grid = GridRevision::new(&grid_id);
 
     let json = serde_json::to_string(&grid).unwrap();
     assert_eq!(json, r#"{"grid_id":"1","fields":[],"blocks":[]}"#)

+ 1 - 0
shared-lib/flowy-sync/src/client_grid/grid_builder.rs

@@ -79,6 +79,7 @@ mod tests {
             grid_id,
             fields: build_context.field_revs,
             blocks: build_context.blocks,
+            info: Default::default(),
         };
 
         let grid_meta_delta = make_grid_delta(&grid_rev);

+ 1 - 6
shared-lib/flowy-sync/src/client_grid/grid_revision_pad.rs

@@ -7,7 +7,6 @@ use flowy_grid_data_model::entities::{FieldChangesetParams, FieldOrder};
 use flowy_grid_data_model::revision::{
     gen_block_id, gen_grid_id, FieldRevision, GridBlockRevision, GridBlockRevisionChangeset, GridRevision,
 };
-use futures::StreamExt;
 use lib_infra::util::move_vec_element;
 use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder};
 use std::collections::HashMap;
@@ -423,11 +422,7 @@ pub fn make_grid_revisions(user_id: &str, grid_rev: &GridRevision) -> RepeatedRe
 
 impl std::default::Default for GridRevisionPad {
     fn default() -> Self {
-        let grid = GridRevision {
-            grid_id: gen_grid_id(),
-            fields: vec![],
-            blocks: vec![],
-        };
+        let grid = GridRevision::new(&gen_grid_id());
         let delta = make_grid_delta(&grid);
         GridRevisionPad {
             grid_rev: Arc::new(grid),