瀏覽代碼

chore: add grid meta

appflowy 3 年之前
父節點
當前提交
e45be3b81e
共有 29 個文件被更改,包括 3363 次插入3009 次删除
  1. 4 5
      frontend/app_flowy/lib/workspace/application/grid/grid_service.dart
  2. 17 0
      frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart
  3. 34 608
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart
  4. 0 27
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbenum.dart
  5. 16 122
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart
  6. 584 0
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pb.dart
  7. 34 0
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbenum.dart
  8. 125 0
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbjson.dart
  9. 9 0
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/meta.pbserver.dart
  10. 1 0
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/protobuf.dart
  11. 2 0
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbenum.dart
  12. 2 1
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart
  13. 2 2
      frontend/rust-lib/flowy-grid/src/event_handler.rs
  14. 1 13
      frontend/rust-lib/flowy-grid/src/manager.rs
  15. 5 2
      frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs
  16. 1 0
      frontend/rust-lib/flowy-grid/src/protobuf/proto/event_map.proto
  17. 11 18
      frontend/rust-lib/flowy-grid/src/services/grid_builder.rs
  18. 28 32
      frontend/rust-lib/flowy-grid/src/services/grid_editor.rs
  19. 6 30
      frontend/rust-lib/flowy-grid/src/services/kv_persistence.rs
  20. 56 54
      shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs
  21. 13 259
      shared-lib/flowy-grid-data-model/src/entities/grid.rs
  22. 215 0
      shared-lib/flowy-grid-data-model/src/entities/meta.rs
  23. 2 0
      shared-lib/flowy-grid-data-model/src/entities/mod.rs
  24. 80 1750
      shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs
  25. 2040 0
      shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs
  26. 3 0
      shared-lib/flowy-grid-data-model/src/protobuf/model/mod.rs
  27. 6 52
      shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto
  28. 50 0
      shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto
  29. 16 34
      shared-lib/flowy-grid-data-model/tests/serde_test.rs

+ 4 - 5
frontend/app_flowy/lib/workspace/application/grid/grid_service.dart

@@ -16,18 +16,17 @@ class GridService {
     return GridEventCreateRow(GridId(value: gridId)).send();
   }
 
-  Future<Either<RepeatedRow, FlowyError>> getRows({required String gridId, required RepeatedRowOrder rowOrders}) {
+  Future<Either<RepeatedRow, FlowyError>> getRows({required String gridId, required List<RowOrder> rowOrders}) {
     final payload = QueryRowPayload.create()
       ..gridId = gridId
-      ..rowOrders = rowOrders;
+      ..rowOrders = RepeatedRowOrder(items: rowOrders);
     return GridEventGetRows(payload).send();
   }
 
-  Future<Either<RepeatedField, FlowyError>> getFields(
-      {required String gridId, required RepeatedFieldOrder fieldOrders}) {
+  Future<Either<RepeatedField, FlowyError>> getFields({required String gridId, required List<FieldOrder> fieldOrders}) {
     final payload = QueryFieldPayload.create()
       ..gridId = gridId
-      ..fieldOrders = fieldOrders;
+      ..fieldOrders = RepeatedFieldOrder(items: fieldOrders);
     return GridEventGetFields(payload).send();
   }
 }

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

@@ -69,3 +69,20 @@ class GridEventCreateRow {
     }
 }
 
+class GridEventUpdateCell {
+     Cell request;
+     GridEventUpdateCell(this.request);
+
+    Future<Either<Unit, FlowyError>> send() {
+    final request = FFIRequest.create()
+          ..event = GridEvent.UpdateCell.toString()
+          ..payload = requestToBytes(this.request);
+
+    return Dispatch.asyncRequest(request)
+        .then((bytesResult) => bytesResult.fold(
+           (bytes) => left(unit),
+           (errBytes) => right(FlowyError.fromBuffer(errBytes)),
+        ));
+    }
+}
+

+ 34 - 608
frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart

@@ -9,33 +9,29 @@ import 'dart:core' as $core;
 
 import 'package:protobuf/protobuf.dart' as $pb;
 
-import 'grid.pbenum.dart';
-
-export 'grid.pbenum.dart';
-
 class Grid extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Grid', createEmptyInstance: create)
     ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id')
-    ..aOM<RepeatedFieldOrder>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldOrders', subBuilder: RepeatedFieldOrder.create)
-    ..aOM<RepeatedRowOrder>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowOrders', subBuilder: RepeatedRowOrder.create)
+    ..pc<FieldOrder>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldOrders', $pb.PbFieldType.PM, subBuilder: FieldOrder.create)
+    ..pc<RowOrder>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowOrders', $pb.PbFieldType.PM, subBuilder: RowOrder.create)
     ..hasRequiredFields = false
   ;
 
   Grid._() : super();
   factory Grid({
     $core.String? id,
-    RepeatedFieldOrder? fieldOrders,
-    RepeatedRowOrder? rowOrders,
+    $core.Iterable<FieldOrder>? fieldOrders,
+    $core.Iterable<RowOrder>? rowOrders,
   }) {
     final _result = create();
     if (id != null) {
       _result.id = id;
     }
     if (fieldOrders != null) {
-      _result.fieldOrders = fieldOrders;
+      _result.fieldOrders.addAll(fieldOrders);
     }
     if (rowOrders != null) {
-      _result.rowOrders = rowOrders;
+      _result.rowOrders.addAll(rowOrders);
     }
     return _result;
   }
@@ -70,47 +66,26 @@ class Grid extends $pb.GeneratedMessage {
   void clearId() => clearField(1);
 
   @$pb.TagNumber(2)
-  RepeatedFieldOrder get fieldOrders => $_getN(1);
-  @$pb.TagNumber(2)
-  set fieldOrders(RepeatedFieldOrder v) { setField(2, v); }
-  @$pb.TagNumber(2)
-  $core.bool hasFieldOrders() => $_has(1);
-  @$pb.TagNumber(2)
-  void clearFieldOrders() => clearField(2);
-  @$pb.TagNumber(2)
-  RepeatedFieldOrder ensureFieldOrders() => $_ensure(1);
+  $core.List<FieldOrder> get fieldOrders => $_getList(1);
 
   @$pb.TagNumber(3)
-  RepeatedRowOrder get rowOrders => $_getN(2);
-  @$pb.TagNumber(3)
-  set rowOrders(RepeatedRowOrder v) { setField(3, v); }
-  @$pb.TagNumber(3)
-  $core.bool hasRowOrders() => $_has(2);
-  @$pb.TagNumber(3)
-  void clearRowOrders() => clearField(3);
-  @$pb.TagNumber(3)
-  RepeatedRowOrder ensureRowOrders() => $_ensure(2);
+  $core.List<RowOrder> get rowOrders => $_getList(2);
 }
 
 class FieldOrder extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FieldOrder', createEmptyInstance: create)
     ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId')
-    ..aOB(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility')
     ..hasRequiredFields = false
   ;
 
   FieldOrder._() : super();
   factory FieldOrder({
     $core.String? fieldId,
-    $core.bool? visibility,
   }) {
     final _result = create();
     if (fieldId != null) {
       _result.fieldId = fieldId;
     }
-    if (visibility != null) {
-      _result.visibility = visibility;
-    }
     return _result;
   }
   factory FieldOrder.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
@@ -142,15 +117,6 @@ class FieldOrder extends $pb.GeneratedMessage {
   $core.bool hasFieldId() => $_has(0);
   @$pb.TagNumber(1)
   void clearFieldId() => clearField(1);
-
-  @$pb.TagNumber(2)
-  $core.bool get visibility => $_getBF(1);
-  @$pb.TagNumber(2)
-  set visibility($core.bool v) { $_setBool(1, v); }
-  @$pb.TagNumber(2)
-  $core.bool hasVisibility() => $_has(1);
-  @$pb.TagNumber(2)
-  void clearVisibility() => clearField(2);
 }
 
 class RepeatedFieldOrder extends $pb.GeneratedMessage {
@@ -194,265 +160,20 @@ class RepeatedFieldOrder extends $pb.GeneratedMessage {
   $core.List<FieldOrder> get items => $_getList(0);
 }
 
-class Field extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Field', createEmptyInstance: create)
-    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id')
-    ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name')
-    ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc')
-    ..e<FieldType>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldType', $pb.PbFieldType.OE, defaultOrMaker: FieldType.RichText, valueOf: FieldType.valueOf, enumValues: FieldType.values)
-    ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'frozen')
-    ..a<$core.int>(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'width', $pb.PbFieldType.O3)
-    ..aOM<AnyData>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptions', subBuilder: AnyData.create)
-    ..hasRequiredFields = false
-  ;
-
-  Field._() : super();
-  factory Field({
-    $core.String? id,
-    $core.String? name,
-    $core.String? desc,
-    FieldType? fieldType,
-    $core.bool? frozen,
-    $core.int? width,
-    AnyData? typeOptions,
-  }) {
-    final _result = create();
-    if (id != null) {
-      _result.id = id;
-    }
-    if (name != null) {
-      _result.name = name;
-    }
-    if (desc != null) {
-      _result.desc = desc;
-    }
-    if (fieldType != null) {
-      _result.fieldType = fieldType;
-    }
-    if (frozen != null) {
-      _result.frozen = frozen;
-    }
-    if (width != null) {
-      _result.width = width;
-    }
-    if (typeOptions != null) {
-      _result.typeOptions = typeOptions;
-    }
-    return _result;
-  }
-  factory Field.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
-  factory Field.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')
-  Field clone() => Field()..mergeFromMessage(this);
-  @$core.Deprecated(
-  'Using this can add significant overhead to your binary. '
-  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
-  'Will be removed in next major version')
-  Field copyWith(void Function(Field) updates) => super.copyWith((message) => updates(message as Field)) as Field; // ignore: deprecated_member_use
-  $pb.BuilderInfo get info_ => _i;
-  @$core.pragma('dart2js:noInline')
-  static Field create() => Field._();
-  Field createEmptyInstance() => create();
-  static $pb.PbList<Field> createRepeated() => $pb.PbList<Field>();
-  @$core.pragma('dart2js:noInline')
-  static Field getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Field>(create);
-  static Field? _defaultInstance;
-
-  @$pb.TagNumber(1)
-  $core.String get id => $_getSZ(0);
-  @$pb.TagNumber(1)
-  set id($core.String v) { $_setString(0, v); }
-  @$pb.TagNumber(1)
-  $core.bool hasId() => $_has(0);
-  @$pb.TagNumber(1)
-  void clearId() => clearField(1);
-
-  @$pb.TagNumber(2)
-  $core.String get name => $_getSZ(1);
-  @$pb.TagNumber(2)
-  set name($core.String v) { $_setString(1, v); }
-  @$pb.TagNumber(2)
-  $core.bool hasName() => $_has(1);
-  @$pb.TagNumber(2)
-  void clearName() => clearField(2);
-
-  @$pb.TagNumber(3)
-  $core.String get desc => $_getSZ(2);
-  @$pb.TagNumber(3)
-  set desc($core.String v) { $_setString(2, v); }
-  @$pb.TagNumber(3)
-  $core.bool hasDesc() => $_has(2);
-  @$pb.TagNumber(3)
-  void clearDesc() => clearField(3);
-
-  @$pb.TagNumber(4)
-  FieldType get fieldType => $_getN(3);
-  @$pb.TagNumber(4)
-  set fieldType(FieldType v) { setField(4, v); }
-  @$pb.TagNumber(4)
-  $core.bool hasFieldType() => $_has(3);
-  @$pb.TagNumber(4)
-  void clearFieldType() => clearField(4);
-
-  @$pb.TagNumber(5)
-  $core.bool get frozen => $_getBF(4);
-  @$pb.TagNumber(5)
-  set frozen($core.bool v) { $_setBool(4, v); }
-  @$pb.TagNumber(5)
-  $core.bool hasFrozen() => $_has(4);
-  @$pb.TagNumber(5)
-  void clearFrozen() => clearField(5);
-
-  @$pb.TagNumber(6)
-  $core.int get width => $_getIZ(5);
-  @$pb.TagNumber(6)
-  set width($core.int v) { $_setSignedInt32(5, v); }
-  @$pb.TagNumber(6)
-  $core.bool hasWidth() => $_has(5);
-  @$pb.TagNumber(6)
-  void clearWidth() => clearField(6);
-
-  @$pb.TagNumber(7)
-  AnyData get typeOptions => $_getN(6);
-  @$pb.TagNumber(7)
-  set typeOptions(AnyData v) { setField(7, v); }
-  @$pb.TagNumber(7)
-  $core.bool hasTypeOptions() => $_has(6);
-  @$pb.TagNumber(7)
-  void clearTypeOptions() => clearField(7);
-  @$pb.TagNumber(7)
-  AnyData ensureTypeOptions() => $_ensure(6);
-}
-
-class RepeatedField extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedField', createEmptyInstance: create)
-    ..pc<Field>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: Field.create)
-    ..hasRequiredFields = false
-  ;
-
-  RepeatedField._() : super();
-  factory RepeatedField({
-    $core.Iterable<Field>? items,
-  }) {
-    final _result = create();
-    if (items != null) {
-      _result.items.addAll(items);
-    }
-    return _result;
-  }
-  factory RepeatedField.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
-  factory RepeatedField.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')
-  RepeatedField clone() => RepeatedField()..mergeFromMessage(this);
-  @$core.Deprecated(
-  'Using this can add significant overhead to your binary. '
-  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
-  'Will be removed in next major version')
-  RepeatedField copyWith(void Function(RepeatedField) updates) => super.copyWith((message) => updates(message as RepeatedField)) as RepeatedField; // ignore: deprecated_member_use
-  $pb.BuilderInfo get info_ => _i;
-  @$core.pragma('dart2js:noInline')
-  static RepeatedField create() => RepeatedField._();
-  RepeatedField createEmptyInstance() => create();
-  static $pb.PbList<RepeatedField> createRepeated() => $pb.PbList<RepeatedField>();
-  @$core.pragma('dart2js:noInline')
-  static RepeatedField getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<RepeatedField>(create);
-  static RepeatedField? _defaultInstance;
-
-  @$pb.TagNumber(1)
-  $core.List<Field> get items => $_getList(0);
-}
-
-class AnyData extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'AnyData', createEmptyInstance: create)
-    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeId')
-    ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'value', $pb.PbFieldType.OY)
-    ..hasRequiredFields = false
-  ;
-
-  AnyData._() : super();
-  factory AnyData({
-    $core.String? typeId,
-    $core.List<$core.int>? value,
-  }) {
-    final _result = create();
-    if (typeId != null) {
-      _result.typeId = typeId;
-    }
-    if (value != null) {
-      _result.value = value;
-    }
-    return _result;
-  }
-  factory AnyData.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
-  factory AnyData.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')
-  AnyData clone() => AnyData()..mergeFromMessage(this);
-  @$core.Deprecated(
-  'Using this can add significant overhead to your binary. '
-  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
-  'Will be removed in next major version')
-  AnyData copyWith(void Function(AnyData) updates) => super.copyWith((message) => updates(message as AnyData)) as AnyData; // ignore: deprecated_member_use
-  $pb.BuilderInfo get info_ => _i;
-  @$core.pragma('dart2js:noInline')
-  static AnyData create() => AnyData._();
-  AnyData createEmptyInstance() => create();
-  static $pb.PbList<AnyData> createRepeated() => $pb.PbList<AnyData>();
-  @$core.pragma('dart2js:noInline')
-  static AnyData getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<AnyData>(create);
-  static AnyData? _defaultInstance;
-
-  @$pb.TagNumber(1)
-  $core.String get typeId => $_getSZ(0);
-  @$pb.TagNumber(1)
-  set typeId($core.String v) { $_setString(0, v); }
-  @$pb.TagNumber(1)
-  $core.bool hasTypeId() => $_has(0);
-  @$pb.TagNumber(1)
-  void clearTypeId() => clearField(1);
-
-  @$pb.TagNumber(2)
-  $core.List<$core.int> get value => $_getN(1);
-  @$pb.TagNumber(2)
-  set value($core.List<$core.int> v) { $_setBytes(1, v); }
-  @$pb.TagNumber(2)
-  $core.bool hasValue() => $_has(1);
-  @$pb.TagNumber(2)
-  void clearValue() => clearField(2);
-}
-
 class RowOrder extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RowOrder', createEmptyInstance: create)
-    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId')
-    ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId')
-    ..aOB(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility')
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId')
     ..hasRequiredFields = false
   ;
 
   RowOrder._() : super();
   factory RowOrder({
-    $core.String? gridId,
     $core.String? rowId,
-    $core.bool? visibility,
   }) {
     final _result = create();
-    if (gridId != null) {
-      _result.gridId = gridId;
-    }
     if (rowId != null) {
       _result.rowId = rowId;
     }
-    if (visibility != null) {
-      _result.visibility = visibility;
-    }
     return _result;
   }
   factory RowOrder.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
@@ -477,31 +198,13 @@ class RowOrder extends $pb.GeneratedMessage {
   static RowOrder? _defaultInstance;
 
   @$pb.TagNumber(1)
-  $core.String get gridId => $_getSZ(0);
+  $core.String get rowId => $_getSZ(0);
   @$pb.TagNumber(1)
-  set gridId($core.String v) { $_setString(0, v); }
+  set rowId($core.String v) { $_setString(0, v); }
   @$pb.TagNumber(1)
-  $core.bool hasGridId() => $_has(0);
+  $core.bool hasRowId() => $_has(0);
   @$pb.TagNumber(1)
-  void clearGridId() => clearField(1);
-
-  @$pb.TagNumber(2)
-  $core.String get rowId => $_getSZ(1);
-  @$pb.TagNumber(2)
-  set rowId($core.String v) { $_setString(1, v); }
-  @$pb.TagNumber(2)
-  $core.bool hasRowId() => $_has(1);
-  @$pb.TagNumber(2)
-  void clearRowId() => clearField(2);
-
-  @$pb.TagNumber(3)
-  $core.bool get visibility => $_getBF(2);
-  @$pb.TagNumber(3)
-  set visibility($core.bool v) { $_setBool(2, v); }
-  @$pb.TagNumber(3)
-  $core.bool hasVisibility() => $_has(2);
-  @$pb.TagNumber(3)
-  void clearVisibility() => clearField(3);
+  void clearRowId() => clearField(1);
 }
 
 class RepeatedRowOrder extends $pb.GeneratedMessage {
@@ -545,29 +248,24 @@ class RepeatedRowOrder extends $pb.GeneratedMessage {
   $core.List<RowOrder> get items => $_getList(0);
 }
 
-class RawRow extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RawRow', createEmptyInstance: create)
+class Row extends $pb.GeneratedMessage {
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Row', createEmptyInstance: create)
     ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id')
-    ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId')
-    ..m<$core.String, RawCell>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'cellByFieldId', entryClassName: 'RawRow.CellByFieldIdEntry', keyFieldType: $pb.PbFieldType.OS, valueFieldType: $pb.PbFieldType.OM, valueCreator: RawCell.create)
-    ..a<$core.int>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'height', $pb.PbFieldType.O3)
+    ..m<$core.String, Cell>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'cellByFieldId', entryClassName: 'Row.CellByFieldIdEntry', keyFieldType: $pb.PbFieldType.OS, valueFieldType: $pb.PbFieldType.OM, valueCreator: Cell.create)
+    ..a<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'height', $pb.PbFieldType.O3)
     ..hasRequiredFields = false
   ;
 
-  RawRow._() : super();
-  factory RawRow({
+  Row._() : super();
+  factory Row({
     $core.String? id,
-    $core.String? gridId,
-    $core.Map<$core.String, RawCell>? cellByFieldId,
+    $core.Map<$core.String, Cell>? cellByFieldId,
     $core.int? height,
   }) {
     final _result = create();
     if (id != null) {
       _result.id = id;
     }
-    if (gridId != null) {
-      _result.gridId = gridId;
-    }
     if (cellByFieldId != null) {
       _result.cellByFieldId.addAll(cellByFieldId);
     }
@@ -576,114 +274,26 @@ class RawRow extends $pb.GeneratedMessage {
     }
     return _result;
   }
-  factory RawRow.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
-  factory RawRow.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')
-  RawRow clone() => RawRow()..mergeFromMessage(this);
-  @$core.Deprecated(
-  'Using this can add significant overhead to your binary. '
-  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
-  'Will be removed in next major version')
-  RawRow copyWith(void Function(RawRow) updates) => super.copyWith((message) => updates(message as RawRow)) as RawRow; // ignore: deprecated_member_use
-  $pb.BuilderInfo get info_ => _i;
-  @$core.pragma('dart2js:noInline')
-  static RawRow create() => RawRow._();
-  RawRow createEmptyInstance() => create();
-  static $pb.PbList<RawRow> createRepeated() => $pb.PbList<RawRow>();
-  @$core.pragma('dart2js:noInline')
-  static RawRow getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<RawRow>(create);
-  static RawRow? _defaultInstance;
-
-  @$pb.TagNumber(1)
-  $core.String get id => $_getSZ(0);
-  @$pb.TagNumber(1)
-  set id($core.String v) { $_setString(0, v); }
-  @$pb.TagNumber(1)
-  $core.bool hasId() => $_has(0);
-  @$pb.TagNumber(1)
-  void clearId() => clearField(1);
-
-  @$pb.TagNumber(2)
-  $core.String get gridId => $_getSZ(1);
-  @$pb.TagNumber(2)
-  set gridId($core.String v) { $_setString(1, v); }
-  @$pb.TagNumber(2)
-  $core.bool hasGridId() => $_has(1);
-  @$pb.TagNumber(2)
-  void clearGridId() => clearField(2);
-
-  @$pb.TagNumber(3)
-  $core.Map<$core.String, RawCell> get cellByFieldId => $_getMap(2);
-
-  @$pb.TagNumber(4)
-  $core.int get height => $_getIZ(3);
-  @$pb.TagNumber(4)
-  set height($core.int v) { $_setSignedInt32(3, v); }
-  @$pb.TagNumber(4)
-  $core.bool hasHeight() => $_has(3);
-  @$pb.TagNumber(4)
-  void clearHeight() => clearField(4);
-}
-
-class RawCell extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RawCell', createEmptyInstance: create)
-    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id')
-    ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId')
-    ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId')
-    ..aOM<AnyData>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data', subBuilder: AnyData.create)
-    ..a<$core.int>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'height', $pb.PbFieldType.O3)
-    ..hasRequiredFields = false
-  ;
-
-  RawCell._() : super();
-  factory RawCell({
-    $core.String? id,
-    $core.String? rowId,
-    $core.String? fieldId,
-    AnyData? data,
-    $core.int? height,
-  }) {
-    final _result = create();
-    if (id != null) {
-      _result.id = id;
-    }
-    if (rowId != null) {
-      _result.rowId = rowId;
-    }
-    if (fieldId != null) {
-      _result.fieldId = fieldId;
-    }
-    if (data != null) {
-      _result.data = data;
-    }
-    if (height != null) {
-      _result.height = height;
-    }
-    return _result;
-  }
-  factory RawCell.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
-  factory RawCell.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+  factory Row.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory Row.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')
-  RawCell clone() => RawCell()..mergeFromMessage(this);
+  Row clone() => Row()..mergeFromMessage(this);
   @$core.Deprecated(
   'Using this can add significant overhead to your binary. '
   'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
   'Will be removed in next major version')
-  RawCell copyWith(void Function(RawCell) updates) => super.copyWith((message) => updates(message as RawCell)) as RawCell; // ignore: deprecated_member_use
+  Row copyWith(void Function(Row) updates) => super.copyWith((message) => updates(message as Row)) as Row; // ignore: deprecated_member_use
   $pb.BuilderInfo get info_ => _i;
   @$core.pragma('dart2js:noInline')
-  static RawCell create() => RawCell._();
-  RawCell createEmptyInstance() => create();
-  static $pb.PbList<RawCell> createRepeated() => $pb.PbList<RawCell>();
+  static Row create() => Row._();
+  Row createEmptyInstance() => create();
+  static $pb.PbList<Row> createRepeated() => $pb.PbList<Row>();
   @$core.pragma('dart2js:noInline')
-  static RawCell getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<RawCell>(create);
-  static RawCell? _defaultInstance;
+  static Row getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Row>(create);
+  static Row? _defaultInstance;
 
   @$pb.TagNumber(1)
   $core.String get id => $_getSZ(0);
@@ -695,42 +305,16 @@ class RawCell extends $pb.GeneratedMessage {
   void clearId() => clearField(1);
 
   @$pb.TagNumber(2)
-  $core.String get rowId => $_getSZ(1);
-  @$pb.TagNumber(2)
-  set rowId($core.String v) { $_setString(1, v); }
-  @$pb.TagNumber(2)
-  $core.bool hasRowId() => $_has(1);
-  @$pb.TagNumber(2)
-  void clearRowId() => clearField(2);
+  $core.Map<$core.String, Cell> get cellByFieldId => $_getMap(1);
 
   @$pb.TagNumber(3)
-  $core.String get fieldId => $_getSZ(2);
+  $core.int get height => $_getIZ(2);
   @$pb.TagNumber(3)
-  set fieldId($core.String v) { $_setString(2, v); }
+  set height($core.int v) { $_setSignedInt32(2, v); }
   @$pb.TagNumber(3)
-  $core.bool hasFieldId() => $_has(2);
+  $core.bool hasHeight() => $_has(2);
   @$pb.TagNumber(3)
-  void clearFieldId() => clearField(3);
-
-  @$pb.TagNumber(4)
-  AnyData get data => $_getN(3);
-  @$pb.TagNumber(4)
-  set data(AnyData v) { setField(4, v); }
-  @$pb.TagNumber(4)
-  $core.bool hasData() => $_has(3);
-  @$pb.TagNumber(4)
-  void clearData() => clearField(4);
-  @$pb.TagNumber(4)
-  AnyData ensureData() => $_ensure(3);
-
-  @$pb.TagNumber(5)
-  $core.int get height => $_getIZ(4);
-  @$pb.TagNumber(5)
-  set height($core.int v) { $_setSignedInt32(4, v); }
-  @$pb.TagNumber(5)
-  $core.bool hasHeight() => $_has(4);
-  @$pb.TagNumber(5)
-  void clearHeight() => clearField(5);
+  void clearHeight() => clearField(3);
 }
 
 class RepeatedRow extends $pb.GeneratedMessage {
@@ -774,75 +358,6 @@ class RepeatedRow extends $pb.GeneratedMessage {
   $core.List<Row> get items => $_getList(0);
 }
 
-class Row extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Row', createEmptyInstance: create)
-    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id')
-    ..m<$core.String, Cell>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'cellByFieldId', entryClassName: 'Row.CellByFieldIdEntry', keyFieldType: $pb.PbFieldType.OS, valueFieldType: $pb.PbFieldType.OM, valueCreator: Cell.create)
-    ..a<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'height', $pb.PbFieldType.O3)
-    ..hasRequiredFields = false
-  ;
-
-  Row._() : super();
-  factory Row({
-    $core.String? id,
-    $core.Map<$core.String, Cell>? cellByFieldId,
-    $core.int? height,
-  }) {
-    final _result = create();
-    if (id != null) {
-      _result.id = id;
-    }
-    if (cellByFieldId != null) {
-      _result.cellByFieldId.addAll(cellByFieldId);
-    }
-    if (height != null) {
-      _result.height = height;
-    }
-    return _result;
-  }
-  factory Row.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
-  factory Row.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')
-  Row clone() => Row()..mergeFromMessage(this);
-  @$core.Deprecated(
-  'Using this can add significant overhead to your binary. '
-  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
-  'Will be removed in next major version')
-  Row copyWith(void Function(Row) updates) => super.copyWith((message) => updates(message as Row)) as Row; // ignore: deprecated_member_use
-  $pb.BuilderInfo get info_ => _i;
-  @$core.pragma('dart2js:noInline')
-  static Row create() => Row._();
-  Row createEmptyInstance() => create();
-  static $pb.PbList<Row> createRepeated() => $pb.PbList<Row>();
-  @$core.pragma('dart2js:noInline')
-  static Row getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Row>(create);
-  static Row? _defaultInstance;
-
-  @$pb.TagNumber(1)
-  $core.String get id => $_getSZ(0);
-  @$pb.TagNumber(1)
-  set id($core.String v) { $_setString(0, v); }
-  @$pb.TagNumber(1)
-  $core.bool hasId() => $_has(0);
-  @$pb.TagNumber(1)
-  void clearId() => clearField(1);
-
-  @$pb.TagNumber(2)
-  $core.Map<$core.String, Cell> get cellByFieldId => $_getMap(1);
-
-  @$pb.TagNumber(3)
-  $core.int get height => $_getIZ(2);
-  @$pb.TagNumber(3)
-  set height($core.int v) { $_setSignedInt32(2, v); }
-  @$pb.TagNumber(3)
-  $core.bool hasHeight() => $_has(2);
-  @$pb.TagNumber(3)
-  void clearHeight() => clearField(3);
-}
-
 class Cell extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Cell', createEmptyInstance: create)
     ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id')
@@ -918,95 +433,6 @@ class Cell extends $pb.GeneratedMessage {
   void clearContent() => clearField(3);
 }
 
-class CellChangeset extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CellChangeset', createEmptyInstance: create)
-    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id')
-    ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId')
-    ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId')
-    ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data')
-    ..hasRequiredFields = false
-  ;
-
-  CellChangeset._() : super();
-  factory CellChangeset({
-    $core.String? id,
-    $core.String? rowId,
-    $core.String? fieldId,
-    $core.String? data,
-  }) {
-    final _result = create();
-    if (id != null) {
-      _result.id = id;
-    }
-    if (rowId != null) {
-      _result.rowId = rowId;
-    }
-    if (fieldId != null) {
-      _result.fieldId = fieldId;
-    }
-    if (data != null) {
-      _result.data = data;
-    }
-    return _result;
-  }
-  factory CellChangeset.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
-  factory CellChangeset.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')
-  CellChangeset clone() => CellChangeset()..mergeFromMessage(this);
-  @$core.Deprecated(
-  'Using this can add significant overhead to your binary. '
-  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
-  'Will be removed in next major version')
-  CellChangeset copyWith(void Function(CellChangeset) updates) => super.copyWith((message) => updates(message as CellChangeset)) as CellChangeset; // ignore: deprecated_member_use
-  $pb.BuilderInfo get info_ => _i;
-  @$core.pragma('dart2js:noInline')
-  static CellChangeset create() => CellChangeset._();
-  CellChangeset createEmptyInstance() => create();
-  static $pb.PbList<CellChangeset> createRepeated() => $pb.PbList<CellChangeset>();
-  @$core.pragma('dart2js:noInline')
-  static CellChangeset getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<CellChangeset>(create);
-  static CellChangeset? _defaultInstance;
-
-  @$pb.TagNumber(1)
-  $core.String get id => $_getSZ(0);
-  @$pb.TagNumber(1)
-  set id($core.String v) { $_setString(0, v); }
-  @$pb.TagNumber(1)
-  $core.bool hasId() => $_has(0);
-  @$pb.TagNumber(1)
-  void clearId() => clearField(1);
-
-  @$pb.TagNumber(2)
-  $core.String get rowId => $_getSZ(1);
-  @$pb.TagNumber(2)
-  set rowId($core.String v) { $_setString(1, v); }
-  @$pb.TagNumber(2)
-  $core.bool hasRowId() => $_has(1);
-  @$pb.TagNumber(2)
-  void clearRowId() => clearField(2);
-
-  @$pb.TagNumber(3)
-  $core.String get fieldId => $_getSZ(2);
-  @$pb.TagNumber(3)
-  set fieldId($core.String v) { $_setString(2, v); }
-  @$pb.TagNumber(3)
-  $core.bool hasFieldId() => $_has(2);
-  @$pb.TagNumber(3)
-  void clearFieldId() => clearField(3);
-
-  @$pb.TagNumber(4)
-  $core.String get data => $_getSZ(3);
-  @$pb.TagNumber(4)
-  set data($core.String v) { $_setString(3, v); }
-  @$pb.TagNumber(4)
-  $core.bool hasData() => $_has(3);
-  @$pb.TagNumber(4)
-  void clearData() => clearField(4);
-}
-
 class CreateGridPayload extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CreateGridPayload', createEmptyInstance: create)
     ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name')

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

@@ -5,30 +5,3 @@
 // @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
 
-// ignore_for_file: UNDEFINED_SHOWN_NAME
-import 'dart:core' as $core;
-import 'package:protobuf/protobuf.dart' as $pb;
-
-class FieldType extends $pb.ProtobufEnum {
-  static const FieldType RichText = FieldType._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'RichText');
-  static const FieldType Number = FieldType._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Number');
-  static const FieldType DateTime = FieldType._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DateTime');
-  static const FieldType SingleSelect = FieldType._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'SingleSelect');
-  static const FieldType MultiSelect = FieldType._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'MultiSelect');
-  static const FieldType Checkbox = FieldType._(5, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Checkbox');
-
-  static const $core.List<FieldType> values = <FieldType> [
-    RichText,
-    Number,
-    DateTime,
-    SingleSelect,
-    MultiSelect,
-    Checkbox,
-  ];
-
-  static final $core.Map<$core.int, FieldType> _byValue = $pb.ProtobufEnum.initByValue(values);
-  static FieldType? valueOf($core.int value) => _byValue[value];
-
-  const FieldType._($core.int v, $core.String n) : super(v, n);
-}
-

+ 16 - 122
frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart

@@ -8,44 +8,28 @@
 import 'dart:core' as $core;
 import 'dart:convert' as $convert;
 import 'dart:typed_data' as $typed_data;
-@$core.Deprecated('Use fieldTypeDescriptor instead')
-const FieldType$json = const {
-  '1': 'FieldType',
-  '2': const [
-    const {'1': 'RichText', '2': 0},
-    const {'1': 'Number', '2': 1},
-    const {'1': 'DateTime', '2': 2},
-    const {'1': 'SingleSelect', '2': 3},
-    const {'1': 'MultiSelect', '2': 4},
-    const {'1': 'Checkbox', '2': 5},
-  ],
-};
-
-/// Descriptor for `FieldType`. Decode as a `google.protobuf.EnumDescriptorProto`.
-final $typed_data.Uint8List fieldTypeDescriptor = $convert.base64Decode('CglGaWVsZFR5cGUSDAoIUmljaFRleHQQABIKCgZOdW1iZXIQARIMCghEYXRlVGltZRACEhAKDFNpbmdsZVNlbGVjdBADEg8KC011bHRpU2VsZWN0EAQSDAoIQ2hlY2tib3gQBQ==');
 @$core.Deprecated('Use gridDescriptor instead')
 const Grid$json = const {
   '1': 'Grid',
   '2': const [
     const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
-    const {'1': 'field_orders', '3': 2, '4': 1, '5': 11, '6': '.RepeatedFieldOrder', '10': 'fieldOrders'},
-    const {'1': 'row_orders', '3': 3, '4': 1, '5': 11, '6': '.RepeatedRowOrder', '10': 'rowOrders'},
+    const {'1': 'field_orders', '3': 2, '4': 3, '5': 11, '6': '.FieldOrder', '10': 'fieldOrders'},
+    const {'1': 'row_orders', '3': 3, '4': 3, '5': 11, '6': '.RowOrder', '10': 'rowOrders'},
   ],
 };
 
 /// Descriptor for `Grid`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List gridDescriptor = $convert.base64Decode('CgRHcmlkEg4KAmlkGAEgASgJUgJpZBI2CgxmaWVsZF9vcmRlcnMYAiABKAsyEy5SZXBlYXRlZEZpZWxkT3JkZXJSC2ZpZWxkT3JkZXJzEjAKCnJvd19vcmRlcnMYAyABKAsyES5SZXBlYXRlZFJvd09yZGVyUglyb3dPcmRlcnM=');
+final $typed_data.Uint8List gridDescriptor = $convert.base64Decode('CgRHcmlkEg4KAmlkGAEgASgJUgJpZBIuCgxmaWVsZF9vcmRlcnMYAiADKAsyCy5GaWVsZE9yZGVyUgtmaWVsZE9yZGVycxIoCgpyb3dfb3JkZXJzGAMgAygLMgkuUm93T3JkZXJSCXJvd09yZGVycw==');
 @$core.Deprecated('Use fieldOrderDescriptor instead')
 const FieldOrder$json = const {
   '1': 'FieldOrder',
   '2': const [
     const {'1': 'field_id', '3': 1, '4': 1, '5': 9, '10': 'fieldId'},
-    const {'1': 'visibility', '3': 2, '4': 1, '5': 8, '10': 'visibility'},
   ],
 };
 
 /// Descriptor for `FieldOrder`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List fieldOrderDescriptor = $convert.base64Decode('CgpGaWVsZE9yZGVyEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElkEh4KCnZpc2liaWxpdHkYAiABKAhSCnZpc2liaWxpdHk=');
+final $typed_data.Uint8List fieldOrderDescriptor = $convert.base64Decode('CgpGaWVsZE9yZGVyEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElk');
 @$core.Deprecated('Use repeatedFieldOrderDescriptor instead')
 const RepeatedFieldOrder$json = const {
   '1': 'RepeatedFieldOrder',
@@ -56,55 +40,16 @@ const RepeatedFieldOrder$json = const {
 
 /// Descriptor for `RepeatedFieldOrder`. Decode as a `google.protobuf.DescriptorProto`.
 final $typed_data.Uint8List repeatedFieldOrderDescriptor = $convert.base64Decode('ChJSZXBlYXRlZEZpZWxkT3JkZXISIQoFaXRlbXMYASADKAsyCy5GaWVsZE9yZGVyUgVpdGVtcw==');
-@$core.Deprecated('Use fieldDescriptor instead')
-const Field$json = const {
-  '1': 'Field',
-  '2': const [
-    const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
-    const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'},
-    const {'1': 'desc', '3': 3, '4': 1, '5': 9, '10': 'desc'},
-    const {'1': 'field_type', '3': 4, '4': 1, '5': 14, '6': '.FieldType', '10': 'fieldType'},
-    const {'1': 'frozen', '3': 5, '4': 1, '5': 8, '10': 'frozen'},
-    const {'1': 'width', '3': 6, '4': 1, '5': 5, '10': 'width'},
-    const {'1': 'type_options', '3': 7, '4': 1, '5': 11, '6': '.AnyData', '10': 'typeOptions'},
-  ],
-};
-
-/// Descriptor for `Field`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List fieldDescriptor = $convert.base64Decode('CgVGaWVsZBIOCgJpZBgBIAEoCVICaWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEikKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVSCWZpZWxkVHlwZRIWCgZmcm96ZW4YBSABKAhSBmZyb3plbhIUCgV3aWR0aBgGIAEoBVIFd2lkdGgSKwoMdHlwZV9vcHRpb25zGAcgASgLMgguQW55RGF0YVILdHlwZU9wdGlvbnM=');
-@$core.Deprecated('Use repeatedFieldDescriptor instead')
-const RepeatedField$json = const {
-  '1': 'RepeatedField',
-  '2': const [
-    const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.Field', '10': 'items'},
-  ],
-};
-
-/// Descriptor for `RepeatedField`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List repeatedFieldDescriptor = $convert.base64Decode('Cg1SZXBlYXRlZEZpZWxkEhwKBWl0ZW1zGAEgAygLMgYuRmllbGRSBWl0ZW1z');
-@$core.Deprecated('Use anyDataDescriptor instead')
-const AnyData$json = const {
-  '1': 'AnyData',
-  '2': const [
-    const {'1': 'type_id', '3': 1, '4': 1, '5': 9, '10': 'typeId'},
-    const {'1': 'value', '3': 2, '4': 1, '5': 12, '10': 'value'},
-  ],
-};
-
-/// Descriptor for `AnyData`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List anyDataDescriptor = $convert.base64Decode('CgdBbnlEYXRhEhcKB3R5cGVfaWQYASABKAlSBnR5cGVJZBIUCgV2YWx1ZRgCIAEoDFIFdmFsdWU=');
 @$core.Deprecated('Use rowOrderDescriptor instead')
 const RowOrder$json = const {
   '1': 'RowOrder',
   '2': const [
-    const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'},
-    const {'1': 'row_id', '3': 2, '4': 1, '5': 9, '10': 'rowId'},
-    const {'1': 'visibility', '3': 3, '4': 1, '5': 8, '10': 'visibility'},
+    const {'1': 'row_id', '3': 1, '4': 1, '5': 9, '10': 'rowId'},
   ],
 };
 
 /// Descriptor for `RowOrder`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List rowOrderDescriptor = $convert.base64Decode('CghSb3dPcmRlchIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSFQoGcm93X2lkGAIgASgJUgVyb3dJZBIeCgp2aXNpYmlsaXR5GAMgASgIUgp2aXNpYmlsaXR5');
+final $typed_data.Uint8List rowOrderDescriptor = $convert.base64Decode('CghSb3dPcmRlchIVCgZyb3dfaWQYASABKAlSBXJvd0lk');
 @$core.Deprecated('Use repeatedRowOrderDescriptor instead')
 const RepeatedRowOrder$json = const {
   '1': 'RepeatedRowOrder',
@@ -115,54 +60,6 @@ const RepeatedRowOrder$json = const {
 
 /// Descriptor for `RepeatedRowOrder`. Decode as a `google.protobuf.DescriptorProto`.
 final $typed_data.Uint8List repeatedRowOrderDescriptor = $convert.base64Decode('ChBSZXBlYXRlZFJvd09yZGVyEh8KBWl0ZW1zGAEgAygLMgkuUm93T3JkZXJSBWl0ZW1z');
-@$core.Deprecated('Use rawRowDescriptor instead')
-const RawRow$json = const {
-  '1': 'RawRow',
-  '2': const [
-    const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
-    const {'1': 'grid_id', '3': 2, '4': 1, '5': 9, '10': 'gridId'},
-    const {'1': 'cell_by_field_id', '3': 3, '4': 3, '5': 11, '6': '.RawRow.CellByFieldIdEntry', '10': 'cellByFieldId'},
-    const {'1': 'height', '3': 4, '4': 1, '5': 5, '10': 'height'},
-  ],
-  '3': const [RawRow_CellByFieldIdEntry$json],
-};
-
-@$core.Deprecated('Use rawRowDescriptor instead')
-const RawRow_CellByFieldIdEntry$json = const {
-  '1': 'CellByFieldIdEntry',
-  '2': const [
-    const {'1': 'key', '3': 1, '4': 1, '5': 9, '10': 'key'},
-    const {'1': 'value', '3': 2, '4': 1, '5': 11, '6': '.RawCell', '10': 'value'},
-  ],
-  '7': const {'7': true},
-};
-
-/// Descriptor for `RawRow`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List rawRowDescriptor = $convert.base64Decode('CgZSYXdSb3cSDgoCaWQYASABKAlSAmlkEhcKB2dyaWRfaWQYAiABKAlSBmdyaWRJZBJDChBjZWxsX2J5X2ZpZWxkX2lkGAMgAygLMhouUmF3Um93LkNlbGxCeUZpZWxkSWRFbnRyeVINY2VsbEJ5RmllbGRJZBIWCgZoZWlnaHQYBCABKAVSBmhlaWdodBpKChJDZWxsQnlGaWVsZElkRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSHgoFdmFsdWUYAiABKAsyCC5SYXdDZWxsUgV2YWx1ZToCOAE=');
-@$core.Deprecated('Use rawCellDescriptor instead')
-const RawCell$json = const {
-  '1': 'RawCell',
-  '2': const [
-    const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
-    const {'1': 'row_id', '3': 2, '4': 1, '5': 9, '10': 'rowId'},
-    const {'1': 'field_id', '3': 3, '4': 1, '5': 9, '10': 'fieldId'},
-    const {'1': 'data', '3': 4, '4': 1, '5': 11, '6': '.AnyData', '10': 'data'},
-    const {'1': 'height', '3': 5, '4': 1, '5': 5, '10': 'height'},
-  ],
-};
-
-/// Descriptor for `RawCell`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List rawCellDescriptor = $convert.base64Decode('CgdSYXdDZWxsEg4KAmlkGAEgASgJUgJpZBIVCgZyb3dfaWQYAiABKAlSBXJvd0lkEhkKCGZpZWxkX2lkGAMgASgJUgdmaWVsZElkEhwKBGRhdGEYBCABKAsyCC5BbnlEYXRhUgRkYXRhEhYKBmhlaWdodBgFIAEoBVIGaGVpZ2h0');
-@$core.Deprecated('Use repeatedRowDescriptor instead')
-const RepeatedRow$json = const {
-  '1': 'RepeatedRow',
-  '2': const [
-    const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.Row', '10': 'items'},
-  ],
-};
-
-/// Descriptor for `RepeatedRow`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List repeatedRowDescriptor = $convert.base64Decode('CgtSZXBlYXRlZFJvdxIaCgVpdGVtcxgBIAMoCzIELlJvd1IFaXRlbXM=');
 @$core.Deprecated('Use rowDescriptor instead')
 const Row$json = const {
   '1': 'Row',
@@ -186,6 +83,16 @@ const Row_CellByFieldIdEntry$json = const {
 
 /// Descriptor for `Row`. Decode as a `google.protobuf.DescriptorProto`.
 final $typed_data.Uint8List rowDescriptor = $convert.base64Decode('CgNSb3cSDgoCaWQYASABKAlSAmlkEkAKEGNlbGxfYnlfZmllbGRfaWQYAiADKAsyFy5Sb3cuQ2VsbEJ5RmllbGRJZEVudHJ5Ug1jZWxsQnlGaWVsZElkEhYKBmhlaWdodBgDIAEoBVIGaGVpZ2h0GkcKEkNlbGxCeUZpZWxkSWRFbnRyeRIQCgNrZXkYASABKAlSA2tleRIbCgV2YWx1ZRgCIAEoCzIFLkNlbGxSBXZhbHVlOgI4AQ==');
+@$core.Deprecated('Use repeatedRowDescriptor instead')
+const RepeatedRow$json = const {
+  '1': 'RepeatedRow',
+  '2': const [
+    const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.Row', '10': 'items'},
+  ],
+};
+
+/// Descriptor for `RepeatedRow`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List repeatedRowDescriptor = $convert.base64Decode('CgtSZXBlYXRlZFJvdxIaCgVpdGVtcxgBIAMoCzIELlJvd1IFaXRlbXM=');
 @$core.Deprecated('Use cellDescriptor instead')
 const Cell$json = const {
   '1': 'Cell',
@@ -198,19 +105,6 @@ const Cell$json = const {
 
 /// Descriptor for `Cell`. Decode as a `google.protobuf.DescriptorProto`.
 final $typed_data.Uint8List cellDescriptor = $convert.base64Decode('CgRDZWxsEg4KAmlkGAEgASgJUgJpZBIZCghmaWVsZF9pZBgCIAEoCVIHZmllbGRJZBIYCgdjb250ZW50GAMgASgJUgdjb250ZW50');
-@$core.Deprecated('Use cellChangesetDescriptor instead')
-const CellChangeset$json = const {
-  '1': 'CellChangeset',
-  '2': const [
-    const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
-    const {'1': 'row_id', '3': 2, '4': 1, '5': 9, '10': 'rowId'},
-    const {'1': 'field_id', '3': 3, '4': 1, '5': 9, '10': 'fieldId'},
-    const {'1': 'data', '3': 4, '4': 1, '5': 9, '10': 'data'},
-  ],
-};
-
-/// Descriptor for `CellChangeset`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List cellChangesetDescriptor = $convert.base64Decode('Cg1DZWxsQ2hhbmdlc2V0Eg4KAmlkGAEgASgJUgJpZBIVCgZyb3dfaWQYAiABKAlSBXJvd0lkEhkKCGZpZWxkX2lkGAMgASgJUgdmaWVsZElkEhIKBGRhdGEYBCABKAlSBGRhdGE=');
 @$core.Deprecated('Use createGridPayloadDescriptor instead')
 const CreateGridPayload$json = const {
   '1': 'CreateGridPayload',

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

@@ -0,0 +1,584 @@
+///
+//  Generated code. Do not modify.
+//  source: meta.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;
+
+import 'meta.pbenum.dart';
+
+export 'meta.pbenum.dart';
+
+class GridMeta extends $pb.GeneratedMessage {
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridMeta', createEmptyInstance: create)
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId')
+    ..pc<Field>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fields', $pb.PbFieldType.PM, subBuilder: Field.create)
+    ..pc<RowMeta>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rows', $pb.PbFieldType.PM, subBuilder: RowMeta.create)
+    ..hasRequiredFields = false
+  ;
+
+  GridMeta._() : super();
+  factory GridMeta({
+    $core.String? gridId,
+    $core.Iterable<Field>? fields,
+    $core.Iterable<RowMeta>? rows,
+  }) {
+    final _result = create();
+    if (gridId != null) {
+      _result.gridId = gridId;
+    }
+    if (fields != null) {
+      _result.fields.addAll(fields);
+    }
+    if (rows != null) {
+      _result.rows.addAll(rows);
+    }
+    return _result;
+  }
+  factory GridMeta.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory GridMeta.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')
+  GridMeta clone() => GridMeta()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  GridMeta copyWith(void Function(GridMeta) updates) => super.copyWith((message) => updates(message as GridMeta)) as GridMeta; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static GridMeta create() => GridMeta._();
+  GridMeta createEmptyInstance() => create();
+  static $pb.PbList<GridMeta> createRepeated() => $pb.PbList<GridMeta>();
+  @$core.pragma('dart2js:noInline')
+  static GridMeta getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<GridMeta>(create);
+  static GridMeta? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.String get gridId => $_getSZ(0);
+  @$pb.TagNumber(1)
+  set gridId($core.String v) { $_setString(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasGridId() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearGridId() => clearField(1);
+
+  @$pb.TagNumber(2)
+  $core.List<Field> get fields => $_getList(1);
+
+  @$pb.TagNumber(3)
+  $core.List<RowMeta> get rows => $_getList(2);
+}
+
+class GridBlock extends $pb.GeneratedMessage {
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlock', createEmptyInstance: create)
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id')
+    ..pc<RowMeta>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rows', $pb.PbFieldType.PM, subBuilder: RowMeta.create)
+    ..hasRequiredFields = false
+  ;
+
+  GridBlock._() : super();
+  factory GridBlock({
+    $core.String? id,
+    $core.Iterable<RowMeta>? rows,
+  }) {
+    final _result = create();
+    if (id != null) {
+      _result.id = id;
+    }
+    if (rows != null) {
+      _result.rows.addAll(rows);
+    }
+    return _result;
+  }
+  factory GridBlock.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory GridBlock.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')
+  GridBlock clone() => GridBlock()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  GridBlock copyWith(void Function(GridBlock) updates) => super.copyWith((message) => updates(message as GridBlock)) as GridBlock; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static GridBlock create() => GridBlock._();
+  GridBlock createEmptyInstance() => create();
+  static $pb.PbList<GridBlock> createRepeated() => $pb.PbList<GridBlock>();
+  @$core.pragma('dart2js:noInline')
+  static GridBlock getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<GridBlock>(create);
+  static GridBlock? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.String get id => $_getSZ(0);
+  @$pb.TagNumber(1)
+  set id($core.String v) { $_setString(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasId() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearId() => clearField(1);
+
+  @$pb.TagNumber(2)
+  $core.List<RowMeta> get rows => $_getList(1);
+}
+
+class Field extends $pb.GeneratedMessage {
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Field', createEmptyInstance: create)
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id')
+    ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name')
+    ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc')
+    ..e<FieldType>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldType', $pb.PbFieldType.OE, defaultOrMaker: FieldType.RichText, valueOf: FieldType.valueOf, enumValues: FieldType.values)
+    ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'frozen')
+    ..aOB(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility')
+    ..a<$core.int>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'width', $pb.PbFieldType.O3)
+    ..aOM<AnyData>(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptions', subBuilder: AnyData.create)
+    ..hasRequiredFields = false
+  ;
+
+  Field._() : super();
+  factory Field({
+    $core.String? id,
+    $core.String? name,
+    $core.String? desc,
+    FieldType? fieldType,
+    $core.bool? frozen,
+    $core.bool? visibility,
+    $core.int? width,
+    AnyData? typeOptions,
+  }) {
+    final _result = create();
+    if (id != null) {
+      _result.id = id;
+    }
+    if (name != null) {
+      _result.name = name;
+    }
+    if (desc != null) {
+      _result.desc = desc;
+    }
+    if (fieldType != null) {
+      _result.fieldType = fieldType;
+    }
+    if (frozen != null) {
+      _result.frozen = frozen;
+    }
+    if (visibility != null) {
+      _result.visibility = visibility;
+    }
+    if (width != null) {
+      _result.width = width;
+    }
+    if (typeOptions != null) {
+      _result.typeOptions = typeOptions;
+    }
+    return _result;
+  }
+  factory Field.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory Field.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')
+  Field clone() => Field()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  Field copyWith(void Function(Field) updates) => super.copyWith((message) => updates(message as Field)) as Field; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static Field create() => Field._();
+  Field createEmptyInstance() => create();
+  static $pb.PbList<Field> createRepeated() => $pb.PbList<Field>();
+  @$core.pragma('dart2js:noInline')
+  static Field getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Field>(create);
+  static Field? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.String get id => $_getSZ(0);
+  @$pb.TagNumber(1)
+  set id($core.String v) { $_setString(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasId() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearId() => clearField(1);
+
+  @$pb.TagNumber(2)
+  $core.String get name => $_getSZ(1);
+  @$pb.TagNumber(2)
+  set name($core.String v) { $_setString(1, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasName() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearName() => clearField(2);
+
+  @$pb.TagNumber(3)
+  $core.String get desc => $_getSZ(2);
+  @$pb.TagNumber(3)
+  set desc($core.String v) { $_setString(2, v); }
+  @$pb.TagNumber(3)
+  $core.bool hasDesc() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearDesc() => clearField(3);
+
+  @$pb.TagNumber(4)
+  FieldType get fieldType => $_getN(3);
+  @$pb.TagNumber(4)
+  set fieldType(FieldType v) { setField(4, v); }
+  @$pb.TagNumber(4)
+  $core.bool hasFieldType() => $_has(3);
+  @$pb.TagNumber(4)
+  void clearFieldType() => clearField(4);
+
+  @$pb.TagNumber(5)
+  $core.bool get frozen => $_getBF(4);
+  @$pb.TagNumber(5)
+  set frozen($core.bool v) { $_setBool(4, v); }
+  @$pb.TagNumber(5)
+  $core.bool hasFrozen() => $_has(4);
+  @$pb.TagNumber(5)
+  void clearFrozen() => clearField(5);
+
+  @$pb.TagNumber(6)
+  $core.bool get visibility => $_getBF(5);
+  @$pb.TagNumber(6)
+  set visibility($core.bool v) { $_setBool(5, v); }
+  @$pb.TagNumber(6)
+  $core.bool hasVisibility() => $_has(5);
+  @$pb.TagNumber(6)
+  void clearVisibility() => clearField(6);
+
+  @$pb.TagNumber(7)
+  $core.int get width => $_getIZ(6);
+  @$pb.TagNumber(7)
+  set width($core.int v) { $_setSignedInt32(6, v); }
+  @$pb.TagNumber(7)
+  $core.bool hasWidth() => $_has(6);
+  @$pb.TagNumber(7)
+  void clearWidth() => clearField(7);
+
+  @$pb.TagNumber(8)
+  AnyData get typeOptions => $_getN(7);
+  @$pb.TagNumber(8)
+  set typeOptions(AnyData v) { setField(8, v); }
+  @$pb.TagNumber(8)
+  $core.bool hasTypeOptions() => $_has(7);
+  @$pb.TagNumber(8)
+  void clearTypeOptions() => clearField(8);
+  @$pb.TagNumber(8)
+  AnyData ensureTypeOptions() => $_ensure(7);
+}
+
+class RepeatedField extends $pb.GeneratedMessage {
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedField', createEmptyInstance: create)
+    ..pc<Field>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: Field.create)
+    ..hasRequiredFields = false
+  ;
+
+  RepeatedField._() : super();
+  factory RepeatedField({
+    $core.Iterable<Field>? items,
+  }) {
+    final _result = create();
+    if (items != null) {
+      _result.items.addAll(items);
+    }
+    return _result;
+  }
+  factory RepeatedField.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory RepeatedField.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')
+  RepeatedField clone() => RepeatedField()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  RepeatedField copyWith(void Function(RepeatedField) updates) => super.copyWith((message) => updates(message as RepeatedField)) as RepeatedField; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static RepeatedField create() => RepeatedField._();
+  RepeatedField createEmptyInstance() => create();
+  static $pb.PbList<RepeatedField> createRepeated() => $pb.PbList<RepeatedField>();
+  @$core.pragma('dart2js:noInline')
+  static RepeatedField getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<RepeatedField>(create);
+  static RepeatedField? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.List<Field> get items => $_getList(0);
+}
+
+class AnyData extends $pb.GeneratedMessage {
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'AnyData', createEmptyInstance: create)
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeId')
+    ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'value', $pb.PbFieldType.OY)
+    ..hasRequiredFields = false
+  ;
+
+  AnyData._() : super();
+  factory AnyData({
+    $core.String? typeId,
+    $core.List<$core.int>? value,
+  }) {
+    final _result = create();
+    if (typeId != null) {
+      _result.typeId = typeId;
+    }
+    if (value != null) {
+      _result.value = value;
+    }
+    return _result;
+  }
+  factory AnyData.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory AnyData.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')
+  AnyData clone() => AnyData()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  AnyData copyWith(void Function(AnyData) updates) => super.copyWith((message) => updates(message as AnyData)) as AnyData; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static AnyData create() => AnyData._();
+  AnyData createEmptyInstance() => create();
+  static $pb.PbList<AnyData> createRepeated() => $pb.PbList<AnyData>();
+  @$core.pragma('dart2js:noInline')
+  static AnyData getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<AnyData>(create);
+  static AnyData? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.String get typeId => $_getSZ(0);
+  @$pb.TagNumber(1)
+  set typeId($core.String v) { $_setString(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasTypeId() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearTypeId() => clearField(1);
+
+  @$pb.TagNumber(2)
+  $core.List<$core.int> get value => $_getN(1);
+  @$pb.TagNumber(2)
+  set value($core.List<$core.int> v) { $_setBytes(1, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasValue() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearValue() => clearField(2);
+}
+
+class RowMeta extends $pb.GeneratedMessage {
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RowMeta', createEmptyInstance: create)
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id')
+    ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId')
+    ..m<$core.String, CellMeta>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'cellByFieldId', entryClassName: 'RowMeta.CellByFieldIdEntry', keyFieldType: $pb.PbFieldType.OS, valueFieldType: $pb.PbFieldType.OM, valueCreator: CellMeta.create)
+    ..a<$core.int>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'height', $pb.PbFieldType.O3)
+    ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility')
+    ..hasRequiredFields = false
+  ;
+
+  RowMeta._() : super();
+  factory RowMeta({
+    $core.String? id,
+    $core.String? gridId,
+    $core.Map<$core.String, CellMeta>? cellByFieldId,
+    $core.int? height,
+    $core.bool? visibility,
+  }) {
+    final _result = create();
+    if (id != null) {
+      _result.id = id;
+    }
+    if (gridId != null) {
+      _result.gridId = gridId;
+    }
+    if (cellByFieldId != null) {
+      _result.cellByFieldId.addAll(cellByFieldId);
+    }
+    if (height != null) {
+      _result.height = height;
+    }
+    if (visibility != null) {
+      _result.visibility = visibility;
+    }
+    return _result;
+  }
+  factory RowMeta.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory RowMeta.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')
+  RowMeta clone() => RowMeta()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  RowMeta copyWith(void Function(RowMeta) updates) => super.copyWith((message) => updates(message as RowMeta)) as RowMeta; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static RowMeta create() => RowMeta._();
+  RowMeta createEmptyInstance() => create();
+  static $pb.PbList<RowMeta> createRepeated() => $pb.PbList<RowMeta>();
+  @$core.pragma('dart2js:noInline')
+  static RowMeta getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<RowMeta>(create);
+  static RowMeta? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.String get id => $_getSZ(0);
+  @$pb.TagNumber(1)
+  set id($core.String v) { $_setString(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasId() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearId() => clearField(1);
+
+  @$pb.TagNumber(2)
+  $core.String get gridId => $_getSZ(1);
+  @$pb.TagNumber(2)
+  set gridId($core.String v) { $_setString(1, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasGridId() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearGridId() => clearField(2);
+
+  @$pb.TagNumber(3)
+  $core.Map<$core.String, CellMeta> get cellByFieldId => $_getMap(2);
+
+  @$pb.TagNumber(4)
+  $core.int get height => $_getIZ(3);
+  @$pb.TagNumber(4)
+  set height($core.int v) { $_setSignedInt32(3, v); }
+  @$pb.TagNumber(4)
+  $core.bool hasHeight() => $_has(3);
+  @$pb.TagNumber(4)
+  void clearHeight() => clearField(4);
+
+  @$pb.TagNumber(5)
+  $core.bool get visibility => $_getBF(4);
+  @$pb.TagNumber(5)
+  set visibility($core.bool v) { $_setBool(4, v); }
+  @$pb.TagNumber(5)
+  $core.bool hasVisibility() => $_has(4);
+  @$pb.TagNumber(5)
+  void clearVisibility() => clearField(5);
+}
+
+class CellMeta extends $pb.GeneratedMessage {
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CellMeta', createEmptyInstance: create)
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id')
+    ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId')
+    ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId')
+    ..aOM<AnyData>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data', subBuilder: AnyData.create)
+    ..a<$core.int>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'height', $pb.PbFieldType.O3)
+    ..hasRequiredFields = false
+  ;
+
+  CellMeta._() : super();
+  factory CellMeta({
+    $core.String? id,
+    $core.String? rowId,
+    $core.String? fieldId,
+    AnyData? data,
+    $core.int? height,
+  }) {
+    final _result = create();
+    if (id != null) {
+      _result.id = id;
+    }
+    if (rowId != null) {
+      _result.rowId = rowId;
+    }
+    if (fieldId != null) {
+      _result.fieldId = fieldId;
+    }
+    if (data != null) {
+      _result.data = data;
+    }
+    if (height != null) {
+      _result.height = height;
+    }
+    return _result;
+  }
+  factory CellMeta.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory CellMeta.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')
+  CellMeta clone() => CellMeta()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  CellMeta copyWith(void Function(CellMeta) updates) => super.copyWith((message) => updates(message as CellMeta)) as CellMeta; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static CellMeta create() => CellMeta._();
+  CellMeta createEmptyInstance() => create();
+  static $pb.PbList<CellMeta> createRepeated() => $pb.PbList<CellMeta>();
+  @$core.pragma('dart2js:noInline')
+  static CellMeta getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<CellMeta>(create);
+  static CellMeta? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.String get id => $_getSZ(0);
+  @$pb.TagNumber(1)
+  set id($core.String v) { $_setString(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasId() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearId() => clearField(1);
+
+  @$pb.TagNumber(2)
+  $core.String get rowId => $_getSZ(1);
+  @$pb.TagNumber(2)
+  set rowId($core.String v) { $_setString(1, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasRowId() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearRowId() => clearField(2);
+
+  @$pb.TagNumber(3)
+  $core.String get fieldId => $_getSZ(2);
+  @$pb.TagNumber(3)
+  set fieldId($core.String v) { $_setString(2, v); }
+  @$pb.TagNumber(3)
+  $core.bool hasFieldId() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearFieldId() => clearField(3);
+
+  @$pb.TagNumber(4)
+  AnyData get data => $_getN(3);
+  @$pb.TagNumber(4)
+  set data(AnyData v) { setField(4, v); }
+  @$pb.TagNumber(4)
+  $core.bool hasData() => $_has(3);
+  @$pb.TagNumber(4)
+  void clearData() => clearField(4);
+  @$pb.TagNumber(4)
+  AnyData ensureData() => $_ensure(3);
+
+  @$pb.TagNumber(5)
+  $core.int get height => $_getIZ(4);
+  @$pb.TagNumber(5)
+  set height($core.int v) { $_setSignedInt32(4, v); }
+  @$pb.TagNumber(5)
+  $core.bool hasHeight() => $_has(4);
+  @$pb.TagNumber(5)
+  void clearHeight() => clearField(5);
+}
+

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

@@ -0,0 +1,34 @@
+///
+//  Generated code. Do not modify.
+//  source: meta.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
+
+// ignore_for_file: UNDEFINED_SHOWN_NAME
+import 'dart:core' as $core;
+import 'package:protobuf/protobuf.dart' as $pb;
+
+class FieldType extends $pb.ProtobufEnum {
+  static const FieldType RichText = FieldType._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'RichText');
+  static const FieldType Number = FieldType._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Number');
+  static const FieldType DateTime = FieldType._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DateTime');
+  static const FieldType SingleSelect = FieldType._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'SingleSelect');
+  static const FieldType MultiSelect = FieldType._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'MultiSelect');
+  static const FieldType Checkbox = FieldType._(5, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Checkbox');
+
+  static const $core.List<FieldType> values = <FieldType> [
+    RichText,
+    Number,
+    DateTime,
+    SingleSelect,
+    MultiSelect,
+    Checkbox,
+  ];
+
+  static final $core.Map<$core.int, FieldType> _byValue = $pb.ProtobufEnum.initByValue(values);
+  static FieldType? valueOf($core.int value) => _byValue[value];
+
+  const FieldType._($core.int v, $core.String n) : super(v, n);
+}
+

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

@@ -0,0 +1,125 @@
+///
+//  Generated code. Do not modify.
+//  source: meta.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 fieldTypeDescriptor instead')
+const FieldType$json = const {
+  '1': 'FieldType',
+  '2': const [
+    const {'1': 'RichText', '2': 0},
+    const {'1': 'Number', '2': 1},
+    const {'1': 'DateTime', '2': 2},
+    const {'1': 'SingleSelect', '2': 3},
+    const {'1': 'MultiSelect', '2': 4},
+    const {'1': 'Checkbox', '2': 5},
+  ],
+};
+
+/// Descriptor for `FieldType`. Decode as a `google.protobuf.EnumDescriptorProto`.
+final $typed_data.Uint8List fieldTypeDescriptor = $convert.base64Decode('CglGaWVsZFR5cGUSDAoIUmljaFRleHQQABIKCgZOdW1iZXIQARIMCghEYXRlVGltZRACEhAKDFNpbmdsZVNlbGVjdBADEg8KC011bHRpU2VsZWN0EAQSDAoIQ2hlY2tib3gQBQ==');
+@$core.Deprecated('Use gridMetaDescriptor instead')
+const GridMeta$json = const {
+  '1': 'GridMeta',
+  '2': const [
+    const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'},
+    const {'1': 'fields', '3': 2, '4': 3, '5': 11, '6': '.Field', '10': 'fields'},
+    const {'1': 'rows', '3': 3, '4': 3, '5': 11, '6': '.RowMeta', '10': 'rows'},
+  ],
+};
+
+/// Descriptor for `GridMeta`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List gridMetaDescriptor = $convert.base64Decode('CghHcmlkTWV0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSHgoGZmllbGRzGAIgAygLMgYuRmllbGRSBmZpZWxkcxIcCgRyb3dzGAMgAygLMgguUm93TWV0YVIEcm93cw==');
+@$core.Deprecated('Use gridBlockDescriptor instead')
+const GridBlock$json = const {
+  '1': 'GridBlock',
+  '2': const [
+    const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
+    const {'1': 'rows', '3': 2, '4': 3, '5': 11, '6': '.RowMeta', '10': 'rows'},
+  ],
+};
+
+/// Descriptor for `GridBlock`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List gridBlockDescriptor = $convert.base64Decode('CglHcmlkQmxvY2sSDgoCaWQYASABKAlSAmlkEhwKBHJvd3MYAiADKAsyCC5Sb3dNZXRhUgRyb3dz');
+@$core.Deprecated('Use fieldDescriptor instead')
+const Field$json = const {
+  '1': 'Field',
+  '2': const [
+    const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
+    const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'},
+    const {'1': 'desc', '3': 3, '4': 1, '5': 9, '10': 'desc'},
+    const {'1': 'field_type', '3': 4, '4': 1, '5': 14, '6': '.FieldType', '10': 'fieldType'},
+    const {'1': 'frozen', '3': 5, '4': 1, '5': 8, '10': 'frozen'},
+    const {'1': 'visibility', '3': 6, '4': 1, '5': 8, '10': 'visibility'},
+    const {'1': 'width', '3': 7, '4': 1, '5': 5, '10': 'width'},
+    const {'1': 'type_options', '3': 8, '4': 1, '5': 11, '6': '.AnyData', '10': 'typeOptions'},
+  ],
+};
+
+/// Descriptor for `Field`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List fieldDescriptor = $convert.base64Decode('CgVGaWVsZBIOCgJpZBgBIAEoCVICaWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEikKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVSCWZpZWxkVHlwZRIWCgZmcm96ZW4YBSABKAhSBmZyb3plbhIeCgp2aXNpYmlsaXR5GAYgASgIUgp2aXNpYmlsaXR5EhQKBXdpZHRoGAcgASgFUgV3aWR0aBIrCgx0eXBlX29wdGlvbnMYCCABKAsyCC5BbnlEYXRhUgt0eXBlT3B0aW9ucw==');
+@$core.Deprecated('Use repeatedFieldDescriptor instead')
+const RepeatedField$json = const {
+  '1': 'RepeatedField',
+  '2': const [
+    const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.Field', '10': 'items'},
+  ],
+};
+
+/// Descriptor for `RepeatedField`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List repeatedFieldDescriptor = $convert.base64Decode('Cg1SZXBlYXRlZEZpZWxkEhwKBWl0ZW1zGAEgAygLMgYuRmllbGRSBWl0ZW1z');
+@$core.Deprecated('Use anyDataDescriptor instead')
+const AnyData$json = const {
+  '1': 'AnyData',
+  '2': const [
+    const {'1': 'type_id', '3': 1, '4': 1, '5': 9, '10': 'typeId'},
+    const {'1': 'value', '3': 2, '4': 1, '5': 12, '10': 'value'},
+  ],
+};
+
+/// Descriptor for `AnyData`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List anyDataDescriptor = $convert.base64Decode('CgdBbnlEYXRhEhcKB3R5cGVfaWQYASABKAlSBnR5cGVJZBIUCgV2YWx1ZRgCIAEoDFIFdmFsdWU=');
+@$core.Deprecated('Use rowMetaDescriptor instead')
+const RowMeta$json = const {
+  '1': 'RowMeta',
+  '2': const [
+    const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
+    const {'1': 'grid_id', '3': 2, '4': 1, '5': 9, '10': 'gridId'},
+    const {'1': 'cell_by_field_id', '3': 3, '4': 3, '5': 11, '6': '.RowMeta.CellByFieldIdEntry', '10': 'cellByFieldId'},
+    const {'1': 'height', '3': 4, '4': 1, '5': 5, '10': 'height'},
+    const {'1': 'visibility', '3': 5, '4': 1, '5': 8, '10': 'visibility'},
+  ],
+  '3': const [RowMeta_CellByFieldIdEntry$json],
+};
+
+@$core.Deprecated('Use rowMetaDescriptor instead')
+const RowMeta_CellByFieldIdEntry$json = const {
+  '1': 'CellByFieldIdEntry',
+  '2': const [
+    const {'1': 'key', '3': 1, '4': 1, '5': 9, '10': 'key'},
+    const {'1': 'value', '3': 2, '4': 1, '5': 11, '6': '.CellMeta', '10': 'value'},
+  ],
+  '7': const {'7': true},
+};
+
+/// Descriptor for `RowMeta`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List rowMetaDescriptor = $convert.base64Decode('CgdSb3dNZXRhEg4KAmlkGAEgASgJUgJpZBIXCgdncmlkX2lkGAIgASgJUgZncmlkSWQSRAoQY2VsbF9ieV9maWVsZF9pZBgDIAMoCzIbLlJvd01ldGEuQ2VsbEJ5RmllbGRJZEVudHJ5Ug1jZWxsQnlGaWVsZElkEhYKBmhlaWdodBgEIAEoBVIGaGVpZ2h0Eh4KCnZpc2liaWxpdHkYBSABKAhSCnZpc2liaWxpdHkaSwoSQ2VsbEJ5RmllbGRJZEVudHJ5EhAKA2tleRgBIAEoCVIDa2V5Eh8KBXZhbHVlGAIgASgLMgkuQ2VsbE1ldGFSBXZhbHVlOgI4AQ==');
+@$core.Deprecated('Use cellMetaDescriptor instead')
+const CellMeta$json = const {
+  '1': 'CellMeta',
+  '2': const [
+    const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
+    const {'1': 'row_id', '3': 2, '4': 1, '5': 9, '10': 'rowId'},
+    const {'1': 'field_id', '3': 3, '4': 1, '5': 9, '10': 'fieldId'},
+    const {'1': 'data', '3': 4, '4': 1, '5': 11, '6': '.AnyData', '10': 'data'},
+    const {'1': 'height', '3': 5, '4': 1, '5': 5, '10': 'height'},
+  ],
+};
+
+/// Descriptor for `CellMeta`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List cellMetaDescriptor = $convert.base64Decode('CghDZWxsTWV0YRIOCgJpZBgBIAEoCVICaWQSFQoGcm93X2lkGAIgASgJUgVyb3dJZBIZCghmaWVsZF9pZBgDIAEoCVIHZmllbGRJZBIcCgRkYXRhGAQgASgLMgguQW55RGF0YVIEZGF0YRIWCgZoZWlnaHQYBSABKAVSBmhlaWdodA==');

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

@@ -0,0 +1,9 @@
+///
+//  Generated code. Do not modify.
+//  source: meta.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 'meta.pb.dart';
+

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

@@ -1,2 +1,3 @@
 // Auto-generated, do not edit 
 export './grid.pb.dart';
+export './meta.pb.dart';

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

@@ -14,12 +14,14 @@ class GridEvent extends $pb.ProtobufEnum {
   static const GridEvent GetRows = GridEvent._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetRows');
   static const GridEvent GetFields = GridEvent._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetFields');
   static const GridEvent CreateRow = GridEvent._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateRow');
+  static const GridEvent UpdateCell = GridEvent._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateCell');
 
   static const $core.List<GridEvent> values = <GridEvent> [
     GetGridData,
     GetRows,
     GetFields,
     CreateRow,
+    UpdateCell,
   ];
 
   static final $core.Map<$core.int, GridEvent> _byValue = $pb.ProtobufEnum.initByValue(values);

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

@@ -16,8 +16,9 @@ const GridEvent$json = const {
     const {'1': 'GetRows', '2': 1},
     const {'1': 'GetFields', '2': 2},
     const {'1': 'CreateRow', '2': 3},
+    const {'1': 'UpdateCell', '2': 4},
   ],
 };
 
 /// Descriptor for `GridEvent`. Decode as a `google.protobuf.EnumDescriptorProto`.
-final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABILCgdHZXRSb3dzEAESDQoJR2V0RmllbGRzEAISDQoJQ3JlYXRlUm93EAM=');
+final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABILCgdHZXRSb3dzEAESDQoJR2V0RmllbGRzEAISDQoJQ3JlYXRlUm93EAMSDgoKVXBkYXRlQ2VsbBAE');

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

@@ -56,7 +56,7 @@ pub(crate) async fn update_cell_handler(
     manager: AppData<Arc<GridManager>>,
 ) -> Result<(), FlowyError> {
     let cell: Cell = data.into_inner();
-    let editor = manager.get_grid_editor(id.as_ref())?;
-    let _ = editor.create_empty_row().await?;
+    // let editor = manager.get_grid_editor(id.as_ref())?;
+    // let _ = editor.create_empty_row().await?;
     Ok(())
 }

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

@@ -4,7 +4,7 @@ use dashmap::DashMap;
 
 use flowy_collaboration::entities::revision::RepeatedRevision;
 use flowy_error::{FlowyError, FlowyResult};
-use flowy_grid_data_model::entities::{Field, RawRow};
+use flowy_grid_data_model::entities::{Field, RowMeta};
 use flowy_sync::{RevisionManager, RevisionPersistence, RevisionWebSocket};
 
 use lib_sqlite::ConnectionPool;
@@ -77,18 +77,6 @@ impl GridManager {
         }
     }
 
-    pub fn save_rows(&self, rows: Vec<RawRow>) -> FlowyResult<()> {
-        let kv_persistence = self.get_kv_persistence()?;
-        let _ = kv_persistence.batch_set(rows)?;
-        Ok(())
-    }
-
-    pub fn save_fields(&self, fields: Vec<Field>) -> FlowyResult<()> {
-        let kv_persistence = self.get_kv_persistence()?;
-        let _ = kv_persistence.batch_set(fields)?;
-        Ok(())
-    }
-
     async fn get_or_create_grid_editor(&self, grid_id: &str) -> FlowyResult<Arc<ClientGridEditor>> {
         match self.editor_map.get(grid_id) {
             None => {

+ 5 - 2
frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs

@@ -29,6 +29,7 @@ pub enum GridEvent {
     GetRows = 1,
     GetFields = 2,
     CreateRow = 3,
+    UpdateCell = 4,
 }
 
 impl ::protobuf::ProtobufEnum for GridEvent {
@@ -42,6 +43,7 @@ impl ::protobuf::ProtobufEnum for GridEvent {
             1 => ::std::option::Option::Some(GridEvent::GetRows),
             2 => ::std::option::Option::Some(GridEvent::GetFields),
             3 => ::std::option::Option::Some(GridEvent::CreateRow),
+            4 => ::std::option::Option::Some(GridEvent::UpdateCell),
             _ => ::std::option::Option::None
         }
     }
@@ -52,6 +54,7 @@ impl ::protobuf::ProtobufEnum for GridEvent {
             GridEvent::GetRows,
             GridEvent::GetFields,
             GridEvent::CreateRow,
+            GridEvent::UpdateCell,
         ];
         values
     }
@@ -80,9 +83,9 @@ impl ::protobuf::reflect::ProtobufValue for GridEvent {
 }
 
 static file_descriptor_proto_data: &'static [u8] = b"\
-    \n\x0fevent_map.proto*G\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\0\x12\
+    \n\x0fevent_map.proto*W\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\0\x12\
     \x0b\n\x07GetRows\x10\x01\x12\r\n\tGetFields\x10\x02\x12\r\n\tCreateRow\
-    \x10\x03b\x06proto3\
+    \x10\x03\x12\x0e\n\nUpdateCell\x10\x04b\x06proto3\
 ";
 
 static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

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

@@ -5,4 +5,5 @@ enum GridEvent {
     GetRows = 1;
     GetFields = 2;
     CreateRow = 3;
+    UpdateCell = 4;
 }

+ 11 - 18
frontend/rust-lib/flowy-grid/src/services/grid_builder.rs

@@ -1,7 +1,7 @@
 use crate::manager::GridManager;
 use flowy_collaboration::client_grid::make_grid_delta;
 use flowy_error::{FlowyError, FlowyResult};
-use flowy_grid_data_model::entities::{Field, FieldOrder, FieldType, Grid, RawCell, RawRow, RowOrder};
+use flowy_grid_data_model::entities::{CellMeta, Field, FieldType, Grid, GridMeta, RowMeta, RowOrder};
 use lib_infra::uuid;
 use std::sync::Arc;
 
@@ -9,7 +9,7 @@ pub struct GridBuilder {
     grid_manager: Arc<GridManager>,
     grid_id: String,
     fields: Vec<Field>,
-    rows: Vec<RawRow>,
+    rows: Vec<RowMeta>,
 }
 
 impl GridBuilder {
@@ -29,39 +29,32 @@ impl GridBuilder {
     }
 
     pub fn add_empty_row(mut self) -> Self {
-        let row = RawRow::new(&uuid(), &self.grid_id, vec![]);
+        let row = RowMeta::new(&uuid(), &self.grid_id, vec![]);
         self.rows.push(row);
         self
     }
 
-    pub fn add_row(mut self, cells: Vec<RawCell>) -> Self {
-        let row = RawRow::new(&uuid(), &self.grid_id, cells);
+    pub fn add_row(mut self, cells: Vec<CellMeta>) -> Self {
+        let row = RowMeta::new(&uuid(), &self.grid_id, cells);
         self.rows.push(row);
         self
     }
 
     pub fn build(self) -> FlowyResult<String> {
-        let field_orders = self.fields.iter().map(FieldOrder::from).collect::<Vec<FieldOrder>>();
-
-        let row_orders = self.rows.iter().map(RowOrder::from).collect::<Vec<RowOrder>>();
-
-        let grid = Grid {
-            id: self.grid_id,
-            field_orders: field_orders.into(),
-            row_orders: row_orders.into(),
+        let grid_meta = GridMeta {
+            grid_id: self.grid_id,
+            fields: self.fields,
+            rows: self.rows,
         };
 
         // let _ = check_rows(&self.fields, &self.rows)?;
-        let _ = self.grid_manager.save_rows(self.rows)?;
-        let _ = self.grid_manager.save_fields(self.fields)?;
-
-        let delta = make_grid_delta(&grid);
+        let delta = make_grid_delta(&grid_meta);
         Ok(delta.to_delta_str())
     }
 }
 
 #[allow(dead_code)]
-fn check_rows(fields: &[Field], rows: &[RawRow]) -> FlowyResult<()> {
+fn check_rows(fields: &[Field], rows: &[RowMeta]) -> FlowyResult<()> {
     let field_ids = fields.iter().map(|field| &field.id).collect::<Vec<&String>>();
     for row in rows {
         let cell_field_ids = row.cell_by_field_id.keys().into_iter().collect::<Vec<&String>>();

+ 28 - 32
frontend/rust-lib/flowy-grid/src/services/grid_editor.rs

@@ -3,19 +3,17 @@ use crate::services::kv_persistence::{GridKVPersistence, KVTransaction};
 use crate::services::stringify::stringify_deserialize;
 
 use dashmap::DashMap;
-use flowy_collaboration::client_grid::{GridChange, GridPad};
+use flowy_collaboration::client_grid::{GridChange, GridMetaPad};
 use flowy_collaboration::entities::revision::Revision;
 use flowy_collaboration::util::make_delta_from_revisions;
 use flowy_error::{FlowyError, FlowyResult};
 use flowy_grid_data_model::entities::{
-    Cell, Field, Grid, RawCell, RawRow, RepeatedField, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, Row,
+    Cell, CellMeta, Field, Grid, RepeatedField, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, Row, RowMeta,
 };
 use flowy_sync::{RevisionCloudService, RevisionCompact, RevisionManager, RevisionObjectBuilder};
 use lib_infra::future::FutureResult;
 use lib_infra::uuid;
 use lib_ot::core::PlainTextAttributes;
-
-use dashmap::mapref::one::Ref;
 use rayon::iter::{IntoParallelIterator, ParallelIterator};
 use std::collections::HashMap;
 use std::sync::Arc;
@@ -24,12 +22,12 @@ use tokio::sync::RwLock;
 pub struct ClientGridEditor {
     grid_id: String,
     user: Arc<dyn GridUser>,
-    grid_pad: Arc<RwLock<GridPad>>,
+    grid_meta_pad: Arc<RwLock<GridMetaPad>>,
     rev_manager: Arc<RevisionManager>,
     kv_persistence: Arc<GridKVPersistence>,
 
     field_map: DashMap<String, Field>,
-    cell_map: DashMap<String, RawCell>,
+    cell_map: DashMap<String, CellMeta>,
 }
 
 impl ClientGridEditor {
@@ -45,13 +43,13 @@ impl ClientGridEditor {
 
         let rev_manager = Arc::new(rev_manager);
         let field_map = load_all_fields(&grid_pad, &kv_persistence).await?;
-        let grid_pad = Arc::new(RwLock::new(grid_pad));
+        let grid_meta_pad = Arc::new(RwLock::new(grid_pad));
         let cell_map = DashMap::new();
 
         Ok(Arc::new(Self {
             grid_id: grid_id.to_owned(),
             user,
-            grid_pad,
+            grid_meta_pad,
             rev_manager,
             kv_persistence,
             field_map,
@@ -60,16 +58,15 @@ impl ClientGridEditor {
     }
 
     pub async fn create_empty_row(&self) -> FlowyResult<()> {
-        let row = RawRow::new(&uuid(), &self.grid_id, vec![]);
-        self.cell_map.insert(row.id.clone(), row.clone());
+        let row = RowMeta::new(&uuid(), &self.grid_id, vec![]);
         self.create_row(row).await?;
         Ok(())
     }
 
-    async fn create_row(&self, row: RawRow) -> FlowyResult<()> {
-        let _ = self.modify(|grid| Ok(grid.create_row(&row)?)).await?;
-        self.cell_map.insert(row.id.clone(), row.clone());
-        let _ = self.kv_persistence.set(row)?;
+    async fn create_row(&self, row: RowMeta) -> FlowyResult<()> {
+        let _ = self.modify(|grid| Ok(grid.create_row(row)?)).await?;
+        // self.cell_map.insert(row.id.clone(), row.clone());
+        // let _ = self.kv_persistence.set(row)?;
         Ok(())
     }
 
@@ -87,8 +84,7 @@ impl ClientGridEditor {
     // }
 
     pub async fn create_field(&mut self, field: Field) -> FlowyResult<()> {
-        let _ = self.modify(|grid| Ok(grid.create_field(&field)?)).await?;
-        let _ = self.kv_persistence.set(field)?;
+        let _ = self.modify(|grid| Ok(grid.create_field(field)?)).await?;
         Ok(())
     }
 
@@ -104,9 +100,9 @@ impl ClientGridEditor {
             .into_iter()
             .map(|row_order| row_order.row_id)
             .collect::<Vec<_>>();
-        let raw_rows: Vec<RawRow> = self.kv_persistence.batch_get(ids)?;
+        let row_metas: Vec<RowMeta> = self.kv_persistence.batch_get(ids)?;
 
-        let make_cell = |field_id: String, raw_cell: RawCell| {
+        let make_cell = |field_id: String, raw_cell: CellMeta| {
             let some_field = self.field_map.get(&field_id);
             if some_field.is_none() {
                 tracing::error!("Can't find the field with {}", field_id);
@@ -128,15 +124,15 @@ impl ClientGridEditor {
             }
         };
 
-        let rows = raw_rows
+        let rows = row_metas
             .into_par_iter()
-            .map(|raw_row| {
+            .map(|row_meta| {
                 let mut row = Row {
-                    id: raw_row.id.clone(),
+                    id: row_meta.id.clone(),
                     cell_by_field_id: Default::default(),
-                    height: raw_row.height,
+                    height: row_meta.height,
                 };
-                row.cell_by_field_id = raw_row
+                row.cell_by_field_id = row_meta
                     .cell_by_field_id
                     .into_par_iter()
                     .flat_map(|(field_id, raw_cell)| make_cell(field_id, raw_cell))
@@ -163,18 +159,18 @@ impl ClientGridEditor {
     }
 
     pub async fn grid_data(&self) -> Grid {
-        self.grid_pad.read().await.grid_data()
+        self.grid_meta_pad.read().await.grid_data()
     }
 
     pub async fn delta_str(&self) -> String {
-        self.grid_pad.read().await.delta_str()
+        self.grid_meta_pad.read().await.delta_str()
     }
 
     async fn modify<F>(&self, f: F) -> FlowyResult<()>
     where
-        F: for<'a> FnOnce(&'a mut GridPad) -> FlowyResult<Option<GridChange>>,
+        F: for<'a> FnOnce(&'a mut GridMetaPad) -> FlowyResult<Option<GridChange>>,
     {
-        let mut write_guard = self.grid_pad.write().await;
+        let mut write_guard = self.grid_meta_pad.write().await;
         match f(&mut *write_guard)? {
             None => {}
             Some(change) => {
@@ -206,13 +202,13 @@ impl ClientGridEditor {
 }
 
 async fn load_all_fields(
-    grid_pad: &GridPad,
+    grid_pad: &GridMetaPad,
     kv_persistence: &Arc<GridKVPersistence>,
 ) -> FlowyResult<DashMap<String, Field>> {
     let field_ids = grid_pad
-        .field_orders()
+        .fields()
         .iter()
-        .map(|field_order| field_order.field_id.clone())
+        .map(|field| field.id.clone())
         .collect::<Vec<_>>();
 
     let fields = kv_persistence.batch_get::<Field>(field_ids)?;
@@ -225,10 +221,10 @@ async fn load_all_fields(
 
 struct GridPadBuilder();
 impl RevisionObjectBuilder for GridPadBuilder {
-    type Output = GridPad;
+    type Output = GridMetaPad;
 
     fn build_object(object_id: &str, revisions: Vec<Revision>) -> FlowyResult<Self::Output> {
-        let pad = GridPad::from_revisions(object_id, revisions)?;
+        let pad = GridMetaPad::from_revisions(object_id, revisions)?;
         Ok(pad)
     }
 }

+ 6 - 30
frontend/rust-lib/flowy-grid/src/services/kv_persistence.rs

@@ -6,8 +6,6 @@ use flowy_database::{
     schema::{kv_table, kv_table::dsl},
 };
 use flowy_error::{FlowyError, FlowyResult};
-use flowy_grid_data_model::entities::GridIdentifiable;
-
 use lib_sqlite::ConnectionPool;
 use std::sync::Arc;
 
@@ -135,33 +133,11 @@ impl<'a> KVTransaction for SqliteTransaction<'a> {
     }
 }
 
-impl<T: TryInto<Bytes, Error = ::protobuf::ProtobufError> + GridIdentifiable> std::convert::From<T> for KeyValue {
-    fn from(value: T) -> Self {
-        let key = value.id().to_string();
-        let bytes: Bytes = value.try_into().unwrap();
-        let value = bytes.to_vec();
-        KeyValue { key, value }
-    }
-}
-
-//
-// impl std::convert::TryInto<RawRow> for KeyValue {
-
-//     type Error = FlowyError;
-//
-//     fn try_into(self) -> Result<RawRow, Self::Error> {
-//         let bytes = Bytes::from(self.value);
-//         RawRow::try_from(bytes)
-//             .map_err(|e| FlowyError::internal().context(format!("Deserialize into raw row failed: {:?}", e)))
-//     }
-// }
-//
-// impl std::convert::TryInto<Field> for KeyValue {
-//     type Error = FlowyError;
-//
-//     fn try_into(self) -> Result<Field, Self::Error> {
-//         let bytes = Bytes::from(self.value);
-//         Field::try_from(bytes)
-//             .map_err(|e| FlowyError::internal().context(format!("Deserialize into field failed: {:?}", e)))
+// impl<T: TryInto<Bytes, Error = ::protobuf::ProtobufError> + GridIdentifiable> std::convert::From<T> for KeyValue {
+//     fn from(value: T) -> Self {
+//         let key = value.id().to_string();
+//         let bytes: Bytes = value.try_into().unwrap();
+//         let value = bytes.to_vec();
+//         KeyValue { key, value }
 //     }
 // }

+ 56 - 54
shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs

@@ -1,7 +1,7 @@
 use crate::entities::revision::{md5, RepeatedRevision, Revision};
 use crate::errors::{internal_error, CollaborateError, CollaborateResult};
 use crate::util::{cal_diff, make_delta_from_revisions};
-use flowy_grid_data_model::entities::{Field, FieldOrder, Grid, RawRow, RepeatedFieldOrder, RowOrder};
+use flowy_grid_data_model::entities::{Field, FieldOrder, Grid, GridMeta, RowMeta, RowOrder};
 use lib_infra::uuid;
 use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder};
 use std::sync::Arc;
@@ -9,70 +9,55 @@ use std::sync::Arc;
 pub type GridDelta = PlainTextDelta;
 pub type GridDeltaBuilder = PlainTextDeltaBuilder;
 
-pub struct GridPad {
-    pub(crate) grid: Arc<Grid>,
+pub struct GridMetaPad {
+    pub(crate) grid_meta: Arc<GridMeta>,
     pub(crate) delta: GridDelta,
 }
 
-impl GridPad {
+impl GridMetaPad {
     pub fn from_delta(delta: GridDelta) -> CollaborateResult<Self> {
         let s = delta.to_str()?;
-        let grid: Grid = serde_json::from_str(&s)
+        let grid: GridMeta = serde_json::from_str(&s)
             .map_err(|e| CollaborateError::internal().context(format!("Deserialize delta to grid failed: {}", e)))?;
 
         Ok(Self {
-            grid: Arc::new(grid),
+            grid_meta: Arc::new(grid),
             delta,
         })
     }
 
     pub fn from_revisions(_grid_id: &str, revisions: Vec<Revision>) -> CollaborateResult<Self> {
-        let folder_delta: GridDelta = make_delta_from_revisions::<PlainTextAttributes>(revisions)?;
-        Self::from_delta(folder_delta)
+        let grid_delta: GridDelta = make_delta_from_revisions::<PlainTextAttributes>(revisions)?;
+        Self::from_delta(grid_delta)
     }
 
-    pub fn create_row(&mut self, row: &RawRow) -> CollaborateResult<Option<GridChange>> {
+    pub fn create_row(&mut self, row: RowMeta) -> CollaborateResult<Option<GridChange>> {
         self.modify_grid(|grid| {
-            let row_order = RowOrder {
-                grid_id: grid.id.clone(),
-                row_id: row.id.clone(),
-                visibility: true,
-            };
-            grid.row_orders.push(row_order);
+            grid.rows.push(row);
             Ok(Some(()))
         })
     }
 
-    pub fn create_field(&mut self, field: &Field) -> CollaborateResult<Option<GridChange>> {
+    pub fn create_field(&mut self, field: Field) -> CollaborateResult<Option<GridChange>> {
         self.modify_grid(|grid| {
-            let field_order = FieldOrder {
-                field_id: field.id.clone(),
-                visibility: true,
-            };
-            grid.field_orders.push(field_order);
+            grid.fields.push(field);
             Ok(Some(()))
         })
     }
 
     pub fn delete_rows(&mut self, row_ids: &[String]) -> CollaborateResult<Option<GridChange>> {
         self.modify_grid(|grid| {
-            grid.row_orders.retain(|row_order| !row_ids.contains(&row_order.row_id));
+            grid.rows.retain(|row| !row_ids.contains(&row.id));
             Ok(Some(()))
         })
     }
 
     pub fn delete_field(&mut self, field_id: &str) -> CollaborateResult<Option<GridChange>> {
-        self.modify_grid(|grid| {
-            match grid
-                .field_orders
-                .iter()
-                .position(|field_order| field_order.field_id == field_id)
-            {
-                None => Ok(None),
-                Some(index) => {
-                    grid.field_orders.remove(index);
-                    Ok(Some(()))
-                }
+        self.modify_grid(|grid| match grid.fields.iter().position(|field| field.id == field_id) {
+            None => Ok(None),
+            Some(index) => {
+                grid.fields.remove(index);
+                Ok(Some(()))
             }
         })
     }
@@ -82,28 +67,45 @@ impl GridPad {
     }
 
     pub fn grid_data(&self) -> Grid {
-        let grid_ref: &Grid = &self.grid;
-        grid_ref.clone()
+        let field_orders = self
+            .grid_meta
+            .fields
+            .iter()
+            .map(FieldOrder::from)
+            .collect::<Vec<FieldOrder>>();
+
+        let row_orders = self
+            .grid_meta
+            .rows
+            .iter()
+            .map(RowOrder::from)
+            .collect::<Vec<RowOrder>>();
+
+        Grid {
+            id: "".to_string(),
+            field_orders,
+            row_orders,
+        }
     }
 
     pub fn delta_str(&self) -> String {
         self.delta.to_delta_str()
     }
 
-    pub fn field_orders(&self) -> &RepeatedFieldOrder {
-        &self.grid.field_orders
+    pub fn fields(&self) -> &[Field] {
+        &self.grid_meta.fields
     }
 
     pub fn modify_grid<F>(&mut self, f: F) -> CollaborateResult<Option<GridChange>>
     where
-        F: FnOnce(&mut Grid) -> CollaborateResult<Option<()>>,
+        F: FnOnce(&mut GridMeta) -> CollaborateResult<Option<()>>,
     {
-        let cloned_grid = self.grid.clone();
-        match f(Arc::make_mut(&mut self.grid))? {
+        let cloned_grid = self.grid_meta.clone();
+        match f(Arc::make_mut(&mut self.grid_meta))? {
             None => Ok(None),
             Some(_) => {
                 let old = json_from_grid(&cloned_grid)?;
-                let new = json_from_grid(&self.grid)?;
+                let new = json_from_grid(&self.grid_meta)?;
                 match cal_diff::<PlainTextAttributes>(old, new) {
                     None => Ok(None),
                     Some(delta) => {
@@ -116,7 +118,7 @@ impl GridPad {
     }
 }
 
-fn json_from_grid(grid: &Arc<Grid>) -> CollaborateResult<String> {
+fn json_from_grid(grid: &Arc<GridMeta>) -> CollaborateResult<String> {
     let json = serde_json::to_string(grid)
         .map_err(|err| internal_error(format!("Serialize grid to json str failed. {:?}", err)))?;
     Ok(json)
@@ -128,28 +130,28 @@ pub struct GridChange {
     pub md5: String,
 }
 
-pub fn make_grid_delta(grid: &Grid) -> GridDelta {
-    let json = serde_json::to_string(&grid).unwrap();
+pub fn make_grid_delta(grid_meta: &GridMeta) -> GridDelta {
+    let json = serde_json::to_string(&grid_meta).unwrap();
     PlainTextDeltaBuilder::new().insert(&json).build()
 }
 
-pub fn make_grid_revisions(user_id: &str, grid: &Grid) -> RepeatedRevision {
-    let delta = make_grid_delta(grid);
+pub fn make_grid_revisions(user_id: &str, grid_meta: &GridMeta) -> RepeatedRevision {
+    let delta = make_grid_delta(grid_meta);
     let bytes = delta.to_bytes();
-    let revision = Revision::initial_revision(user_id, &grid.id, bytes);
+    let revision = Revision::initial_revision(user_id, &grid_meta.grid_id, bytes);
     revision.into()
 }
 
-impl std::default::Default for GridPad {
+impl std::default::Default for GridMetaPad {
     fn default() -> Self {
-        let grid = Grid {
-            id: uuid(),
-            field_orders: Default::default(),
-            row_orders: Default::default(),
+        let grid = GridMeta {
+            grid_id: uuid(),
+            fields: vec![],
+            rows: vec![],
         };
         let delta = make_grid_delta(&grid);
-        GridPad {
-            grid: Arc::new(grid),
+        GridMetaPad {
+            grid_meta: Arc::new(grid),
             delta,
         }
     }

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

@@ -1,3 +1,4 @@
+use crate::entities::{Field, RowMeta};
 use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
 use serde::{Deserialize, Serialize};
 use std::collections::HashMap;
@@ -6,239 +7,63 @@ use strum_macros::{Display, EnumIter, EnumString};
 pub const DEFAULT_ROW_HEIGHT: i32 = 36;
 pub const DEFAULT_FIELD_WIDTH: i32 = 150;
 
-pub trait GridIdentifiable {
-    fn id(&self) -> &str;
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize, ProtoBuf)]
+#[derive(Debug, Clone, Default, ProtoBuf)]
 pub struct Grid {
     #[pb(index = 1)]
     pub id: String,
 
     #[pb(index = 2)]
-    #[serde(flatten)]
-    pub field_orders: RepeatedFieldOrder,
+    pub field_orders: Vec<FieldOrder>,
 
     #[pb(index = 3)]
-    #[serde(flatten)]
-    pub row_orders: RepeatedRowOrder,
+    pub row_orders: Vec<RowOrder>,
 }
 
-#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, ProtoBuf)]
+#[derive(Debug, Clone, Default, ProtoBuf)]
 pub struct FieldOrder {
     #[pb(index = 1)]
     pub field_id: String,
-
-    #[pb(index = 2)]
-    pub visibility: bool,
 }
 
 impl std::convert::From<&Field> for FieldOrder {
     fn from(field: &Field) -> Self {
         Self {
             field_id: field.id.clone(),
-            visibility: true,
         }
     }
 }
 
-#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize, ProtoBuf)]
+#[derive(Debug, Clone, Default, ProtoBuf)]
 pub struct RepeatedFieldOrder {
     #[pb(index = 1)]
-    #[serde(rename(serialize = "field_orders", deserialize = "field_orders"))]
     pub items: Vec<FieldOrder>,
 }
 
-impl std::convert::From<Vec<FieldOrder>> for RepeatedFieldOrder {
-    fn from(items: Vec<FieldOrder>) -> Self {
-        Self { items }
-    }
-}
-
 impl std::ops::Deref for RepeatedFieldOrder {
     type Target = Vec<FieldOrder>;
-
     fn deref(&self) -> &Self::Target {
         &self.items
     }
 }
 
-impl std::ops::DerefMut for RepeatedFieldOrder {
-    fn deref_mut(&mut self) -> &mut Self::Target {
-        &mut self.items
-    }
-}
-
-#[derive(Debug, Clone, Default, ProtoBuf)]
-pub struct Field {
-    #[pb(index = 1)]
-    pub id: String,
-
-    #[pb(index = 2)]
-    pub name: String,
-
-    #[pb(index = 3)]
-    pub desc: String,
-
-    #[pb(index = 4)]
-    pub field_type: FieldType,
-
-    #[pb(index = 5)]
-    pub frozen: bool,
-
-    #[pb(index = 6)]
-    pub width: i32,
-
-    #[pb(index = 7)]
-    pub type_options: AnyData,
-}
-
-impl Field {
-    pub fn new(id: &str, name: &str, desc: &str, field_type: FieldType) -> Self {
-        Self {
-            id: id.to_owned(),
-            name: name.to_string(),
-            desc: desc.to_string(),
-            field_type,
-            frozen: false,
-            width: DEFAULT_FIELD_WIDTH,
-            type_options: Default::default(),
-        }
-    }
-}
-
-impl GridIdentifiable for Field {
-    fn id(&self) -> &str {
-        &self.id
-    }
-}
-
-#[derive(Debug, Default, ProtoBuf)]
-pub struct RepeatedField {
-    #[pb(index = 1)]
-    pub items: Vec<Field>,
-}
-impl std::ops::Deref for RepeatedField {
-    type Target = Vec<Field>;
-    fn deref(&self) -> &Self::Target {
-        &self.items
-    }
-}
-
-impl std::ops::DerefMut for RepeatedField {
-    fn deref_mut(&mut self) -> &mut Self::Target {
-        &mut self.items
-    }
-}
-
-impl std::convert::From<Vec<Field>> for RepeatedField {
-    fn from(items: Vec<Field>) -> Self {
-        Self { items }
-    }
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum, EnumString, EnumIter, Display, Serialize, Deserialize)]
-pub enum FieldType {
-    RichText = 0,
-    Number = 1,
-    DateTime = 2,
-    SingleSelect = 3,
-    MultiSelect = 4,
-    Checkbox = 5,
-}
-
-impl std::default::Default for FieldType {
-    fn default() -> Self {
-        FieldType::RichText
-    }
-}
-
-impl FieldType {
-    #[allow(dead_code)]
-    pub fn type_id(&self) -> String {
-        let ty = self.clone();
-        format!("{}", ty as u8)
-    }
-
-    pub fn from_type_id(type_id: &str) -> Result<FieldType, String> {
-        match type_id {
-            "0" => Ok(FieldType::RichText),
-            "1" => Ok(FieldType::Number),
-            "2" => Ok(FieldType::DateTime),
-            "3" => Ok(FieldType::SingleSelect),
-            "4" => Ok(FieldType::MultiSelect),
-            "5" => Ok(FieldType::Checkbox),
-            _ => Err(format!("Invalid type_id: {}", type_id)),
-        }
-    }
-}
-
-#[derive(Debug, Clone, Default, ProtoBuf)]
-pub struct AnyData {
-    #[pb(index = 1)]
-    pub type_id: String,
-
-    #[pb(index = 2)]
-    pub value: Vec<u8>,
-}
-
-impl AnyData {
-    pub fn from_str(field_type: &FieldType, s: &str) -> AnyData {
-        Self::from_bytes(field_type, s.as_bytes().to_vec())
-    }
-
-    pub fn from_bytes<T: AsRef<[u8]>>(field_type: &FieldType, bytes: T) -> AnyData {
-        AnyData {
-            type_id: field_type.type_id(),
-            value: bytes.as_ref().to_vec(),
-        }
-    }
-}
-
-impl ToString for AnyData {
-    fn to_string(&self) -> String {
-        match String::from_utf8(self.value.clone()) {
-            Ok(s) => s,
-            Err(_) => "".to_owned(),
-        }
-    }
-}
-
-#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize, ProtoBuf)]
+#[derive(Debug, Default, Clone, ProtoBuf)]
 pub struct RowOrder {
     #[pb(index = 1)]
-    pub grid_id: String,
-
-    #[pb(index = 2)]
     pub row_id: String,
-
-    #[pb(index = 3)]
-    pub visibility: bool,
 }
 
-impl std::convert::From<&RawRow> for RowOrder {
-    fn from(row: &RawRow) -> Self {
-        Self {
-            grid_id: row.grid_id.clone(),
-            row_id: row.id.clone(),
-            visibility: true,
-        }
+impl std::convert::From<&RowMeta> for RowOrder {
+    fn from(row: &RowMeta) -> Self {
+        Self { row_id: row.id.clone() }
     }
 }
 
-#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, ProtoBuf)]
+#[derive(Debug, Clone, Default, ProtoBuf)]
 pub struct RepeatedRowOrder {
     #[pb(index = 1)]
-    #[serde(rename(serialize = "row_orders", deserialize = "row_orders"))]
     pub items: Vec<RowOrder>,
 }
 
-impl std::convert::From<Vec<RowOrder>> for RepeatedRowOrder {
-    fn from(items: Vec<RowOrder>) -> Self {
-        Self { items }
-    }
-}
-
 impl std::ops::Deref for RepeatedRowOrder {
     type Target = Vec<RowOrder>;
     fn deref(&self) -> &Self::Target {
@@ -253,57 +78,14 @@ impl std::ops::DerefMut for RepeatedRowOrder {
 }
 
 #[derive(Debug, Default, ProtoBuf)]
-pub struct RawRow {
-    #[pb(index = 1)]
-    pub id: String,
-
-    #[pb(index = 2)]
-    pub grid_id: String,
-
-    #[pb(index = 3)]
-    pub cell_by_field_id: HashMap<String, RawCell>,
-
-    #[pb(index = 4)]
-    pub height: i32,
-}
-
-impl RawRow {
-    pub fn new(id: &str, grid_id: &str, cells: Vec<RawCell>) -> Self {
-        let cell_by_field_id = cells
-            .into_iter()
-            .map(|cell| (cell.id.clone(), cell))
-            .collect::<HashMap<String, RawCell>>();
-
-        Self {
-            id: id.to_owned(),
-            grid_id: grid_id.to_owned(),
-            cell_by_field_id,
-            height: DEFAULT_ROW_HEIGHT,
-        }
-    }
-}
-
-impl GridIdentifiable for RawRow {
-    fn id(&self) -> &str {
-        &self.id
-    }
-}
-
-#[derive(Debug, Default, ProtoBuf)]
-pub struct RawCell {
+pub struct Row {
     #[pb(index = 1)]
     pub id: String,
 
     #[pb(index = 2)]
-    pub row_id: String,
+    pub cell_by_field_id: HashMap<String, Cell>,
 
     #[pb(index = 3)]
-    pub field_id: String,
-
-    #[pb(index = 4)]
-    pub data: AnyData,
-
-    #[pb(index = 5)]
     pub height: i32,
 }
 
@@ -331,19 +113,6 @@ impl std::convert::From<Vec<Row>> for RepeatedRow {
         Self { items }
     }
 }
-
-#[derive(Debug, Default, ProtoBuf)]
-pub struct Row {
-    #[pb(index = 1)]
-    pub id: String,
-
-    #[pb(index = 2)]
-    pub cell_by_field_id: HashMap<String, Cell>,
-
-    #[pb(index = 3)]
-    pub height: i32,
-}
-
 #[derive(Debug, Default, ProtoBuf)]
 pub struct Cell {
     #[pb(index = 1)]
@@ -356,21 +125,6 @@ pub struct Cell {
     pub content: String,
 }
 
-#[derive(Debug, Default, ProtoBuf)]
-pub struct CellChangeset {
-    #[pb(index = 1)]
-    pub id: String,
-
-    #[pb(index = 2)]
-    pub row_id: String,
-
-    #[pb(index = 3)]
-    pub field_id: String,
-
-    #[pb(index = 4)]
-    pub data: String,
-}
-
 #[derive(ProtoBuf, Default)]
 pub struct CreateGridPayload {
     #[pb(index = 1)]

+ 215 - 0
shared-lib/flowy-grid-data-model/src/entities/meta.rs

@@ -0,0 +1,215 @@
+use crate::entities::Row;
+use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
+use serde::{Deserialize, Serialize};
+use std::collections::HashMap;
+use strum_macros::{Display, EnumIter, EnumString};
+
+pub const DEFAULT_ROW_HEIGHT: i32 = 36;
+pub const DEFAULT_FIELD_WIDTH: i32 = 150;
+
+#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)]
+pub struct GridMeta {
+    #[pb(index = 1)]
+    pub grid_id: String,
+
+    #[pb(index = 2)]
+    pub fields: Vec<Field>,
+
+    #[pb(index = 3)]
+    pub rows: Vec<RowMeta>,
+}
+
+#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)]
+pub struct GridBlock {
+    #[pb(index = 1)]
+    pub id: String,
+
+    #[pb(index = 2)]
+    pub rows: Vec<RowMeta>,
+}
+
+#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)]
+pub struct Field {
+    #[pb(index = 1)]
+    pub id: String,
+
+    #[pb(index = 2)]
+    pub name: String,
+
+    #[pb(index = 3)]
+    pub desc: String,
+
+    #[pb(index = 4)]
+    pub field_type: FieldType,
+
+    #[pb(index = 5)]
+    pub frozen: bool,
+
+    #[pb(index = 6)]
+    pub visibility: bool,
+
+    #[pb(index = 7)]
+    pub width: i32,
+
+    #[pb(index = 8)]
+    pub type_options: AnyData,
+}
+
+impl Field {
+    pub fn new(id: &str, name: &str, desc: &str, field_type: FieldType) -> Self {
+        Self {
+            id: id.to_owned(),
+            name: name.to_string(),
+            desc: desc.to_string(),
+            field_type,
+            frozen: false,
+            visibility: true,
+            width: DEFAULT_FIELD_WIDTH,
+            type_options: Default::default(),
+        }
+    }
+}
+
+#[derive(Debug, Default, ProtoBuf)]
+pub struct RepeatedField {
+    #[pb(index = 1)]
+    pub items: Vec<Field>,
+}
+impl std::ops::Deref for RepeatedField {
+    type Target = Vec<Field>;
+    fn deref(&self) -> &Self::Target {
+        &self.items
+    }
+}
+
+impl std::ops::DerefMut for RepeatedField {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        &mut self.items
+    }
+}
+
+impl std::convert::From<Vec<Field>> for RepeatedField {
+    fn from(items: Vec<Field>) -> Self {
+        Self { items }
+    }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum, EnumString, EnumIter, Display, Serialize, Deserialize)]
+pub enum FieldType {
+    RichText = 0,
+    Number = 1,
+    DateTime = 2,
+    SingleSelect = 3,
+    MultiSelect = 4,
+    Checkbox = 5,
+}
+
+impl std::default::Default for FieldType {
+    fn default() -> Self {
+        FieldType::RichText
+    }
+}
+
+impl FieldType {
+    #[allow(dead_code)]
+    pub fn type_id(&self) -> String {
+        let ty = self.clone();
+        format!("{}", ty as u8)
+    }
+
+    pub fn from_type_id(type_id: &str) -> Result<FieldType, String> {
+        match type_id {
+            "0" => Ok(FieldType::RichText),
+            "1" => Ok(FieldType::Number),
+            "2" => Ok(FieldType::DateTime),
+            "3" => Ok(FieldType::SingleSelect),
+            "4" => Ok(FieldType::MultiSelect),
+            "5" => Ok(FieldType::Checkbox),
+            _ => Err(format!("Invalid type_id: {}", type_id)),
+        }
+    }
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, Default, ProtoBuf)]
+pub struct AnyData {
+    #[pb(index = 1)]
+    pub type_id: String,
+
+    #[pb(index = 2)]
+    pub value: Vec<u8>,
+}
+
+impl AnyData {
+    pub fn from_str(field_type: &FieldType, s: &str) -> AnyData {
+        Self::from_bytes(field_type, s.as_bytes().to_vec())
+    }
+
+    pub fn from_bytes<T: AsRef<[u8]>>(field_type: &FieldType, bytes: T) -> AnyData {
+        AnyData {
+            type_id: field_type.type_id(),
+            value: bytes.as_ref().to_vec(),
+        }
+    }
+}
+
+impl ToString for AnyData {
+    fn to_string(&self) -> String {
+        match String::from_utf8(self.value.clone()) {
+            Ok(s) => s,
+            Err(_) => "".to_owned(),
+        }
+    }
+}
+
+#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)]
+pub struct RowMeta {
+    #[pb(index = 1)]
+    pub id: String,
+
+    #[pb(index = 2)]
+    pub grid_id: String,
+
+    #[pb(index = 3)]
+    pub cell_by_field_id: HashMap<String, CellMeta>,
+
+    #[pb(index = 4)]
+    pub height: i32,
+
+    #[pb(index = 5)]
+    pub visibility: bool,
+}
+
+impl RowMeta {
+    pub fn new(id: &str, grid_id: &str, cells: Vec<CellMeta>) -> Self {
+        let cell_by_field_id = cells
+            .into_iter()
+            .map(|cell| (cell.id.clone(), cell))
+            .collect::<HashMap<String, CellMeta>>();
+
+        Self {
+            id: id.to_owned(),
+            grid_id: grid_id.to_owned(),
+            cell_by_field_id,
+            height: DEFAULT_ROW_HEIGHT,
+            visibility: true,
+        }
+    }
+}
+
+#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)]
+pub struct CellMeta {
+    #[pb(index = 1)]
+    pub id: String,
+
+    #[pb(index = 2)]
+    pub row_id: String,
+
+    #[pb(index = 3)]
+    pub field_id: String,
+
+    #[pb(index = 4)]
+    pub data: AnyData,
+
+    #[pb(index = 5)]
+    pub height: i32,
+}

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

@@ -1,3 +1,5 @@
 mod grid;
+mod meta;
 
 pub use grid::*;
+pub use meta::*;

文件差異過大導致無法顯示
+ 80 - 1750
shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs


+ 2040 - 0
shared-lib/flowy-grid-data-model/src/protobuf/model/meta.rs

@@ -0,0 +1,2040 @@
+// 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 `meta.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 GridMeta {
+    // message fields
+    pub grid_id: ::std::string::String,
+    pub fields: ::protobuf::RepeatedField<Field>,
+    pub rows: ::protobuf::RepeatedField<RowMeta>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a GridMeta {
+    fn default() -> &'a GridMeta {
+        <GridMeta as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl GridMeta {
+    pub fn new() -> GridMeta {
+        ::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())
+    }
+
+    // repeated .Field fields = 2;
+
+
+    pub fn get_fields(&self) -> &[Field] {
+        &self.fields
+    }
+    pub fn clear_fields(&mut self) {
+        self.fields.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_fields(&mut self, v: ::protobuf::RepeatedField<Field>) {
+        self.fields = v;
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_fields(&mut self) -> &mut ::protobuf::RepeatedField<Field> {
+        &mut self.fields
+    }
+
+    // Take field
+    pub fn take_fields(&mut self) -> ::protobuf::RepeatedField<Field> {
+        ::std::mem::replace(&mut self.fields, ::protobuf::RepeatedField::new())
+    }
+
+    // repeated .RowMeta rows = 3;
+
+
+    pub fn get_rows(&self) -> &[RowMeta] {
+        &self.rows
+    }
+    pub fn clear_rows(&mut self) {
+        self.rows.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_rows(&mut self, v: ::protobuf::RepeatedField<RowMeta>) {
+        self.rows = v;
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_rows(&mut self) -> &mut ::protobuf::RepeatedField<RowMeta> {
+        &mut self.rows
+    }
+
+    // Take field
+    pub fn take_rows(&mut self) -> ::protobuf::RepeatedField<RowMeta> {
+        ::std::mem::replace(&mut self.rows, ::protobuf::RepeatedField::new())
+    }
+}
+
+impl ::protobuf::Message for GridMeta {
+    fn is_initialized(&self) -> bool {
+        for v in &self.fields {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        for v in &self.rows {
+            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 => {
+                    ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.fields)?;
+                },
+                3 => {
+                    ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.rows)?;
+                },
+                _ => {
+                    ::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);
+        }
+        for value in &self.fields {
+            let len = value.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        };
+        for value in &self.rows {
+            let len = value.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)?;
+        }
+        for v in &self.fields {
+            os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        };
+        for v in &self.rows {
+            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() -> GridMeta {
+        GridMeta::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: &GridMeta| { &m.grid_id },
+                |m: &mut GridMeta| { &mut m.grid_id },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<Field>>(
+                "fields",
+                |m: &GridMeta| { &m.fields },
+                |m: &mut GridMeta| { &mut m.fields },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<RowMeta>>(
+                "rows",
+                |m: &GridMeta| { &m.rows },
+                |m: &mut GridMeta| { &mut m.rows },
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<GridMeta>(
+                "GridMeta",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static GridMeta {
+        static instance: ::protobuf::rt::LazyV2<GridMeta> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(GridMeta::new)
+    }
+}
+
+impl ::protobuf::Clear for GridMeta {
+    fn clear(&mut self) {
+        self.grid_id.clear();
+        self.fields.clear();
+        self.rows.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for GridMeta {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for GridMeta {
+    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+        ::protobuf::reflect::ReflectValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct GridBlock {
+    // message fields
+    pub id: ::std::string::String,
+    pub rows: ::protobuf::RepeatedField<RowMeta>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a GridBlock {
+    fn default() -> &'a GridBlock {
+        <GridBlock as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl GridBlock {
+    pub fn new() -> GridBlock {
+        ::std::default::Default::default()
+    }
+
+    // string id = 1;
+
+
+    pub fn get_id(&self) -> &str {
+        &self.id
+    }
+    pub fn clear_id(&mut self) {
+        self.id.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_id(&mut self, v: ::std::string::String) {
+        self.id = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_id(&mut self) -> &mut ::std::string::String {
+        &mut self.id
+    }
+
+    // Take field
+    pub fn take_id(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.id, ::std::string::String::new())
+    }
+
+    // repeated .RowMeta rows = 2;
+
+
+    pub fn get_rows(&self) -> &[RowMeta] {
+        &self.rows
+    }
+    pub fn clear_rows(&mut self) {
+        self.rows.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_rows(&mut self, v: ::protobuf::RepeatedField<RowMeta>) {
+        self.rows = v;
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_rows(&mut self) -> &mut ::protobuf::RepeatedField<RowMeta> {
+        &mut self.rows
+    }
+
+    // Take field
+    pub fn take_rows(&mut self) -> ::protobuf::RepeatedField<RowMeta> {
+        ::std::mem::replace(&mut self.rows, ::protobuf::RepeatedField::new())
+    }
+}
+
+impl ::protobuf::Message for GridBlock {
+    fn is_initialized(&self) -> bool {
+        for v in &self.rows {
+            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.id)?;
+                },
+                2 => {
+                    ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.rows)?;
+                },
+                _ => {
+                    ::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.id.is_empty() {
+            my_size += ::protobuf::rt::string_size(1, &self.id);
+        }
+        for value in &self.rows {
+            let len = value.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.id.is_empty() {
+            os.write_string(1, &self.id)?;
+        }
+        for v in &self.rows {
+            os.write_tag(2, ::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() -> GridBlock {
+        GridBlock::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>(
+                "id",
+                |m: &GridBlock| { &m.id },
+                |m: &mut GridBlock| { &mut m.id },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<RowMeta>>(
+                "rows",
+                |m: &GridBlock| { &m.rows },
+                |m: &mut GridBlock| { &mut m.rows },
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<GridBlock>(
+                "GridBlock",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static GridBlock {
+        static instance: ::protobuf::rt::LazyV2<GridBlock> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(GridBlock::new)
+    }
+}
+
+impl ::protobuf::Clear for GridBlock {
+    fn clear(&mut self) {
+        self.id.clear();
+        self.rows.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for GridBlock {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for GridBlock {
+    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+        ::protobuf::reflect::ReflectValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct Field {
+    // message fields
+    pub id: ::std::string::String,
+    pub name: ::std::string::String,
+    pub desc: ::std::string::String,
+    pub field_type: FieldType,
+    pub frozen: bool,
+    pub visibility: bool,
+    pub width: i32,
+    pub type_options: ::protobuf::SingularPtrField<AnyData>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a Field {
+    fn default() -> &'a Field {
+        <Field as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl Field {
+    pub fn new() -> Field {
+        ::std::default::Default::default()
+    }
+
+    // string id = 1;
+
+
+    pub fn get_id(&self) -> &str {
+        &self.id
+    }
+    pub fn clear_id(&mut self) {
+        self.id.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_id(&mut self, v: ::std::string::String) {
+        self.id = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_id(&mut self) -> &mut ::std::string::String {
+        &mut self.id
+    }
+
+    // Take field
+    pub fn take_id(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.id, ::std::string::String::new())
+    }
+
+    // string name = 2;
+
+
+    pub fn get_name(&self) -> &str {
+        &self.name
+    }
+    pub fn clear_name(&mut self) {
+        self.name.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_name(&mut self, v: ::std::string::String) {
+        self.name = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_name(&mut self) -> &mut ::std::string::String {
+        &mut self.name
+    }
+
+    // Take field
+    pub fn take_name(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.name, ::std::string::String::new())
+    }
+
+    // string desc = 3;
+
+
+    pub fn get_desc(&self) -> &str {
+        &self.desc
+    }
+    pub fn clear_desc(&mut self) {
+        self.desc.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_desc(&mut self, v: ::std::string::String) {
+        self.desc = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_desc(&mut self) -> &mut ::std::string::String {
+        &mut self.desc
+    }
+
+    // Take field
+    pub fn take_desc(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.desc, ::std::string::String::new())
+    }
+
+    // .FieldType field_type = 4;
+
+
+    pub fn get_field_type(&self) -> FieldType {
+        self.field_type
+    }
+    pub fn clear_field_type(&mut self) {
+        self.field_type = FieldType::RichText;
+    }
+
+    // Param is passed by value, moved
+    pub fn set_field_type(&mut self, v: FieldType) {
+        self.field_type = v;
+    }
+
+    // bool frozen = 5;
+
+
+    pub fn get_frozen(&self) -> bool {
+        self.frozen
+    }
+    pub fn clear_frozen(&mut self) {
+        self.frozen = false;
+    }
+
+    // Param is passed by value, moved
+    pub fn set_frozen(&mut self, v: bool) {
+        self.frozen = v;
+    }
+
+    // bool visibility = 6;
+
+
+    pub fn get_visibility(&self) -> bool {
+        self.visibility
+    }
+    pub fn clear_visibility(&mut self) {
+        self.visibility = false;
+    }
+
+    // Param is passed by value, moved
+    pub fn set_visibility(&mut self, v: bool) {
+        self.visibility = v;
+    }
+
+    // int32 width = 7;
+
+
+    pub fn get_width(&self) -> i32 {
+        self.width
+    }
+    pub fn clear_width(&mut self) {
+        self.width = 0;
+    }
+
+    // Param is passed by value, moved
+    pub fn set_width(&mut self, v: i32) {
+        self.width = v;
+    }
+
+    // .AnyData type_options = 8;
+
+
+    pub fn get_type_options(&self) -> &AnyData {
+        self.type_options.as_ref().unwrap_or_else(|| <AnyData as ::protobuf::Message>::default_instance())
+    }
+    pub fn clear_type_options(&mut self) {
+        self.type_options.clear();
+    }
+
+    pub fn has_type_options(&self) -> bool {
+        self.type_options.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_type_options(&mut self, v: AnyData) {
+        self.type_options = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_type_options(&mut self) -> &mut AnyData {
+        if self.type_options.is_none() {
+            self.type_options.set_default();
+        }
+        self.type_options.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_type_options(&mut self) -> AnyData {
+        self.type_options.take().unwrap_or_else(|| AnyData::new())
+    }
+}
+
+impl ::protobuf::Message for Field {
+    fn is_initialized(&self) -> bool {
+        for v in &self.type_options {
+            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.id)?;
+                },
+                2 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?;
+                },
+                3 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.desc)?;
+                },
+                4 => {
+                    ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.field_type, 4, &mut self.unknown_fields)?
+                },
+                5 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_bool()?;
+                    self.frozen = tmp;
+                },
+                6 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_bool()?;
+                    self.visibility = tmp;
+                },
+                7 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_int32()?;
+                    self.width = tmp;
+                },
+                8 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.type_options)?;
+                },
+                _ => {
+                    ::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.id.is_empty() {
+            my_size += ::protobuf::rt::string_size(1, &self.id);
+        }
+        if !self.name.is_empty() {
+            my_size += ::protobuf::rt::string_size(2, &self.name);
+        }
+        if !self.desc.is_empty() {
+            my_size += ::protobuf::rt::string_size(3, &self.desc);
+        }
+        if self.field_type != FieldType::RichText {
+            my_size += ::protobuf::rt::enum_size(4, self.field_type);
+        }
+        if self.frozen != false {
+            my_size += 2;
+        }
+        if self.visibility != false {
+            my_size += 2;
+        }
+        if self.width != 0 {
+            my_size += ::protobuf::rt::value_size(7, self.width, ::protobuf::wire_format::WireTypeVarint);
+        }
+        if let Some(ref v) = self.type_options.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 !self.id.is_empty() {
+            os.write_string(1, &self.id)?;
+        }
+        if !self.name.is_empty() {
+            os.write_string(2, &self.name)?;
+        }
+        if !self.desc.is_empty() {
+            os.write_string(3, &self.desc)?;
+        }
+        if self.field_type != FieldType::RichText {
+            os.write_enum(4, ::protobuf::ProtobufEnum::value(&self.field_type))?;
+        }
+        if self.frozen != false {
+            os.write_bool(5, self.frozen)?;
+        }
+        if self.visibility != false {
+            os.write_bool(6, self.visibility)?;
+        }
+        if self.width != 0 {
+            os.write_int32(7, self.width)?;
+        }
+        if let Some(ref v) = self.type_options.as_ref() {
+            os.write_tag(8, ::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() -> Field {
+        Field::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>(
+                "id",
+                |m: &Field| { &m.id },
+                |m: &mut Field| { &mut m.id },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "name",
+                |m: &Field| { &m.name },
+                |m: &mut Field| { &mut m.name },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "desc",
+                |m: &Field| { &m.desc },
+                |m: &mut Field| { &mut m.desc },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum<FieldType>>(
+                "field_type",
+                |m: &Field| { &m.field_type },
+                |m: &mut Field| { &mut m.field_type },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>(
+                "frozen",
+                |m: &Field| { &m.frozen },
+                |m: &mut Field| { &mut m.frozen },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>(
+                "visibility",
+                |m: &Field| { &m.visibility },
+                |m: &mut Field| { &mut m.visibility },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>(
+                "width",
+                |m: &Field| { &m.width },
+                |m: &mut Field| { &mut m.width },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<AnyData>>(
+                "type_options",
+                |m: &Field| { &m.type_options },
+                |m: &mut Field| { &mut m.type_options },
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<Field>(
+                "Field",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static Field {
+        static instance: ::protobuf::rt::LazyV2<Field> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(Field::new)
+    }
+}
+
+impl ::protobuf::Clear for Field {
+    fn clear(&mut self) {
+        self.id.clear();
+        self.name.clear();
+        self.desc.clear();
+        self.field_type = FieldType::RichText;
+        self.frozen = false;
+        self.visibility = false;
+        self.width = 0;
+        self.type_options.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for Field {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for Field {
+    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+        ::protobuf::reflect::ReflectValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct RepeatedField {
+    // message fields
+    pub items: ::protobuf::RepeatedField<Field>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a RepeatedField {
+    fn default() -> &'a RepeatedField {
+        <RepeatedField as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl RepeatedField {
+    pub fn new() -> RepeatedField {
+        ::std::default::Default::default()
+    }
+
+    // repeated .Field items = 1;
+
+
+    pub fn get_items(&self) -> &[Field] {
+        &self.items
+    }
+    pub fn clear_items(&mut self) {
+        self.items.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_items(&mut self, v: ::protobuf::RepeatedField<Field>) {
+        self.items = v;
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_items(&mut self) -> &mut ::protobuf::RepeatedField<Field> {
+        &mut self.items
+    }
+
+    // Take field
+    pub fn take_items(&mut self) -> ::protobuf::RepeatedField<Field> {
+        ::std::mem::replace(&mut self.items, ::protobuf::RepeatedField::new())
+    }
+}
+
+impl ::protobuf::Message for RepeatedField {
+    fn is_initialized(&self) -> bool {
+        for v in &self.items {
+            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_repeated_message_into(wire_type, is, &mut self.items)?;
+                },
+                _ => {
+                    ::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;
+        for value in &self.items {
+            let len = value.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<()> {
+        for v in &self.items {
+            os.write_tag(1, ::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() -> RepeatedField {
+        RepeatedField::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_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<Field>>(
+                "items",
+                |m: &RepeatedField| { &m.items },
+                |m: &mut RepeatedField| { &mut m.items },
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<RepeatedField>(
+                "RepeatedField",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static RepeatedField {
+        static instance: ::protobuf::rt::LazyV2<RepeatedField> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(RepeatedField::new)
+    }
+}
+
+impl ::protobuf::Clear for RepeatedField {
+    fn clear(&mut self) {
+        self.items.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for RepeatedField {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for RepeatedField {
+    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+        ::protobuf::reflect::ReflectValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct AnyData {
+    // message fields
+    pub type_id: ::std::string::String,
+    pub value: ::std::vec::Vec<u8>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a AnyData {
+    fn default() -> &'a AnyData {
+        <AnyData as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl AnyData {
+    pub fn new() -> AnyData {
+        ::std::default::Default::default()
+    }
+
+    // string type_id = 1;
+
+
+    pub fn get_type_id(&self) -> &str {
+        &self.type_id
+    }
+    pub fn clear_type_id(&mut self) {
+        self.type_id.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_type_id(&mut self, v: ::std::string::String) {
+        self.type_id = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_type_id(&mut self) -> &mut ::std::string::String {
+        &mut self.type_id
+    }
+
+    // Take field
+    pub fn take_type_id(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.type_id, ::std::string::String::new())
+    }
+
+    // bytes value = 2;
+
+
+    pub fn get_value(&self) -> &[u8] {
+        &self.value
+    }
+    pub fn clear_value(&mut self) {
+        self.value.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_value(&mut self, v: ::std::vec::Vec<u8>) {
+        self.value = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_value(&mut self) -> &mut ::std::vec::Vec<u8> {
+        &mut self.value
+    }
+
+    // Take field
+    pub fn take_value(&mut self) -> ::std::vec::Vec<u8> {
+        ::std::mem::replace(&mut self.value, ::std::vec::Vec::new())
+    }
+}
+
+impl ::protobuf::Message for AnyData {
+    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.type_id)?;
+                },
+                2 => {
+                    ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.value)?;
+                },
+                _ => {
+                    ::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.type_id.is_empty() {
+            my_size += ::protobuf::rt::string_size(1, &self.type_id);
+        }
+        if !self.value.is_empty() {
+            my_size += ::protobuf::rt::bytes_size(2, &self.value);
+        }
+        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.type_id.is_empty() {
+            os.write_string(1, &self.type_id)?;
+        }
+        if !self.value.is_empty() {
+            os.write_bytes(2, &self.value)?;
+        }
+        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() -> AnyData {
+        AnyData::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>(
+                "type_id",
+                |m: &AnyData| { &m.type_id },
+                |m: &mut AnyData| { &mut m.type_id },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
+                "value",
+                |m: &AnyData| { &m.value },
+                |m: &mut AnyData| { &mut m.value },
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<AnyData>(
+                "AnyData",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static AnyData {
+        static instance: ::protobuf::rt::LazyV2<AnyData> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(AnyData::new)
+    }
+}
+
+impl ::protobuf::Clear for AnyData {
+    fn clear(&mut self) {
+        self.type_id.clear();
+        self.value.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for AnyData {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for AnyData {
+    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+        ::protobuf::reflect::ReflectValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct RowMeta {
+    // message fields
+    pub id: ::std::string::String,
+    pub grid_id: ::std::string::String,
+    pub cell_by_field_id: ::std::collections::HashMap<::std::string::String, CellMeta>,
+    pub height: i32,
+    pub visibility: bool,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a RowMeta {
+    fn default() -> &'a RowMeta {
+        <RowMeta as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl RowMeta {
+    pub fn new() -> RowMeta {
+        ::std::default::Default::default()
+    }
+
+    // string id = 1;
+
+
+    pub fn get_id(&self) -> &str {
+        &self.id
+    }
+    pub fn clear_id(&mut self) {
+        self.id.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_id(&mut self, v: ::std::string::String) {
+        self.id = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_id(&mut self) -> &mut ::std::string::String {
+        &mut self.id
+    }
+
+    // Take field
+    pub fn take_id(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.id, ::std::string::String::new())
+    }
+
+    // string grid_id = 2;
+
+
+    pub fn get_grid_id(&self) -> &str {
+        &self.grid_id
+    }
+    pub fn clear_grid_id(&mut self) {
+        self.grid_id.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_grid_id(&mut self, v: ::std::string::String) {
+        self.grid_id = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_grid_id(&mut self) -> &mut ::std::string::String {
+        &mut self.grid_id
+    }
+
+    // Take field
+    pub fn take_grid_id(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.grid_id, ::std::string::String::new())
+    }
+
+    // repeated .RowMeta.CellByFieldIdEntry cell_by_field_id = 3;
+
+
+    pub fn get_cell_by_field_id(&self) -> &::std::collections::HashMap<::std::string::String, CellMeta> {
+        &self.cell_by_field_id
+    }
+    pub fn clear_cell_by_field_id(&mut self) {
+        self.cell_by_field_id.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_cell_by_field_id(&mut self, v: ::std::collections::HashMap<::std::string::String, CellMeta>) {
+        self.cell_by_field_id = v;
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_cell_by_field_id(&mut self) -> &mut ::std::collections::HashMap<::std::string::String, CellMeta> {
+        &mut self.cell_by_field_id
+    }
+
+    // Take field
+    pub fn take_cell_by_field_id(&mut self) -> ::std::collections::HashMap<::std::string::String, CellMeta> {
+        ::std::mem::replace(&mut self.cell_by_field_id, ::std::collections::HashMap::new())
+    }
+
+    // int32 height = 4;
+
+
+    pub fn get_height(&self) -> i32 {
+        self.height
+    }
+    pub fn clear_height(&mut self) {
+        self.height = 0;
+    }
+
+    // Param is passed by value, moved
+    pub fn set_height(&mut self, v: i32) {
+        self.height = v;
+    }
+
+    // bool visibility = 5;
+
+
+    pub fn get_visibility(&self) -> bool {
+        self.visibility
+    }
+    pub fn clear_visibility(&mut self) {
+        self.visibility = false;
+    }
+
+    // Param is passed by value, moved
+    pub fn set_visibility(&mut self, v: bool) {
+        self.visibility = v;
+    }
+}
+
+impl ::protobuf::Message for RowMeta {
+    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.id)?;
+                },
+                2 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?;
+                },
+                3 => {
+                    ::protobuf::rt::read_map_into::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage<CellMeta>>(wire_type, is, &mut self.cell_by_field_id)?;
+                },
+                4 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_int32()?;
+                    self.height = tmp;
+                },
+                5 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_bool()?;
+                    self.visibility = tmp;
+                },
+                _ => {
+                    ::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.id.is_empty() {
+            my_size += ::protobuf::rt::string_size(1, &self.id);
+        }
+        if !self.grid_id.is_empty() {
+            my_size += ::protobuf::rt::string_size(2, &self.grid_id);
+        }
+        my_size += ::protobuf::rt::compute_map_size::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage<CellMeta>>(3, &self.cell_by_field_id);
+        if self.height != 0 {
+            my_size += ::protobuf::rt::value_size(4, self.height, ::protobuf::wire_format::WireTypeVarint);
+        }
+        if self.visibility != false {
+            my_size += 2;
+        }
+        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.id.is_empty() {
+            os.write_string(1, &self.id)?;
+        }
+        if !self.grid_id.is_empty() {
+            os.write_string(2, &self.grid_id)?;
+        }
+        ::protobuf::rt::write_map_with_cached_sizes::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage<CellMeta>>(3, &self.cell_by_field_id, os)?;
+        if self.height != 0 {
+            os.write_int32(4, self.height)?;
+        }
+        if self.visibility != false {
+            os.write_bool(5, self.visibility)?;
+        }
+        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() -> RowMeta {
+        RowMeta::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>(
+                "id",
+                |m: &RowMeta| { &m.id },
+                |m: &mut RowMeta| { &mut m.id },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "grid_id",
+                |m: &RowMeta| { &m.grid_id },
+                |m: &mut RowMeta| { &mut m.grid_id },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_map_accessor::<_, ::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage<CellMeta>>(
+                "cell_by_field_id",
+                |m: &RowMeta| { &m.cell_by_field_id },
+                |m: &mut RowMeta| { &mut m.cell_by_field_id },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>(
+                "height",
+                |m: &RowMeta| { &m.height },
+                |m: &mut RowMeta| { &mut m.height },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>(
+                "visibility",
+                |m: &RowMeta| { &m.visibility },
+                |m: &mut RowMeta| { &mut m.visibility },
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<RowMeta>(
+                "RowMeta",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static RowMeta {
+        static instance: ::protobuf::rt::LazyV2<RowMeta> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(RowMeta::new)
+    }
+}
+
+impl ::protobuf::Clear for RowMeta {
+    fn clear(&mut self) {
+        self.id.clear();
+        self.grid_id.clear();
+        self.cell_by_field_id.clear();
+        self.height = 0;
+        self.visibility = false;
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for RowMeta {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for RowMeta {
+    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+        ::protobuf::reflect::ReflectValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct CellMeta {
+    // message fields
+    pub id: ::std::string::String,
+    pub row_id: ::std::string::String,
+    pub field_id: ::std::string::String,
+    pub data: ::protobuf::SingularPtrField<AnyData>,
+    pub height: i32,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a CellMeta {
+    fn default() -> &'a CellMeta {
+        <CellMeta as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl CellMeta {
+    pub fn new() -> CellMeta {
+        ::std::default::Default::default()
+    }
+
+    // string id = 1;
+
+
+    pub fn get_id(&self) -> &str {
+        &self.id
+    }
+    pub fn clear_id(&mut self) {
+        self.id.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_id(&mut self, v: ::std::string::String) {
+        self.id = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_id(&mut self) -> &mut ::std::string::String {
+        &mut self.id
+    }
+
+    // Take field
+    pub fn take_id(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.id, ::std::string::String::new())
+    }
+
+    // string row_id = 2;
+
+
+    pub fn get_row_id(&self) -> &str {
+        &self.row_id
+    }
+    pub fn clear_row_id(&mut self) {
+        self.row_id.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_row_id(&mut self, v: ::std::string::String) {
+        self.row_id = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_row_id(&mut self) -> &mut ::std::string::String {
+        &mut self.row_id
+    }
+
+    // Take field
+    pub fn take_row_id(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.row_id, ::std::string::String::new())
+    }
+
+    // string field_id = 3;
+
+
+    pub fn get_field_id(&self) -> &str {
+        &self.field_id
+    }
+    pub fn clear_field_id(&mut self) {
+        self.field_id.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_field_id(&mut self, v: ::std::string::String) {
+        self.field_id = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_field_id(&mut self) -> &mut ::std::string::String {
+        &mut self.field_id
+    }
+
+    // Take field
+    pub fn take_field_id(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.field_id, ::std::string::String::new())
+    }
+
+    // .AnyData data = 4;
+
+
+    pub fn get_data(&self) -> &AnyData {
+        self.data.as_ref().unwrap_or_else(|| <AnyData as ::protobuf::Message>::default_instance())
+    }
+    pub fn clear_data(&mut self) {
+        self.data.clear();
+    }
+
+    pub fn has_data(&self) -> bool {
+        self.data.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_data(&mut self, v: AnyData) {
+        self.data = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_data(&mut self) -> &mut AnyData {
+        if self.data.is_none() {
+            self.data.set_default();
+        }
+        self.data.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_data(&mut self) -> AnyData {
+        self.data.take().unwrap_or_else(|| AnyData::new())
+    }
+
+    // int32 height = 5;
+
+
+    pub fn get_height(&self) -> i32 {
+        self.height
+    }
+    pub fn clear_height(&mut self) {
+        self.height = 0;
+    }
+
+    // Param is passed by value, moved
+    pub fn set_height(&mut self, v: i32) {
+        self.height = v;
+    }
+}
+
+impl ::protobuf::Message for CellMeta {
+    fn is_initialized(&self) -> bool {
+        for v in &self.data {
+            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.id)?;
+                },
+                2 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.row_id)?;
+                },
+                3 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?;
+                },
+                4 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.data)?;
+                },
+                5 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    let tmp = is.read_int32()?;
+                    self.height = tmp;
+                },
+                _ => {
+                    ::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.id.is_empty() {
+            my_size += ::protobuf::rt::string_size(1, &self.id);
+        }
+        if !self.row_id.is_empty() {
+            my_size += ::protobuf::rt::string_size(2, &self.row_id);
+        }
+        if !self.field_id.is_empty() {
+            my_size += ::protobuf::rt::string_size(3, &self.field_id);
+        }
+        if let Some(ref v) = self.data.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        if self.height != 0 {
+            my_size += ::protobuf::rt::value_size(5, self.height, ::protobuf::wire_format::WireTypeVarint);
+        }
+        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.id.is_empty() {
+            os.write_string(1, &self.id)?;
+        }
+        if !self.row_id.is_empty() {
+            os.write_string(2, &self.row_id)?;
+        }
+        if !self.field_id.is_empty() {
+            os.write_string(3, &self.field_id)?;
+        }
+        if let Some(ref v) = self.data.as_ref() {
+            os.write_tag(4, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        if self.height != 0 {
+            os.write_int32(5, self.height)?;
+        }
+        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() -> CellMeta {
+        CellMeta::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>(
+                "id",
+                |m: &CellMeta| { &m.id },
+                |m: &mut CellMeta| { &mut m.id },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "row_id",
+                |m: &CellMeta| { &m.row_id },
+                |m: &mut CellMeta| { &mut m.row_id },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "field_id",
+                |m: &CellMeta| { &m.field_id },
+                |m: &mut CellMeta| { &mut m.field_id },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<AnyData>>(
+                "data",
+                |m: &CellMeta| { &m.data },
+                |m: &mut CellMeta| { &mut m.data },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>(
+                "height",
+                |m: &CellMeta| { &m.height },
+                |m: &mut CellMeta| { &mut m.height },
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<CellMeta>(
+                "CellMeta",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static CellMeta {
+        static instance: ::protobuf::rt::LazyV2<CellMeta> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(CellMeta::new)
+    }
+}
+
+impl ::protobuf::Clear for CellMeta {
+    fn clear(&mut self) {
+        self.id.clear();
+        self.row_id.clear();
+        self.field_id.clear();
+        self.data.clear();
+        self.height = 0;
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for CellMeta {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for CellMeta {
+    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+        ::protobuf::reflect::ReflectValueRef::Message(self)
+    }
+}
+
+#[derive(Clone,PartialEq,Eq,Debug,Hash)]
+pub enum FieldType {
+    RichText = 0,
+    Number = 1,
+    DateTime = 2,
+    SingleSelect = 3,
+    MultiSelect = 4,
+    Checkbox = 5,
+}
+
+impl ::protobuf::ProtobufEnum for FieldType {
+    fn value(&self) -> i32 {
+        *self as i32
+    }
+
+    fn from_i32(value: i32) -> ::std::option::Option<FieldType> {
+        match value {
+            0 => ::std::option::Option::Some(FieldType::RichText),
+            1 => ::std::option::Option::Some(FieldType::Number),
+            2 => ::std::option::Option::Some(FieldType::DateTime),
+            3 => ::std::option::Option::Some(FieldType::SingleSelect),
+            4 => ::std::option::Option::Some(FieldType::MultiSelect),
+            5 => ::std::option::Option::Some(FieldType::Checkbox),
+            _ => ::std::option::Option::None
+        }
+    }
+
+    fn values() -> &'static [Self] {
+        static values: &'static [FieldType] = &[
+            FieldType::RichText,
+            FieldType::Number,
+            FieldType::DateTime,
+            FieldType::SingleSelect,
+            FieldType::MultiSelect,
+            FieldType::Checkbox,
+        ];
+        values
+    }
+
+    fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor {
+        static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT;
+        descriptor.get(|| {
+            ::protobuf::reflect::EnumDescriptor::new_pb_name::<FieldType>("FieldType", file_descriptor_proto())
+        })
+    }
+}
+
+impl ::std::marker::Copy for FieldType {
+}
+
+impl ::std::default::Default for FieldType {
+    fn default() -> Self {
+        FieldType::RichText
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for FieldType {
+    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+        ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self))
+    }
+}
+
+static file_descriptor_proto_data: &'static [u8] = b"\
+    \n\nmeta.proto\"a\n\x08GridMeta\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\
+    \x06gridId\x12\x1e\n\x06fields\x18\x02\x20\x03(\x0b2\x06.FieldR\x06field\
+    s\x12\x1c\n\x04rows\x18\x03\x20\x03(\x0b2\x08.RowMetaR\x04rows\"9\n\tGri\
+    dBlock\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x1c\n\x04rows\x18\
+    \x02\x20\x03(\x0b2\x08.RowMetaR\x04rows\"\xe5\x01\n\x05Field\x12\x0e\n\
+    \x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\
+    \x04name\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_typ\
+    e\x18\x04\x20\x01(\x0e2\n.FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\
+    \x05\x20\x01(\x08R\x06frozen\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\
+    \nvisibility\x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05width\x12+\n\
+    \x0ctype_options\x18\x08\x20\x01(\x0b2\x08.AnyDataR\x0btypeOptions\"-\n\
+    \rRepeatedField\x12\x1c\n\x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05i\
+    tems\"8\n\x07AnyData\x12\x17\n\x07type_id\x18\x01\x20\x01(\tR\x06typeId\
+    \x12\x14\n\x05value\x18\x02\x20\x01(\x0cR\x05value\"\xfd\x01\n\x07RowMet\
+    a\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x17\n\x07grid_id\x18\x02\
+    \x20\x01(\tR\x06gridId\x12D\n\x10cell_by_field_id\x18\x03\x20\x03(\x0b2\
+    \x1b.RowMeta.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\
+    \x04\x20\x01(\x05R\x06height\x12\x1e\n\nvisibility\x18\x05\x20\x01(\x08R\
+    \nvisibility\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\
+    \x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05\
+    value:\x028\x01\"\x82\x01\n\x08CellMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\
+    \tR\x02id\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08\
+    field_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x1c\n\x04data\x18\x04\x20\
+    \x01(\x0b2\x08.AnyDataR\x04data\x12\x16\n\x06height\x18\x05\x20\x01(\x05\
+    R\x06height*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Number\
+    \x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\
+    \x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06prot\
+    o3\
+";
+
+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

@@ -3,3 +3,6 @@
 
 mod grid;
 pub use grid::*;
+
+mod meta;
+pub use meta::*;

+ 6 - 52
shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto

@@ -2,72 +2,34 @@ syntax = "proto3";
 
 message Grid {
     string id = 1;
-    RepeatedFieldOrder field_orders = 2;
-    RepeatedRowOrder row_orders = 3;
+    repeated FieldOrder field_orders = 2;
+    repeated RowOrder row_orders = 3;
 }
 message FieldOrder {
     string field_id = 1;
-    bool visibility = 2;
 }
 message RepeatedFieldOrder {
     repeated FieldOrder items = 1;
 }
-message Field {
-    string id = 1;
-    string name = 2;
-    string desc = 3;
-    FieldType field_type = 4;
-    bool frozen = 5;
-    int32 width = 6;
-    AnyData type_options = 7;
-}
-message RepeatedField {
-    repeated Field items = 1;
-}
-message AnyData {
-    string type_id = 1;
-    bytes value = 2;
-}
 message RowOrder {
-    string grid_id = 1;
-    string row_id = 2;
-    bool visibility = 3;
+    string row_id = 1;
 }
 message RepeatedRowOrder {
     repeated RowOrder items = 1;
 }
-message RawRow {
-    string id = 1;
-    string grid_id = 2;
-    map<string, RawCell> cell_by_field_id = 3;
-    int32 height = 4;
-}
-message RawCell {
-    string id = 1;
-    string row_id = 2;
-    string field_id = 3;
-    AnyData data = 4;
-    int32 height = 5;
-}
-message RepeatedRow {
-    repeated Row items = 1;
-}
 message Row {
     string id = 1;
     map<string, Cell> cell_by_field_id = 2;
     int32 height = 3;
 }
+message RepeatedRow {
+    repeated Row items = 1;
+}
 message Cell {
     string id = 1;
     string field_id = 2;
     string content = 3;
 }
-message CellChangeset {
-    string id = 1;
-    string row_id = 2;
-    string field_id = 3;
-    string data = 4;
-}
 message CreateGridPayload {
     string name = 1;
 }
@@ -82,11 +44,3 @@ message QueryRowPayload {
     string grid_id = 1;
     RepeatedRowOrder row_orders = 2;
 }
-enum FieldType {
-    RichText = 0;
-    Number = 1;
-    DateTime = 2;
-    SingleSelect = 3;
-    MultiSelect = 4;
-    Checkbox = 5;
-}

+ 50 - 0
shared-lib/flowy-grid-data-model/src/protobuf/proto/meta.proto

@@ -0,0 +1,50 @@
+syntax = "proto3";
+
+message GridMeta {
+    string grid_id = 1;
+    repeated Field fields = 2;
+    repeated RowMeta rows = 3;
+}
+message GridBlock {
+    string id = 1;
+    repeated RowMeta rows = 2;
+}
+message Field {
+    string id = 1;
+    string name = 2;
+    string desc = 3;
+    FieldType field_type = 4;
+    bool frozen = 5;
+    bool visibility = 6;
+    int32 width = 7;
+    AnyData type_options = 8;
+}
+message RepeatedField {
+    repeated Field items = 1;
+}
+message AnyData {
+    string type_id = 1;
+    bytes value = 2;
+}
+message RowMeta {
+    string id = 1;
+    string grid_id = 2;
+    map<string, CellMeta> cell_by_field_id = 3;
+    int32 height = 4;
+    bool visibility = 5;
+}
+message CellMeta {
+    string id = 1;
+    string row_id = 2;
+    string field_id = 3;
+    AnyData data = 4;
+    int32 height = 5;
+}
+enum FieldType {
+    RichText = 0;
+    Number = 1;
+    DateTime = 2;
+    SingleSelect = 3;
+    MultiSelect = 4;
+    Checkbox = 5;
+}

+ 16 - 34
shared-lib/flowy-grid-data-model/tests/serde_test.rs

@@ -3,54 +3,36 @@ use flowy_grid_data_model::entities::*;
 #[test]
 fn grid_serde_test() {
     let grid_id = "1".to_owned();
-    let field_orders = RepeatedFieldOrder {
-        items: vec![create_field_order("1")],
-    };
-    let row_orders = RepeatedRowOrder {
-        items: vec![create_row_order(&grid_id, "1")],
-    };
-
-    let grid = Grid {
-        id: grid_id,
-        field_orders,
-        row_orders,
+    let fields = vec![create_field("1")];
+    let grid = GridMeta {
+        grid_id,
+        fields,
+        rows: vec![],
     };
 
-    let json = serde_json::to_string(&grid).unwrap();
-    let grid2: Grid = serde_json::from_str(&json).unwrap();
-    assert_eq!(grid, grid2);
+    let grid_1_json = serde_json::to_string(&grid).unwrap();
+    let _: Grid = serde_json::from_str(&grid_1_json).unwrap();
     assert_eq!(
-        json,
-        r#"{"id":"1","field_orders":[{"field_id":"1","visibility":false}],"row_orders":[{"grid_id":"1","row_id":"1","visibility":false}]}"#
+        grid_1_json,
+        r#"{"id":"1","fields":[{"id":"1","name":"Text Field","desc":"","field_type":"RichText","frozen":false,"visibility":true,"width":150,"type_options":{"type_id":"","value":[]}}],"rows":[]}"#
     )
 }
 
 #[test]
 fn grid_default_serde_test() {
     let grid_id = "1".to_owned();
-    let grid = Grid {
-        id: grid_id,
-        field_orders: RepeatedFieldOrder::default(),
-        row_orders: RepeatedRowOrder::default(),
+    let grid = GridMeta {
+        grid_id,
+        fields: vec![],
+        rows: vec![],
     };
 
     let json = serde_json::to_string(&grid).unwrap();
-    assert_eq!(json, r#"{"id":"1","field_orders":[],"row_orders":[]}"#)
-}
-
-fn create_field_order(field_id: &str) -> FieldOrder {
-    FieldOrder {
-        field_id: field_id.to_owned(),
-        visibility: false,
-    }
+    assert_eq!(json, r#"{"id":"1","fields":[],"row_orders":[]}"#)
 }
 
-fn create_row_order(grid_id: &str, row_id: &str) -> RowOrder {
-    RowOrder {
-        grid_id: grid_id.to_string(),
-        row_id: row_id.to_string(),
-        visibility: false,
-    }
+fn create_field(field_id: &str) -> Field {
+    Field::new(field_id, "Text Field", "", FieldType::RichText)
 }
 
 #[allow(dead_code)]

部分文件因文件數量過多而無法顯示