Sfoglia il codice sorgente

refactor: separate grid revision structs from entities

appflowy 3 anni fa
parent
commit
a13e6798ee
84 ha cambiato i file con 8131 aggiunte e 3324 eliminazioni
  1. 1 0
      frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cell_service.dart
  2. 1 1
      frontend/app_flowy/lib/workspace/application/grid/cell/date_cell_bloc.dart
  3. 1 1
      frontend/app_flowy/lib/workspace/application/grid/field/field_action_sheet_bloc.dart
  4. 1 1
      frontend/app_flowy/lib/workspace/application/grid/field/field_cell_bloc.dart
  5. 1 1
      frontend/app_flowy/lib/workspace/application/grid/field/field_editor_pannel_bloc.dart
  6. 1 1
      frontend/app_flowy/lib/workspace/application/grid/field/field_listener.dart
  7. 1 0
      frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart
  8. 1 1
      frontend/app_flowy/lib/workspace/application/grid/field/grid_listenr.dart
  9. 1 1
      frontend/app_flowy/lib/workspace/application/grid/field/type_option/type_option_service.dart
  10. 1 1
      frontend/app_flowy/lib/workspace/application/grid/grid_header_bloc.dart
  11. 1 0
      frontend/app_flowy/lib/workspace/application/grid/grid_service.dart
  12. 1 1
      frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart
  13. 1 0
      frontend/app_flowy/lib/workspace/application/grid/row/row_listener.dart
  14. 1 0
      frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart
  15. 1 1
      frontend/app_flowy/lib/workspace/application/grid/setting/property_bloc.dart
  16. 1 2
      frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart
  17. 1 1
      frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart
  18. 1 1
      frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart
  19. 1 1
      frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor_pannel.dart
  20. 1 1
      frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_extension.dart
  21. 1 1
      frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart
  22. 1 1
      frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart
  23. 1 1
      frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/row_detail.dart
  24. 1 1
      frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart
  25. 17 0
      frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-folder/dart_event.dart
  26. 2 0
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart
  27. 2 1
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart
  28. 173 39
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view_info.pb.dart
  29. 26 8
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view_info.pbjson.dart
  30. 2 0
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder/event_map.pbenum.dart
  31. 2 1
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder/event_map.pbjson.dart
  32. 1246 0
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/field.pb.dart
  33. 36 0
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/field.pbenum.dart
  34. 215 0
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/field.pbjson.dart
  35. 9 0
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/field.pbserver.dart
  36. 7 986
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart
  37. 0 25
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbenum.dart
  38. 0 205
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart
  39. 1 0
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/protobuf.dart
  40. 10 6
      frontend/rust-lib/flowy-folder/src/protobuf/model/event_map.rs
  41. 1 0
      frontend/rust-lib/flowy-folder/src/protobuf/proto/event_map.proto
  42. 3 20
      frontend/rust-lib/flowy-folder/src/services/view/controller.rs
  43. 30 29
      frontend/rust-lib/flowy-grid/src/event_handler.rs
  44. 3 3
      frontend/rust-lib/flowy-grid/src/macros.rs
  45. 4 4
      frontend/rust-lib/flowy-grid/src/manager.rs
  46. 46 44
      frontend/rust-lib/flowy-grid/src/services/block_manager.rs
  47. 23 22
      frontend/rust-lib/flowy-grid/src/services/block_revision_editor.rs
  48. 18 17
      frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs
  49. 17 19
      frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs
  50. 40 35
      frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs
  51. 36 37
      frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option/number_type_option.rs
  52. 39 40
      frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs
  53. 14 15
      frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs
  54. 15 15
      frontend/rust-lib/flowy-grid/src/services/field/type_options/url_type_option.rs
  55. 3 3
      frontend/rust-lib/flowy-grid/src/services/field/type_options/util.rs
  56. 89 90
      frontend/rust-lib/flowy-grid/src/services/grid_editor.rs
  57. 2 2
      frontend/rust-lib/flowy-grid/src/services/mod.rs
  58. 32 31
      frontend/rust-lib/flowy-grid/src/services/row/cell_data_operation.rs
  59. 17 17
      frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs
  60. 29 30
      frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs
  61. 2 1
      frontend/rust-lib/flowy-grid/src/util.rs
  62. 36 36
      frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs
  63. 72 78
      frontend/rust-lib/flowy-grid/tests/grid/script.rs
  64. 6 9
      frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs
  65. 6 3
      shared-lib/flowy-error-code/src/protobuf/model/code.rs
  66. 1 0
      shared-lib/flowy-error-code/src/protobuf/proto/code.proto
  67. 533 101
      shared-lib/flowy-folder-data-model/src/protobuf/model/view_info.rs
  68. 10 4
      shared-lib/flowy-folder-data-model/src/protobuf/proto/view_info.proto
  69. 1 1
      shared-lib/flowy-grid-data-model/Flowy.toml
  70. 525 0
      shared-lib/flowy-grid-data-model/src/entities/field.rs
  71. 6 586
      shared-lib/flowy-grid-data-model/src/entities/grid.rs
  72. 2 2
      shared-lib/flowy-grid-data-model/src/entities/mod.rs
  73. 1 0
      shared-lib/flowy-grid-data-model/src/lib.rs
  74. 4104 0
      shared-lib/flowy-grid-data-model/src/protobuf/model/field.rs
  75. 241 469
      shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs
  76. 3 0
      shared-lib/flowy-grid-data-model/src/protobuf/model/mod.rs
  77. 87 0
      shared-lib/flowy-grid-data-model/src/protobuf/proto/field.proto
  78. 1 85
      shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto
  79. 86 23
      shared-lib/flowy-grid-data-model/src/revision/mod.rs
  80. 2 2
      shared-lib/flowy-grid-data-model/tests/serde_test.rs
  81. 77 72
      shared-lib/flowy-sync/src/client_grid/grid_block_revsion_pad.rs
  82. 18 15
      shared-lib/flowy-sync/src/client_grid/grid_builder.rs
  83. 74 69
      shared-lib/flowy-sync/src/client_grid/grid_revision_pad.rs
  84. 4 4
      shared-lib/flowy-sync/src/client_grid/mod.rs

+ 1 - 0
frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cell_service.dart

@@ -6,6 +6,7 @@ import 'package:equatable/equatable.dart';
 import 'package:flowy_sdk/dispatch/dispatch.dart';
 import 'package:flowy_sdk/log.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-grid-data-model/field.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/cell_entities.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart';

+ 1 - 1
frontend/app_flowy/lib/workspace/application/grid/cell/date_cell_bloc.dart

@@ -1,4 +1,4 @@
-import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Field;
+import 'package:flowy_sdk/protobuf/flowy-grid-data-model/field.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';

+ 1 - 1
frontend/app_flowy/lib/workspace/application/grid/field/field_action_sheet_bloc.dart

@@ -1,5 +1,5 @@
 import 'package:flowy_sdk/log.dart';
-import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-grid-data-model/field.pb.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
 import 'dart:async';

+ 1 - 1
frontend/app_flowy/lib/workspace/application/grid/field/field_cell_bloc.dart

@@ -1,7 +1,7 @@
 import 'package:app_flowy/workspace/application/grid/field/field_listener.dart';
 import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
 import 'package:flowy_sdk/log.dart';
-import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Field;
+import 'package:flowy_sdk/protobuf/flowy-grid-data-model/field.pb.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
 import 'dart:async';

+ 1 - 1
frontend/app_flowy/lib/workspace/application/grid/field/field_editor_pannel_bloc.dart

@@ -1,4 +1,4 @@
-import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-grid-data-model/field.pb.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
 import 'dart:async';

+ 1 - 1
frontend/app_flowy/lib/workspace/application/grid/field/field_listener.dart

@@ -1,6 +1,6 @@
 import 'package:dartz/dartz.dart';
-import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-grid-data-model/field.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
 import 'package:flowy_infra/notifier.dart';
 import 'dart:async';

+ 1 - 0
frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart

@@ -2,6 +2,7 @@ import 'package:dartz/dartz.dart';
 import 'package:flowy_sdk/dispatch/dispatch.dart';
 import 'package:flowy_sdk/log.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-grid-data-model/field.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
 import 'package:flutter/foundation.dart';

+ 1 - 1
frontend/app_flowy/lib/workspace/application/grid/field/grid_listenr.dart

@@ -1,5 +1,5 @@
 import 'package:dartz/dartz.dart';
-import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-grid-data-model/field.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
 import 'package:flowy_infra/notifier.dart';

+ 1 - 1
frontend/app_flowy/lib/workspace/application/grid/field/type_option/type_option_service.dart

@@ -4,7 +4,7 @@ import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
 import 'package:dartz/dartz.dart';
 import 'package:flowy_sdk/dispatch/dispatch.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
-import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-grid-data-model/field.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/cell_entities.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart';

+ 1 - 1
frontend/app_flowy/lib/workspace/application/grid/grid_header_bloc.dart

@@ -1,6 +1,6 @@
 import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
 import 'package:flowy_sdk/log.dart';
-import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-grid-data-model/field.pb.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
 import 'dart:async';

+ 1 - 0
frontend/app_flowy/lib/workspace/application/grid/grid_service.dart

@@ -6,6 +6,7 @@ import 'package:flowy_sdk/dispatch/dispatch.dart';
 import 'package:flowy_sdk/log.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-grid-data-model/field.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
 import 'package:flutter/foundation.dart';
 import 'cell/cell_service/cell_service.dart';

+ 1 - 1
frontend/app_flowy/lib/workspace/application/grid/row/row_bloc.dart

@@ -1,7 +1,7 @@
 import 'dart:collection';
 import 'package:app_flowy/workspace/application/grid/cell/cell_service/cell_service.dart';
 import 'package:equatable/equatable.dart';
-import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Field;
+import 'package:flowy_sdk/protobuf/flowy-grid-data-model/field.pb.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
 import 'dart:async';

+ 1 - 0
frontend/app_flowy/lib/workspace/application/grid/row/row_listener.dart

@@ -1,4 +1,5 @@
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-grid-data-model/field.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
 import 'package:flowy_infra/notifier.dart';

+ 1 - 0
frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart

@@ -5,6 +5,7 @@ import 'package:dartz/dartz.dart';
 import 'package:flowy_sdk/dispatch/dispatch.dart';
 import 'package:flowy_sdk/log.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-grid-data-model/field.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/row_entities.pb.dart';
 import 'package:flutter/foundation.dart';

+ 1 - 1
frontend/app_flowy/lib/workspace/application/grid/setting/property_bloc.dart

@@ -1,7 +1,7 @@
 import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
 import 'package:app_flowy/workspace/application/grid/grid_service.dart';
 import 'package:flowy_sdk/log.dart';
-import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-grid-data-model/field.pb.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
 import 'dart:async';

+ 1 - 2
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/layout/layout.dart

@@ -1,5 +1,4 @@
-import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
-
+import 'package:flowy_sdk/protobuf/flowy-grid-data-model/field.pb.dart';
 import 'sizes.dart';
 
 class GridLayout {

+ 1 - 1
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart

@@ -1,5 +1,5 @@
 import 'package:app_flowy/workspace/application/grid/cell/cell_service/cell_service.dart';
-import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show FieldType;
+import 'package:flowy_sdk/protobuf/flowy-grid-data-model/field.pb.dart';
 import 'package:flutter/services.dart';
 import 'package:flutter/widgets.dart';
 import 'package:flutter/material.dart';

+ 1 - 1
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart

@@ -6,7 +6,7 @@ import 'package:flowy_infra/theme.dart';
 import 'package:flowy_infra_ui/style_widget/button.dart';
 import 'package:flowy_infra_ui/style_widget/hover.dart';
 import 'package:flowy_infra_ui/style_widget/text.dart';
-import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Field;
+import 'package:flowy_sdk/protobuf/flowy-grid-data-model/field.pb.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'field_type_extension.dart';

+ 1 - 1
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_editor_pannel.dart

@@ -10,7 +10,7 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart';
 import 'package:flowy_infra_ui/style_widget/button.dart';
 import 'package:flowy_infra_ui/style_widget/text.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
-import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-grid-data-model/field.pb.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:app_flowy/workspace/application/grid/prelude.dart';

+ 1 - 1
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_extension.dart

@@ -1,4 +1,4 @@
-import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show FieldType;
+import 'package:flowy_sdk/protobuf/flowy-grid-data-model/field.pb.dart';
 import 'package:app_flowy/generated/locale_keys.g.dart';
 import 'package:easy_localization/easy_localization.dart';
 

+ 1 - 1
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart

@@ -6,7 +6,7 @@ import 'package:flowy_infra_ui/style_widget/button.dart';
 import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
 import 'package:flowy_infra_ui/style_widget/text.dart';
 import 'package:flowy_infra_ui/widget/spacing.dart';
-import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show FieldType;
+import 'package:flowy_sdk/protobuf/flowy-grid-data-model/field.pb.dart';
 import 'package:flutter/material.dart';
 import 'field_type_extension.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';

+ 1 - 1
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header.dart

@@ -5,7 +5,7 @@ import 'package:flowy_infra/image.dart';
 import 'package:flowy_infra/theme.dart';
 import 'package:flowy_infra_ui/style_widget/button.dart';
 import 'package:flowy_infra_ui/style_widget/text.dart';
-import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' hide Row;
+import 'package:flowy_sdk/protobuf/flowy-grid-data-model/field.pb.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:reorderables/reorderables.dart';

+ 1 - 1
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/row_detail.dart

@@ -14,7 +14,7 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart';
 import 'package:flowy_infra_ui/style_widget/icon_button.dart';
 import 'package:flowy_infra_ui/style_widget/scrolling/styled_scroll_bar.dart';
 import 'package:flowy_infra_ui/widget/spacing.dart';
-import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show FieldType;
+import 'package:flowy_sdk/protobuf/flowy-grid-data-model/field.pb.dart';
 import 'package:easy_localization/easy_localization.dart';
 import 'package:app_flowy/generated/locale_keys.g.dart';
 import 'package:flutter/material.dart';

+ 1 - 1
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/toolbar/grid_property.dart

@@ -12,7 +12,7 @@ import 'package:flowy_infra_ui/style_widget/button.dart';
 import 'package:flowy_infra_ui/style_widget/icon_button.dart';
 import 'package:flowy_infra_ui/style_widget/text.dart';
 import 'package:flowy_infra_ui/widget/spacing.dart';
-import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Field;
+import 'package:flowy_sdk/protobuf/flowy-grid-data-model/field.pb.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:styled_widget/styled_widget.dart';

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

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

+ 2 - 0
frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbenum.dart

@@ -53,6 +53,7 @@ class ErrorCode extends $pb.ProtobufEnum {
   static const ErrorCode FieldInvalidOperation = ErrorCode._(444, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'FieldInvalidOperation');
   static const ErrorCode TypeOptionDataIsEmpty = ErrorCode._(450, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'TypeOptionDataIsEmpty');
   static const ErrorCode InvalidDateTimeFormat = ErrorCode._(500, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'InvalidDateTimeFormat');
+  static const ErrorCode UnexpectedEmptyString = ErrorCode._(999, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UnexpectedEmptyString');
   static const ErrorCode InvalidData = ErrorCode._(1000, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'InvalidData');
 
   static const $core.List<ErrorCode> values = <ErrorCode> [
@@ -99,6 +100,7 @@ class ErrorCode extends $pb.ProtobufEnum {
     FieldInvalidOperation,
     TypeOptionDataIsEmpty,
     InvalidDateTimeFormat,
+    UnexpectedEmptyString,
     InvalidData,
   ];
 

+ 2 - 1
frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-error-code/code.pbjson.dart

@@ -55,9 +55,10 @@ const ErrorCode$json = const {
     const {'1': 'FieldInvalidOperation', '2': 444},
     const {'1': 'TypeOptionDataIsEmpty', '2': 450},
     const {'1': 'InvalidDateTimeFormat', '2': 500},
+    const {'1': 'UnexpectedEmptyString', '2': 999},
     const {'1': 'InvalidData', '2': 1000},
   ],
 };
 
 /// Descriptor for `ErrorCode`. Decode as a `google.protobuf.EnumDescriptorProto`.
-final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSDAoISW50ZXJuYWwQABIUChBVc2VyVW5hdXRob3JpemVkEAISEgoOUmVjb3JkTm90Rm91bmQQAxIRCg1Vc2VySWRJc0VtcHR5EAQSGAoUV29ya3NwYWNlTmFtZUludmFsaWQQZBIWChJXb3Jrc3BhY2VJZEludmFsaWQQZRIYChRBcHBDb2xvclN0eWxlSW52YWxpZBBmEhgKFFdvcmtzcGFjZURlc2NUb29Mb25nEGcSGAoUV29ya3NwYWNlTmFtZVRvb0xvbmcQaBIQCgxBcHBJZEludmFsaWQQbhISCg5BcHBOYW1lSW52YWxpZBBvEhMKD1ZpZXdOYW1lSW52YWxpZBB4EhgKFFZpZXdUaHVtYm5haWxJbnZhbGlkEHkSEQoNVmlld0lkSW52YWxpZBB6EhMKD1ZpZXdEZXNjVG9vTG9uZxB7EhMKD1ZpZXdEYXRhSW52YWxpZBB8EhMKD1ZpZXdOYW1lVG9vTG9uZxB9EhEKDENvbm5lY3RFcnJvchDIARIRCgxFbWFpbElzRW1wdHkQrAISFwoSRW1haWxGb3JtYXRJbnZhbGlkEK0CEhcKEkVtYWlsQWxyZWFkeUV4aXN0cxCuAhIUCg9QYXNzd29yZElzRW1wdHkQrwISFAoPUGFzc3dvcmRUb29Mb25nELACEiUKIFBhc3N3b3JkQ29udGFpbnNGb3JiaWRDaGFyYWN0ZXJzELECEhoKFVBhc3N3b3JkRm9ybWF0SW52YWxpZBCyAhIVChBQYXNzd29yZE5vdE1hdGNoELMCEhQKD1VzZXJOYW1lVG9vTG9uZxC0AhInCiJVc2VyTmFtZUNvbnRhaW5Gb3JiaWRkZW5DaGFyYWN0ZXJzELUCEhQKD1VzZXJOYW1lSXNFbXB0eRC2AhISCg1Vc2VySWRJbnZhbGlkELcCEhEKDFVzZXJOb3RFeGlzdBC4AhIQCgtUZXh0VG9vTG9uZxCQAxISCg1HcmlkSWRJc0VtcHR5EJoDEhMKDkJsb2NrSWRJc0VtcHR5EKQDEhEKDFJvd0lkSXNFbXB0eRCuAxIUCg9PcHRpb25JZElzRW1wdHkQrwMSEwoORmllbGRJZElzRW1wdHkQuAMSFgoRRmllbGREb2VzTm90RXhpc3QQuQMSHAoXU2VsZWN0T3B0aW9uTmFtZUlzRW1wdHkQugMSEwoORmllbGROb3RFeGlzdHMQuwMSGgoVRmllbGRJbnZhbGlkT3BlcmF0aW9uELwDEhoKFVR5cGVPcHRpb25EYXRhSXNFbXB0eRDCAxIaChVJbnZhbGlkRGF0ZVRpbWVGb3JtYXQQ9AMSEAoLSW52YWxpZERhdGEQ6Ac=');
+final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSDAoISW50ZXJuYWwQABIUChBVc2VyVW5hdXRob3JpemVkEAISEgoOUmVjb3JkTm90Rm91bmQQAxIRCg1Vc2VySWRJc0VtcHR5EAQSGAoUV29ya3NwYWNlTmFtZUludmFsaWQQZBIWChJXb3Jrc3BhY2VJZEludmFsaWQQZRIYChRBcHBDb2xvclN0eWxlSW52YWxpZBBmEhgKFFdvcmtzcGFjZURlc2NUb29Mb25nEGcSGAoUV29ya3NwYWNlTmFtZVRvb0xvbmcQaBIQCgxBcHBJZEludmFsaWQQbhISCg5BcHBOYW1lSW52YWxpZBBvEhMKD1ZpZXdOYW1lSW52YWxpZBB4EhgKFFZpZXdUaHVtYm5haWxJbnZhbGlkEHkSEQoNVmlld0lkSW52YWxpZBB6EhMKD1ZpZXdEZXNjVG9vTG9uZxB7EhMKD1ZpZXdEYXRhSW52YWxpZBB8EhMKD1ZpZXdOYW1lVG9vTG9uZxB9EhEKDENvbm5lY3RFcnJvchDIARIRCgxFbWFpbElzRW1wdHkQrAISFwoSRW1haWxGb3JtYXRJbnZhbGlkEK0CEhcKEkVtYWlsQWxyZWFkeUV4aXN0cxCuAhIUCg9QYXNzd29yZElzRW1wdHkQrwISFAoPUGFzc3dvcmRUb29Mb25nELACEiUKIFBhc3N3b3JkQ29udGFpbnNGb3JiaWRDaGFyYWN0ZXJzELECEhoKFVBhc3N3b3JkRm9ybWF0SW52YWxpZBCyAhIVChBQYXNzd29yZE5vdE1hdGNoELMCEhQKD1VzZXJOYW1lVG9vTG9uZxC0AhInCiJVc2VyTmFtZUNvbnRhaW5Gb3JiaWRkZW5DaGFyYWN0ZXJzELUCEhQKD1VzZXJOYW1lSXNFbXB0eRC2AhISCg1Vc2VySWRJbnZhbGlkELcCEhEKDFVzZXJOb3RFeGlzdBC4AhIQCgtUZXh0VG9vTG9uZxCQAxISCg1HcmlkSWRJc0VtcHR5EJoDEhMKDkJsb2NrSWRJc0VtcHR5EKQDEhEKDFJvd0lkSXNFbXB0eRCuAxIUCg9PcHRpb25JZElzRW1wdHkQrwMSEwoORmllbGRJZElzRW1wdHkQuAMSFgoRRmllbGREb2VzTm90RXhpc3QQuQMSHAoXU2VsZWN0T3B0aW9uTmFtZUlzRW1wdHkQugMSEwoORmllbGROb3RFeGlzdHMQuwMSGgoVRmllbGRJbnZhbGlkT3BlcmF0aW9uELwDEhoKFVR5cGVPcHRpb25EYXRhSXNFbXB0eRDCAxIaChVJbnZhbGlkRGF0ZVRpbWVGb3JtYXQQ9AMSGgoVVW5leHBlY3RlZEVtcHR5U3RyaW5nEOcHEhAKC0ludmFsaWREYXRhEOgH');

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

@@ -231,17 +231,17 @@ class ViewExtData extends $pb.GeneratedMessage {
 
 class ViewFilter extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ViewFilter', createEmptyInstance: create)
-    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId')
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'objectId')
     ..hasRequiredFields = false
   ;
 
   ViewFilter._() : super();
   factory ViewFilter({
-    $core.String? fieldId,
+    $core.String? objectId,
   }) {
     final _result = create();
-    if (fieldId != null) {
-      _result.fieldId = fieldId;
+    if (objectId != null) {
+      _result.objectId = objectId;
     }
     return _result;
   }
@@ -267,43 +267,43 @@ class ViewFilter extends $pb.GeneratedMessage {
   static ViewFilter? _defaultInstance;
 
   @$pb.TagNumber(1)
-  $core.String get fieldId => $_getSZ(0);
+  $core.String get objectId => $_getSZ(0);
   @$pb.TagNumber(1)
-  set fieldId($core.String v) { $_setString(0, v); }
+  set objectId($core.String v) { $_setString(0, v); }
   @$pb.TagNumber(1)
-  $core.bool hasFieldId() => $_has(0);
+  $core.bool hasObjectId() => $_has(0);
   @$pb.TagNumber(1)
-  void clearFieldId() => clearField(1);
+  void clearObjectId() => clearField(1);
 }
 
-enum ViewGroup_OneOfSubGroupFieldId {
-  subGroupFieldId, 
+enum ViewGroup_OneOfSubGroupObjectId {
+  subGroupObjectId, 
   notSet
 }
 
 class ViewGroup extends $pb.GeneratedMessage {
-  static const $core.Map<$core.int, ViewGroup_OneOfSubGroupFieldId> _ViewGroup_OneOfSubGroupFieldIdByTag = {
-    2 : ViewGroup_OneOfSubGroupFieldId.subGroupFieldId,
-    0 : ViewGroup_OneOfSubGroupFieldId.notSet
+  static const $core.Map<$core.int, ViewGroup_OneOfSubGroupObjectId> _ViewGroup_OneOfSubGroupObjectIdByTag = {
+    2 : ViewGroup_OneOfSubGroupObjectId.subGroupObjectId,
+    0 : ViewGroup_OneOfSubGroupObjectId.notSet
   };
   static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ViewGroup', createEmptyInstance: create)
     ..oo(0, [2])
-    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'groupFieldId')
-    ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'subGroupFieldId')
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'groupObjectId')
+    ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'subGroupObjectId')
     ..hasRequiredFields = false
   ;
 
   ViewGroup._() : super();
   factory ViewGroup({
-    $core.String? groupFieldId,
-    $core.String? subGroupFieldId,
+    $core.String? groupObjectId,
+    $core.String? subGroupObjectId,
   }) {
     final _result = create();
-    if (groupFieldId != null) {
-      _result.groupFieldId = groupFieldId;
+    if (groupObjectId != null) {
+      _result.groupObjectId = groupObjectId;
     }
-    if (subGroupFieldId != null) {
-      _result.subGroupFieldId = subGroupFieldId;
+    if (subGroupObjectId != null) {
+      _result.subGroupObjectId = subGroupObjectId;
     }
     return _result;
   }
@@ -328,41 +328,41 @@ class ViewGroup extends $pb.GeneratedMessage {
   static ViewGroup getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ViewGroup>(create);
   static ViewGroup? _defaultInstance;
 
-  ViewGroup_OneOfSubGroupFieldId whichOneOfSubGroupFieldId() => _ViewGroup_OneOfSubGroupFieldIdByTag[$_whichOneof(0)]!;
-  void clearOneOfSubGroupFieldId() => clearField($_whichOneof(0));
+  ViewGroup_OneOfSubGroupObjectId whichOneOfSubGroupObjectId() => _ViewGroup_OneOfSubGroupObjectIdByTag[$_whichOneof(0)]!;
+  void clearOneOfSubGroupObjectId() => clearField($_whichOneof(0));
 
   @$pb.TagNumber(1)
-  $core.String get groupFieldId => $_getSZ(0);
+  $core.String get groupObjectId => $_getSZ(0);
   @$pb.TagNumber(1)
-  set groupFieldId($core.String v) { $_setString(0, v); }
+  set groupObjectId($core.String v) { $_setString(0, v); }
   @$pb.TagNumber(1)
-  $core.bool hasGroupFieldId() => $_has(0);
+  $core.bool hasGroupObjectId() => $_has(0);
   @$pb.TagNumber(1)
-  void clearGroupFieldId() => clearField(1);
+  void clearGroupObjectId() => clearField(1);
 
   @$pb.TagNumber(2)
-  $core.String get subGroupFieldId => $_getSZ(1);
+  $core.String get subGroupObjectId => $_getSZ(1);
   @$pb.TagNumber(2)
-  set subGroupFieldId($core.String v) { $_setString(1, v); }
+  set subGroupObjectId($core.String v) { $_setString(1, v); }
   @$pb.TagNumber(2)
-  $core.bool hasSubGroupFieldId() => $_has(1);
+  $core.bool hasSubGroupObjectId() => $_has(1);
   @$pb.TagNumber(2)
-  void clearSubGroupFieldId() => clearField(2);
+  void clearSubGroupObjectId() => clearField(2);
 }
 
 class ViewSort extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ViewSort', createEmptyInstance: create)
-    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId')
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'objectId')
     ..hasRequiredFields = false
   ;
 
   ViewSort._() : super();
   factory ViewSort({
-    $core.String? fieldId,
+    $core.String? objectId,
   }) {
     final _result = create();
-    if (fieldId != null) {
-      _result.fieldId = fieldId;
+    if (objectId != null) {
+      _result.objectId = objectId;
     }
     return _result;
   }
@@ -388,12 +388,146 @@ class ViewSort extends $pb.GeneratedMessage {
   static ViewSort? _defaultInstance;
 
   @$pb.TagNumber(1)
-  $core.String get fieldId => $_getSZ(0);
+  $core.String get objectId => $_getSZ(0);
   @$pb.TagNumber(1)
-  set fieldId($core.String v) { $_setString(0, v); }
+  set objectId($core.String v) { $_setString(0, v); }
   @$pb.TagNumber(1)
-  $core.bool hasFieldId() => $_has(0);
+  $core.bool hasObjectId() => $_has(0);
   @$pb.TagNumber(1)
-  void clearFieldId() => clearField(1);
+  void clearObjectId() => clearField(1);
+}
+
+enum UpdateViewInfoPayload_OneOfFilter {
+  filter, 
+  notSet
+}
+
+enum UpdateViewInfoPayload_OneOfGroup {
+  group, 
+  notSet
+}
+
+enum UpdateViewInfoPayload_OneOfSort {
+  sort, 
+  notSet
+}
+
+class UpdateViewInfoPayload extends $pb.GeneratedMessage {
+  static const $core.Map<$core.int, UpdateViewInfoPayload_OneOfFilter> _UpdateViewInfoPayload_OneOfFilterByTag = {
+    2 : UpdateViewInfoPayload_OneOfFilter.filter,
+    0 : UpdateViewInfoPayload_OneOfFilter.notSet
+  };
+  static const $core.Map<$core.int, UpdateViewInfoPayload_OneOfGroup> _UpdateViewInfoPayload_OneOfGroupByTag = {
+    3 : UpdateViewInfoPayload_OneOfGroup.group,
+    0 : UpdateViewInfoPayload_OneOfGroup.notSet
+  };
+  static const $core.Map<$core.int, UpdateViewInfoPayload_OneOfSort> _UpdateViewInfoPayload_OneOfSortByTag = {
+    4 : UpdateViewInfoPayload_OneOfSort.sort,
+    0 : UpdateViewInfoPayload_OneOfSort.notSet
+  };
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'UpdateViewInfoPayload', createEmptyInstance: create)
+    ..oo(0, [2])
+    ..oo(1, [3])
+    ..oo(2, [4])
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'viewId')
+    ..aOM<ViewFilter>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'filter', subBuilder: ViewFilter.create)
+    ..aOM<ViewGroup>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'group', subBuilder: ViewGroup.create)
+    ..aOM<ViewSort>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'sort', subBuilder: ViewSort.create)
+    ..hasRequiredFields = false
+  ;
+
+  UpdateViewInfoPayload._() : super();
+  factory UpdateViewInfoPayload({
+    $core.String? viewId,
+    ViewFilter? filter,
+    ViewGroup? group,
+    ViewSort? sort,
+  }) {
+    final _result = create();
+    if (viewId != null) {
+      _result.viewId = viewId;
+    }
+    if (filter != null) {
+      _result.filter = filter;
+    }
+    if (group != null) {
+      _result.group = group;
+    }
+    if (sort != null) {
+      _result.sort = sort;
+    }
+    return _result;
+  }
+  factory UpdateViewInfoPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory UpdateViewInfoPayload.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  UpdateViewInfoPayload clone() => UpdateViewInfoPayload()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  UpdateViewInfoPayload copyWith(void Function(UpdateViewInfoPayload) updates) => super.copyWith((message) => updates(message as UpdateViewInfoPayload)) as UpdateViewInfoPayload; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static UpdateViewInfoPayload create() => UpdateViewInfoPayload._();
+  UpdateViewInfoPayload createEmptyInstance() => create();
+  static $pb.PbList<UpdateViewInfoPayload> createRepeated() => $pb.PbList<UpdateViewInfoPayload>();
+  @$core.pragma('dart2js:noInline')
+  static UpdateViewInfoPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<UpdateViewInfoPayload>(create);
+  static UpdateViewInfoPayload? _defaultInstance;
+
+  UpdateViewInfoPayload_OneOfFilter whichOneOfFilter() => _UpdateViewInfoPayload_OneOfFilterByTag[$_whichOneof(0)]!;
+  void clearOneOfFilter() => clearField($_whichOneof(0));
+
+  UpdateViewInfoPayload_OneOfGroup whichOneOfGroup() => _UpdateViewInfoPayload_OneOfGroupByTag[$_whichOneof(1)]!;
+  void clearOneOfGroup() => clearField($_whichOneof(1));
+
+  UpdateViewInfoPayload_OneOfSort whichOneOfSort() => _UpdateViewInfoPayload_OneOfSortByTag[$_whichOneof(2)]!;
+  void clearOneOfSort() => clearField($_whichOneof(2));
+
+  @$pb.TagNumber(1)
+  $core.String get viewId => $_getSZ(0);
+  @$pb.TagNumber(1)
+  set viewId($core.String v) { $_setString(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasViewId() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearViewId() => clearField(1);
+
+  @$pb.TagNumber(2)
+  ViewFilter get filter => $_getN(1);
+  @$pb.TagNumber(2)
+  set filter(ViewFilter v) { setField(2, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasFilter() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearFilter() => clearField(2);
+  @$pb.TagNumber(2)
+  ViewFilter ensureFilter() => $_ensure(1);
+
+  @$pb.TagNumber(3)
+  ViewGroup get group => $_getN(2);
+  @$pb.TagNumber(3)
+  set group(ViewGroup v) { setField(3, v); }
+  @$pb.TagNumber(3)
+  $core.bool hasGroup() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearGroup() => clearField(3);
+  @$pb.TagNumber(3)
+  ViewGroup ensureGroup() => $_ensure(2);
+
+  @$pb.TagNumber(4)
+  ViewSort get sort => $_getN(3);
+  @$pb.TagNumber(4)
+  set sort(ViewSort v) { setField(4, v); }
+  @$pb.TagNumber(4)
+  $core.bool hasSort() => $_has(3);
+  @$pb.TagNumber(4)
+  void clearSort() => clearField(4);
+  @$pb.TagNumber(4)
+  ViewSort ensureSort() => $_ensure(3);
 }
 

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

@@ -40,33 +40,51 @@ final $typed_data.Uint8List viewExtDataDescriptor = $convert.base64Decode('CgtWa
 const ViewFilter$json = const {
   '1': 'ViewFilter',
   '2': const [
-    const {'1': 'field_id', '3': 1, '4': 1, '5': 9, '10': 'fieldId'},
+    const {'1': 'object_id', '3': 1, '4': 1, '5': 9, '10': 'objectId'},
   ],
 };
 
 /// Descriptor for `ViewFilter`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List viewFilterDescriptor = $convert.base64Decode('CgpWaWV3RmlsdGVyEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElk');
+final $typed_data.Uint8List viewFilterDescriptor = $convert.base64Decode('CgpWaWV3RmlsdGVyEhsKCW9iamVjdF9pZBgBIAEoCVIIb2JqZWN0SWQ=');
 @$core.Deprecated('Use viewGroupDescriptor instead')
 const ViewGroup$json = const {
   '1': 'ViewGroup',
   '2': const [
-    const {'1': 'group_field_id', '3': 1, '4': 1, '5': 9, '10': 'groupFieldId'},
-    const {'1': 'sub_group_field_id', '3': 2, '4': 1, '5': 9, '9': 0, '10': 'subGroupFieldId'},
+    const {'1': 'group_object_id', '3': 1, '4': 1, '5': 9, '10': 'groupObjectId'},
+    const {'1': 'sub_group_object_id', '3': 2, '4': 1, '5': 9, '9': 0, '10': 'subGroupObjectId'},
   ],
   '8': const [
-    const {'1': 'one_of_sub_group_field_id'},
+    const {'1': 'one_of_sub_group_object_id'},
   ],
 };
 
 /// Descriptor for `ViewGroup`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List viewGroupDescriptor = $convert.base64Decode('CglWaWV3R3JvdXASJAoOZ3JvdXBfZmllbGRfaWQYASABKAlSDGdyb3VwRmllbGRJZBItChJzdWJfZ3JvdXBfZmllbGRfaWQYAiABKAlIAFIPc3ViR3JvdXBGaWVsZElkQhsKGW9uZV9vZl9zdWJfZ3JvdXBfZmllbGRfaWQ=');
+final $typed_data.Uint8List viewGroupDescriptor = $convert.base64Decode('CglWaWV3R3JvdXASJgoPZ3JvdXBfb2JqZWN0X2lkGAEgASgJUg1ncm91cE9iamVjdElkEi8KE3N1Yl9ncm91cF9vYmplY3RfaWQYAiABKAlIAFIQc3ViR3JvdXBPYmplY3RJZEIcChpvbmVfb2Zfc3ViX2dyb3VwX29iamVjdF9pZA==');
 @$core.Deprecated('Use viewSortDescriptor instead')
 const ViewSort$json = const {
   '1': 'ViewSort',
   '2': const [
-    const {'1': 'field_id', '3': 1, '4': 1, '5': 9, '10': 'fieldId'},
+    const {'1': 'object_id', '3': 1, '4': 1, '5': 9, '10': 'objectId'},
   ],
 };
 
 /// Descriptor for `ViewSort`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List viewSortDescriptor = $convert.base64Decode('CghWaWV3U29ydBIZCghmaWVsZF9pZBgBIAEoCVIHZmllbGRJZA==');
+final $typed_data.Uint8List viewSortDescriptor = $convert.base64Decode('CghWaWV3U29ydBIbCglvYmplY3RfaWQYASABKAlSCG9iamVjdElk');
+@$core.Deprecated('Use updateViewInfoPayloadDescriptor instead')
+const UpdateViewInfoPayload$json = const {
+  '1': 'UpdateViewInfoPayload',
+  '2': const [
+    const {'1': 'view_id', '3': 1, '4': 1, '5': 9, '10': 'viewId'},
+    const {'1': 'filter', '3': 2, '4': 1, '5': 11, '6': '.ViewFilter', '9': 0, '10': 'filter'},
+    const {'1': 'group', '3': 3, '4': 1, '5': 11, '6': '.ViewGroup', '9': 1, '10': 'group'},
+    const {'1': 'sort', '3': 4, '4': 1, '5': 11, '6': '.ViewSort', '9': 2, '10': 'sort'},
+  ],
+  '8': const [
+    const {'1': 'one_of_filter'},
+    const {'1': 'one_of_group'},
+    const {'1': 'one_of_sort'},
+  ],
+};
+
+/// Descriptor for `UpdateViewInfoPayload`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List updateViewInfoPayloadDescriptor = $convert.base64Decode('ChVVcGRhdGVWaWV3SW5mb1BheWxvYWQSFwoHdmlld19pZBgBIAEoCVIGdmlld0lkEiUKBmZpbHRlchgCIAEoCzILLlZpZXdGaWx0ZXJIAFIGZmlsdGVyEiIKBWdyb3VwGAMgASgLMgouVmlld0dyb3VwSAFSBWdyb3VwEh8KBHNvcnQYBCABKAsyCS5WaWV3U29ydEgCUgRzb3J0Qg8KDW9uZV9vZl9maWx0ZXJCDgoMb25lX29mX2dyb3VwQg0KC29uZV9vZl9zb3J0');

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

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

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

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

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

@@ -0,0 +1,1246 @@
+///
+//  Generated code. Do not modify.
+//  source: field.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 'field.pbenum.dart';
+
+export 'field.pbenum.dart';
+
+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)
+    ..aOB(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'isPrimary')
+    ..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,
+    $core.bool? isPrimary,
+  }) {
+    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 (isPrimary != null) {
+      _result.isPrimary = isPrimary;
+    }
+    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)
+  $core.bool get isPrimary => $_getBF(7);
+  @$pb.TagNumber(8)
+  set isPrimary($core.bool v) { $_setBool(7, v); }
+  @$pb.TagNumber(8)
+  $core.bool hasIsPrimary() => $_has(7);
+  @$pb.TagNumber(8)
+  void clearIsPrimary() => clearField(8);
+}
+
+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')
+    ..hasRequiredFields = false
+  ;
+
+  FieldOrder._() : super();
+  factory FieldOrder({
+    $core.String? fieldId,
+  }) {
+    final _result = create();
+    if (fieldId != null) {
+      _result.fieldId = fieldId;
+    }
+    return _result;
+  }
+  factory FieldOrder.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory FieldOrder.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')
+  FieldOrder clone() => FieldOrder()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  FieldOrder copyWith(void Function(FieldOrder) updates) => super.copyWith((message) => updates(message as FieldOrder)) as FieldOrder; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static FieldOrder create() => FieldOrder._();
+  FieldOrder createEmptyInstance() => create();
+  static $pb.PbList<FieldOrder> createRepeated() => $pb.PbList<FieldOrder>();
+  @$core.pragma('dart2js:noInline')
+  static FieldOrder getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<FieldOrder>(create);
+  static FieldOrder? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.String get fieldId => $_getSZ(0);
+  @$pb.TagNumber(1)
+  set fieldId($core.String v) { $_setString(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasFieldId() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearFieldId() => clearField(1);
+}
+
+class GridFieldChangeset extends $pb.GeneratedMessage {
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridFieldChangeset', createEmptyInstance: create)
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId')
+    ..pc<IndexField>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'insertedFields', $pb.PbFieldType.PM, subBuilder: IndexField.create)
+    ..pc<FieldOrder>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'deletedFields', $pb.PbFieldType.PM, subBuilder: FieldOrder.create)
+    ..pc<Field>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'updatedFields', $pb.PbFieldType.PM, subBuilder: Field.create)
+    ..hasRequiredFields = false
+  ;
+
+  GridFieldChangeset._() : super();
+  factory GridFieldChangeset({
+    $core.String? gridId,
+    $core.Iterable<IndexField>? insertedFields,
+    $core.Iterable<FieldOrder>? deletedFields,
+    $core.Iterable<Field>? updatedFields,
+  }) {
+    final _result = create();
+    if (gridId != null) {
+      _result.gridId = gridId;
+    }
+    if (insertedFields != null) {
+      _result.insertedFields.addAll(insertedFields);
+    }
+    if (deletedFields != null) {
+      _result.deletedFields.addAll(deletedFields);
+    }
+    if (updatedFields != null) {
+      _result.updatedFields.addAll(updatedFields);
+    }
+    return _result;
+  }
+  factory GridFieldChangeset.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory GridFieldChangeset.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')
+  GridFieldChangeset clone() => GridFieldChangeset()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  GridFieldChangeset copyWith(void Function(GridFieldChangeset) updates) => super.copyWith((message) => updates(message as GridFieldChangeset)) as GridFieldChangeset; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static GridFieldChangeset create() => GridFieldChangeset._();
+  GridFieldChangeset createEmptyInstance() => create();
+  static $pb.PbList<GridFieldChangeset> createRepeated() => $pb.PbList<GridFieldChangeset>();
+  @$core.pragma('dart2js:noInline')
+  static GridFieldChangeset getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<GridFieldChangeset>(create);
+  static GridFieldChangeset? _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<IndexField> get insertedFields => $_getList(1);
+
+  @$pb.TagNumber(3)
+  $core.List<FieldOrder> get deletedFields => $_getList(2);
+
+  @$pb.TagNumber(4)
+  $core.List<Field> get updatedFields => $_getList(3);
+}
+
+class IndexField extends $pb.GeneratedMessage {
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'IndexField', createEmptyInstance: create)
+    ..aOM<Field>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'field', subBuilder: Field.create)
+    ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'index', $pb.PbFieldType.O3)
+    ..hasRequiredFields = false
+  ;
+
+  IndexField._() : super();
+  factory IndexField({
+    Field? field_1,
+    $core.int? index,
+  }) {
+    final _result = create();
+    if (field_1 != null) {
+      _result.field_1 = field_1;
+    }
+    if (index != null) {
+      _result.index = index;
+    }
+    return _result;
+  }
+  factory IndexField.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory IndexField.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')
+  IndexField clone() => IndexField()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  IndexField copyWith(void Function(IndexField) updates) => super.copyWith((message) => updates(message as IndexField)) as IndexField; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static IndexField create() => IndexField._();
+  IndexField createEmptyInstance() => create();
+  static $pb.PbList<IndexField> createRepeated() => $pb.PbList<IndexField>();
+  @$core.pragma('dart2js:noInline')
+  static IndexField getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<IndexField>(create);
+  static IndexField? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  Field get field_1 => $_getN(0);
+  @$pb.TagNumber(1)
+  set field_1(Field v) { setField(1, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasField_1() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearField_1() => clearField(1);
+  @$pb.TagNumber(1)
+  Field ensureField_1() => $_ensure(0);
+
+  @$pb.TagNumber(2)
+  $core.int get index => $_getIZ(1);
+  @$pb.TagNumber(2)
+  set index($core.int v) { $_setSignedInt32(1, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasIndex() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearIndex() => clearField(2);
+}
+
+enum GetEditFieldContextPayload_OneOfFieldId {
+  fieldId, 
+  notSet
+}
+
+class GetEditFieldContextPayload extends $pb.GeneratedMessage {
+  static const $core.Map<$core.int, GetEditFieldContextPayload_OneOfFieldId> _GetEditFieldContextPayload_OneOfFieldIdByTag = {
+    2 : GetEditFieldContextPayload_OneOfFieldId.fieldId,
+    0 : GetEditFieldContextPayload_OneOfFieldId.notSet
+  };
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GetEditFieldContextPayload', createEmptyInstance: create)
+    ..oo(0, [2])
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId')
+    ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId')
+    ..e<FieldType>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldType', $pb.PbFieldType.OE, defaultOrMaker: FieldType.RichText, valueOf: FieldType.valueOf, enumValues: FieldType.values)
+    ..hasRequiredFields = false
+  ;
+
+  GetEditFieldContextPayload._() : super();
+  factory GetEditFieldContextPayload({
+    $core.String? gridId,
+    $core.String? fieldId,
+    FieldType? fieldType,
+  }) {
+    final _result = create();
+    if (gridId != null) {
+      _result.gridId = gridId;
+    }
+    if (fieldId != null) {
+      _result.fieldId = fieldId;
+    }
+    if (fieldType != null) {
+      _result.fieldType = fieldType;
+    }
+    return _result;
+  }
+  factory GetEditFieldContextPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory GetEditFieldContextPayload.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')
+  GetEditFieldContextPayload clone() => GetEditFieldContextPayload()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  GetEditFieldContextPayload copyWith(void Function(GetEditFieldContextPayload) updates) => super.copyWith((message) => updates(message as GetEditFieldContextPayload)) as GetEditFieldContextPayload; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static GetEditFieldContextPayload create() => GetEditFieldContextPayload._();
+  GetEditFieldContextPayload createEmptyInstance() => create();
+  static $pb.PbList<GetEditFieldContextPayload> createRepeated() => $pb.PbList<GetEditFieldContextPayload>();
+  @$core.pragma('dart2js:noInline')
+  static GetEditFieldContextPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<GetEditFieldContextPayload>(create);
+  static GetEditFieldContextPayload? _defaultInstance;
+
+  GetEditFieldContextPayload_OneOfFieldId whichOneOfFieldId() => _GetEditFieldContextPayload_OneOfFieldIdByTag[$_whichOneof(0)]!;
+  void clearOneOfFieldId() => clearField($_whichOneof(0));
+
+  @$pb.TagNumber(1)
+  $core.String get gridId => $_getSZ(0);
+  @$pb.TagNumber(1)
+  set gridId($core.String v) { $_setString(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasGridId() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearGridId() => clearField(1);
+
+  @$pb.TagNumber(2)
+  $core.String get fieldId => $_getSZ(1);
+  @$pb.TagNumber(2)
+  set fieldId($core.String v) { $_setString(1, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasFieldId() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearFieldId() => clearField(2);
+
+  @$pb.TagNumber(3)
+  FieldType get fieldType => $_getN(2);
+  @$pb.TagNumber(3)
+  set fieldType(FieldType v) { setField(3, v); }
+  @$pb.TagNumber(3)
+  $core.bool hasFieldType() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearFieldType() => clearField(3);
+}
+
+class EditFieldPayload extends $pb.GeneratedMessage {
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'EditFieldPayload', createEmptyInstance: create)
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId')
+    ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId')
+    ..e<FieldType>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldType', $pb.PbFieldType.OE, defaultOrMaker: FieldType.RichText, valueOf: FieldType.valueOf, enumValues: FieldType.values)
+    ..aOB(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'createIfNotExist')
+    ..hasRequiredFields = false
+  ;
+
+  EditFieldPayload._() : super();
+  factory EditFieldPayload({
+    $core.String? gridId,
+    $core.String? fieldId,
+    FieldType? fieldType,
+    $core.bool? createIfNotExist,
+  }) {
+    final _result = create();
+    if (gridId != null) {
+      _result.gridId = gridId;
+    }
+    if (fieldId != null) {
+      _result.fieldId = fieldId;
+    }
+    if (fieldType != null) {
+      _result.fieldType = fieldType;
+    }
+    if (createIfNotExist != null) {
+      _result.createIfNotExist = createIfNotExist;
+    }
+    return _result;
+  }
+  factory EditFieldPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory EditFieldPayload.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')
+  EditFieldPayload clone() => EditFieldPayload()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  EditFieldPayload copyWith(void Function(EditFieldPayload) updates) => super.copyWith((message) => updates(message as EditFieldPayload)) as EditFieldPayload; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static EditFieldPayload create() => EditFieldPayload._();
+  EditFieldPayload createEmptyInstance() => create();
+  static $pb.PbList<EditFieldPayload> createRepeated() => $pb.PbList<EditFieldPayload>();
+  @$core.pragma('dart2js:noInline')
+  static EditFieldPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<EditFieldPayload>(create);
+  static EditFieldPayload? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.String get gridId => $_getSZ(0);
+  @$pb.TagNumber(1)
+  set gridId($core.String v) { $_setString(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasGridId() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearGridId() => clearField(1);
+
+  @$pb.TagNumber(2)
+  $core.String get fieldId => $_getSZ(1);
+  @$pb.TagNumber(2)
+  set fieldId($core.String v) { $_setString(1, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasFieldId() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearFieldId() => clearField(2);
+
+  @$pb.TagNumber(3)
+  FieldType get fieldType => $_getN(2);
+  @$pb.TagNumber(3)
+  set fieldType(FieldType v) { setField(3, v); }
+  @$pb.TagNumber(3)
+  $core.bool hasFieldType() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearFieldType() => clearField(3);
+
+  @$pb.TagNumber(4)
+  $core.bool get createIfNotExist => $_getBF(3);
+  @$pb.TagNumber(4)
+  set createIfNotExist($core.bool v) { $_setBool(3, v); }
+  @$pb.TagNumber(4)
+  $core.bool hasCreateIfNotExist() => $_has(3);
+  @$pb.TagNumber(4)
+  void clearCreateIfNotExist() => clearField(4);
+}
+
+class FieldTypeOptionContext extends $pb.GeneratedMessage {
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FieldTypeOptionContext', createEmptyInstance: create)
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId')
+    ..aOM<Field>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridField', subBuilder: Field.create)
+    ..a<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptionData', $pb.PbFieldType.OY)
+    ..hasRequiredFields = false
+  ;
+
+  FieldTypeOptionContext._() : super();
+  factory FieldTypeOptionContext({
+    $core.String? gridId,
+    Field? gridField,
+    $core.List<$core.int>? typeOptionData,
+  }) {
+    final _result = create();
+    if (gridId != null) {
+      _result.gridId = gridId;
+    }
+    if (gridField != null) {
+      _result.gridField = gridField;
+    }
+    if (typeOptionData != null) {
+      _result.typeOptionData = typeOptionData;
+    }
+    return _result;
+  }
+  factory FieldTypeOptionContext.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory FieldTypeOptionContext.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')
+  FieldTypeOptionContext clone() => FieldTypeOptionContext()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  FieldTypeOptionContext copyWith(void Function(FieldTypeOptionContext) updates) => super.copyWith((message) => updates(message as FieldTypeOptionContext)) as FieldTypeOptionContext; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static FieldTypeOptionContext create() => FieldTypeOptionContext._();
+  FieldTypeOptionContext createEmptyInstance() => create();
+  static $pb.PbList<FieldTypeOptionContext> createRepeated() => $pb.PbList<FieldTypeOptionContext>();
+  @$core.pragma('dart2js:noInline')
+  static FieldTypeOptionContext getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<FieldTypeOptionContext>(create);
+  static FieldTypeOptionContext? _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)
+  Field get gridField => $_getN(1);
+  @$pb.TagNumber(2)
+  set gridField(Field v) { setField(2, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasGridField() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearGridField() => clearField(2);
+  @$pb.TagNumber(2)
+  Field ensureGridField() => $_ensure(1);
+
+  @$pb.TagNumber(3)
+  $core.List<$core.int> get typeOptionData => $_getN(2);
+  @$pb.TagNumber(3)
+  set typeOptionData($core.List<$core.int> v) { $_setBytes(2, v); }
+  @$pb.TagNumber(3)
+  $core.bool hasTypeOptionData() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearTypeOptionData() => clearField(3);
+}
+
+class FieldTypeOptionData extends $pb.GeneratedMessage {
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FieldTypeOptionData', createEmptyInstance: create)
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId')
+    ..aOM<Field>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'field', subBuilder: Field.create)
+    ..a<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptionData', $pb.PbFieldType.OY)
+    ..hasRequiredFields = false
+  ;
+
+  FieldTypeOptionData._() : super();
+  factory FieldTypeOptionData({
+    $core.String? gridId,
+    Field? field_2,
+    $core.List<$core.int>? typeOptionData,
+  }) {
+    final _result = create();
+    if (gridId != null) {
+      _result.gridId = gridId;
+    }
+    if (field_2 != null) {
+      _result.field_2 = field_2;
+    }
+    if (typeOptionData != null) {
+      _result.typeOptionData = typeOptionData;
+    }
+    return _result;
+  }
+  factory FieldTypeOptionData.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory FieldTypeOptionData.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')
+  FieldTypeOptionData clone() => FieldTypeOptionData()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  FieldTypeOptionData copyWith(void Function(FieldTypeOptionData) updates) => super.copyWith((message) => updates(message as FieldTypeOptionData)) as FieldTypeOptionData; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static FieldTypeOptionData create() => FieldTypeOptionData._();
+  FieldTypeOptionData createEmptyInstance() => create();
+  static $pb.PbList<FieldTypeOptionData> createRepeated() => $pb.PbList<FieldTypeOptionData>();
+  @$core.pragma('dart2js:noInline')
+  static FieldTypeOptionData getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<FieldTypeOptionData>(create);
+  static FieldTypeOptionData? _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)
+  Field get field_2 => $_getN(1);
+  @$pb.TagNumber(2)
+  set field_2(Field v) { setField(2, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasField_2() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearField_2() => clearField(2);
+  @$pb.TagNumber(2)
+  Field ensureField_2() => $_ensure(1);
+
+  @$pb.TagNumber(3)
+  $core.List<$core.int> get typeOptionData => $_getN(2);
+  @$pb.TagNumber(3)
+  set typeOptionData($core.List<$core.int> v) { $_setBytes(2, v); }
+  @$pb.TagNumber(3)
+  $core.bool hasTypeOptionData() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearTypeOptionData() => clearField(3);
+}
+
+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 RepeatedFieldOrder extends $pb.GeneratedMessage {
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedFieldOrder', createEmptyInstance: create)
+    ..pc<FieldOrder>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: FieldOrder.create)
+    ..hasRequiredFields = false
+  ;
+
+  RepeatedFieldOrder._() : super();
+  factory RepeatedFieldOrder({
+    $core.Iterable<FieldOrder>? items,
+  }) {
+    final _result = create();
+    if (items != null) {
+      _result.items.addAll(items);
+    }
+    return _result;
+  }
+  factory RepeatedFieldOrder.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory RepeatedFieldOrder.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')
+  RepeatedFieldOrder clone() => RepeatedFieldOrder()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  RepeatedFieldOrder copyWith(void Function(RepeatedFieldOrder) updates) => super.copyWith((message) => updates(message as RepeatedFieldOrder)) as RepeatedFieldOrder; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static RepeatedFieldOrder create() => RepeatedFieldOrder._();
+  RepeatedFieldOrder createEmptyInstance() => create();
+  static $pb.PbList<RepeatedFieldOrder> createRepeated() => $pb.PbList<RepeatedFieldOrder>();
+  @$core.pragma('dart2js:noInline')
+  static RepeatedFieldOrder getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<RepeatedFieldOrder>(create);
+  static RepeatedFieldOrder? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.List<FieldOrder> get items => $_getList(0);
+}
+
+enum InsertFieldPayload_OneOfStartFieldId {
+  startFieldId, 
+  notSet
+}
+
+class InsertFieldPayload extends $pb.GeneratedMessage {
+  static const $core.Map<$core.int, InsertFieldPayload_OneOfStartFieldId> _InsertFieldPayload_OneOfStartFieldIdByTag = {
+    4 : InsertFieldPayload_OneOfStartFieldId.startFieldId,
+    0 : InsertFieldPayload_OneOfStartFieldId.notSet
+  };
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'InsertFieldPayload', createEmptyInstance: create)
+    ..oo(0, [4])
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId')
+    ..aOM<Field>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'field', subBuilder: Field.create)
+    ..a<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptionData', $pb.PbFieldType.OY)
+    ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'startFieldId')
+    ..hasRequiredFields = false
+  ;
+
+  InsertFieldPayload._() : super();
+  factory InsertFieldPayload({
+    $core.String? gridId,
+    Field? field_2,
+    $core.List<$core.int>? typeOptionData,
+    $core.String? startFieldId,
+  }) {
+    final _result = create();
+    if (gridId != null) {
+      _result.gridId = gridId;
+    }
+    if (field_2 != null) {
+      _result.field_2 = field_2;
+    }
+    if (typeOptionData != null) {
+      _result.typeOptionData = typeOptionData;
+    }
+    if (startFieldId != null) {
+      _result.startFieldId = startFieldId;
+    }
+    return _result;
+  }
+  factory InsertFieldPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory InsertFieldPayload.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')
+  InsertFieldPayload clone() => InsertFieldPayload()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  InsertFieldPayload copyWith(void Function(InsertFieldPayload) updates) => super.copyWith((message) => updates(message as InsertFieldPayload)) as InsertFieldPayload; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static InsertFieldPayload create() => InsertFieldPayload._();
+  InsertFieldPayload createEmptyInstance() => create();
+  static $pb.PbList<InsertFieldPayload> createRepeated() => $pb.PbList<InsertFieldPayload>();
+  @$core.pragma('dart2js:noInline')
+  static InsertFieldPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<InsertFieldPayload>(create);
+  static InsertFieldPayload? _defaultInstance;
+
+  InsertFieldPayload_OneOfStartFieldId whichOneOfStartFieldId() => _InsertFieldPayload_OneOfStartFieldIdByTag[$_whichOneof(0)]!;
+  void clearOneOfStartFieldId() => clearField($_whichOneof(0));
+
+  @$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)
+  Field get field_2 => $_getN(1);
+  @$pb.TagNumber(2)
+  set field_2(Field v) { setField(2, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasField_2() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearField_2() => clearField(2);
+  @$pb.TagNumber(2)
+  Field ensureField_2() => $_ensure(1);
+
+  @$pb.TagNumber(3)
+  $core.List<$core.int> get typeOptionData => $_getN(2);
+  @$pb.TagNumber(3)
+  set typeOptionData($core.List<$core.int> v) { $_setBytes(2, v); }
+  @$pb.TagNumber(3)
+  $core.bool hasTypeOptionData() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearTypeOptionData() => clearField(3);
+
+  @$pb.TagNumber(4)
+  $core.String get startFieldId => $_getSZ(3);
+  @$pb.TagNumber(4)
+  set startFieldId($core.String v) { $_setString(3, v); }
+  @$pb.TagNumber(4)
+  $core.bool hasStartFieldId() => $_has(3);
+  @$pb.TagNumber(4)
+  void clearStartFieldId() => clearField(4);
+}
+
+class UpdateFieldTypeOptionPayload extends $pb.GeneratedMessage {
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'UpdateFieldTypeOptionPayload', createEmptyInstance: create)
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId')
+    ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId')
+    ..a<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptionData', $pb.PbFieldType.OY)
+    ..hasRequiredFields = false
+  ;
+
+  UpdateFieldTypeOptionPayload._() : super();
+  factory UpdateFieldTypeOptionPayload({
+    $core.String? gridId,
+    $core.String? fieldId,
+    $core.List<$core.int>? typeOptionData,
+  }) {
+    final _result = create();
+    if (gridId != null) {
+      _result.gridId = gridId;
+    }
+    if (fieldId != null) {
+      _result.fieldId = fieldId;
+    }
+    if (typeOptionData != null) {
+      _result.typeOptionData = typeOptionData;
+    }
+    return _result;
+  }
+  factory UpdateFieldTypeOptionPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory UpdateFieldTypeOptionPayload.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')
+  UpdateFieldTypeOptionPayload clone() => UpdateFieldTypeOptionPayload()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  UpdateFieldTypeOptionPayload copyWith(void Function(UpdateFieldTypeOptionPayload) updates) => super.copyWith((message) => updates(message as UpdateFieldTypeOptionPayload)) as UpdateFieldTypeOptionPayload; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static UpdateFieldTypeOptionPayload create() => UpdateFieldTypeOptionPayload._();
+  UpdateFieldTypeOptionPayload createEmptyInstance() => create();
+  static $pb.PbList<UpdateFieldTypeOptionPayload> createRepeated() => $pb.PbList<UpdateFieldTypeOptionPayload>();
+  @$core.pragma('dart2js:noInline')
+  static UpdateFieldTypeOptionPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<UpdateFieldTypeOptionPayload>(create);
+  static UpdateFieldTypeOptionPayload? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.String get gridId => $_getSZ(0);
+  @$pb.TagNumber(1)
+  set gridId($core.String v) { $_setString(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasGridId() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearGridId() => clearField(1);
+
+  @$pb.TagNumber(2)
+  $core.String get fieldId => $_getSZ(1);
+  @$pb.TagNumber(2)
+  set fieldId($core.String v) { $_setString(1, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasFieldId() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearFieldId() => clearField(2);
+
+  @$pb.TagNumber(3)
+  $core.List<$core.int> get typeOptionData => $_getN(2);
+  @$pb.TagNumber(3)
+  set typeOptionData($core.List<$core.int> v) { $_setBytes(2, v); }
+  @$pb.TagNumber(3)
+  $core.bool hasTypeOptionData() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearTypeOptionData() => clearField(3);
+}
+
+class QueryFieldPayload extends $pb.GeneratedMessage {
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'QueryFieldPayload', createEmptyInstance: create)
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId')
+    ..aOM<RepeatedFieldOrder>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldOrders', subBuilder: RepeatedFieldOrder.create)
+    ..hasRequiredFields = false
+  ;
+
+  QueryFieldPayload._() : super();
+  factory QueryFieldPayload({
+    $core.String? gridId,
+    RepeatedFieldOrder? fieldOrders,
+  }) {
+    final _result = create();
+    if (gridId != null) {
+      _result.gridId = gridId;
+    }
+    if (fieldOrders != null) {
+      _result.fieldOrders = fieldOrders;
+    }
+    return _result;
+  }
+  factory QueryFieldPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory QueryFieldPayload.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')
+  QueryFieldPayload clone() => QueryFieldPayload()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  QueryFieldPayload copyWith(void Function(QueryFieldPayload) updates) => super.copyWith((message) => updates(message as QueryFieldPayload)) as QueryFieldPayload; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static QueryFieldPayload create() => QueryFieldPayload._();
+  QueryFieldPayload createEmptyInstance() => create();
+  static $pb.PbList<QueryFieldPayload> createRepeated() => $pb.PbList<QueryFieldPayload>();
+  @$core.pragma('dart2js:noInline')
+  static QueryFieldPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<QueryFieldPayload>(create);
+  static QueryFieldPayload? _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)
+  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);
+}
+
+enum FieldChangesetPayload_OneOfName {
+  name, 
+  notSet
+}
+
+enum FieldChangesetPayload_OneOfDesc {
+  desc, 
+  notSet
+}
+
+enum FieldChangesetPayload_OneOfFieldType {
+  fieldType, 
+  notSet
+}
+
+enum FieldChangesetPayload_OneOfFrozen {
+  frozen, 
+  notSet
+}
+
+enum FieldChangesetPayload_OneOfVisibility {
+  visibility, 
+  notSet
+}
+
+enum FieldChangesetPayload_OneOfWidth {
+  width, 
+  notSet
+}
+
+enum FieldChangesetPayload_OneOfTypeOptionData {
+  typeOptionData, 
+  notSet
+}
+
+class FieldChangesetPayload extends $pb.GeneratedMessage {
+  static const $core.Map<$core.int, FieldChangesetPayload_OneOfName> _FieldChangesetPayload_OneOfNameByTag = {
+    3 : FieldChangesetPayload_OneOfName.name,
+    0 : FieldChangesetPayload_OneOfName.notSet
+  };
+  static const $core.Map<$core.int, FieldChangesetPayload_OneOfDesc> _FieldChangesetPayload_OneOfDescByTag = {
+    4 : FieldChangesetPayload_OneOfDesc.desc,
+    0 : FieldChangesetPayload_OneOfDesc.notSet
+  };
+  static const $core.Map<$core.int, FieldChangesetPayload_OneOfFieldType> _FieldChangesetPayload_OneOfFieldTypeByTag = {
+    5 : FieldChangesetPayload_OneOfFieldType.fieldType,
+    0 : FieldChangesetPayload_OneOfFieldType.notSet
+  };
+  static const $core.Map<$core.int, FieldChangesetPayload_OneOfFrozen> _FieldChangesetPayload_OneOfFrozenByTag = {
+    6 : FieldChangesetPayload_OneOfFrozen.frozen,
+    0 : FieldChangesetPayload_OneOfFrozen.notSet
+  };
+  static const $core.Map<$core.int, FieldChangesetPayload_OneOfVisibility> _FieldChangesetPayload_OneOfVisibilityByTag = {
+    7 : FieldChangesetPayload_OneOfVisibility.visibility,
+    0 : FieldChangesetPayload_OneOfVisibility.notSet
+  };
+  static const $core.Map<$core.int, FieldChangesetPayload_OneOfWidth> _FieldChangesetPayload_OneOfWidthByTag = {
+    8 : FieldChangesetPayload_OneOfWidth.width,
+    0 : FieldChangesetPayload_OneOfWidth.notSet
+  };
+  static const $core.Map<$core.int, FieldChangesetPayload_OneOfTypeOptionData> _FieldChangesetPayload_OneOfTypeOptionDataByTag = {
+    9 : FieldChangesetPayload_OneOfTypeOptionData.typeOptionData,
+    0 : FieldChangesetPayload_OneOfTypeOptionData.notSet
+  };
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FieldChangesetPayload', createEmptyInstance: create)
+    ..oo(0, [3])
+    ..oo(1, [4])
+    ..oo(2, [5])
+    ..oo(3, [6])
+    ..oo(4, [7])
+    ..oo(5, [8])
+    ..oo(6, [9])
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId')
+    ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId')
+    ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name')
+    ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc')
+    ..e<FieldType>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldType', $pb.PbFieldType.OE, defaultOrMaker: FieldType.RichText, valueOf: FieldType.valueOf, enumValues: FieldType.values)
+    ..aOB(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'frozen')
+    ..aOB(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility')
+    ..a<$core.int>(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'width', $pb.PbFieldType.O3)
+    ..a<$core.List<$core.int>>(9, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptionData', $pb.PbFieldType.OY)
+    ..hasRequiredFields = false
+  ;
+
+  FieldChangesetPayload._() : super();
+  factory FieldChangesetPayload({
+    $core.String? fieldId,
+    $core.String? gridId,
+    $core.String? name,
+    $core.String? desc,
+    FieldType? fieldType,
+    $core.bool? frozen,
+    $core.bool? visibility,
+    $core.int? width,
+    $core.List<$core.int>? typeOptionData,
+  }) {
+    final _result = create();
+    if (fieldId != null) {
+      _result.fieldId = fieldId;
+    }
+    if (gridId != null) {
+      _result.gridId = gridId;
+    }
+    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 (typeOptionData != null) {
+      _result.typeOptionData = typeOptionData;
+    }
+    return _result;
+  }
+  factory FieldChangesetPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory FieldChangesetPayload.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')
+  FieldChangesetPayload clone() => FieldChangesetPayload()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  FieldChangesetPayload copyWith(void Function(FieldChangesetPayload) updates) => super.copyWith((message) => updates(message as FieldChangesetPayload)) as FieldChangesetPayload; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static FieldChangesetPayload create() => FieldChangesetPayload._();
+  FieldChangesetPayload createEmptyInstance() => create();
+  static $pb.PbList<FieldChangesetPayload> createRepeated() => $pb.PbList<FieldChangesetPayload>();
+  @$core.pragma('dart2js:noInline')
+  static FieldChangesetPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<FieldChangesetPayload>(create);
+  static FieldChangesetPayload? _defaultInstance;
+
+  FieldChangesetPayload_OneOfName whichOneOfName() => _FieldChangesetPayload_OneOfNameByTag[$_whichOneof(0)]!;
+  void clearOneOfName() => clearField($_whichOneof(0));
+
+  FieldChangesetPayload_OneOfDesc whichOneOfDesc() => _FieldChangesetPayload_OneOfDescByTag[$_whichOneof(1)]!;
+  void clearOneOfDesc() => clearField($_whichOneof(1));
+
+  FieldChangesetPayload_OneOfFieldType whichOneOfFieldType() => _FieldChangesetPayload_OneOfFieldTypeByTag[$_whichOneof(2)]!;
+  void clearOneOfFieldType() => clearField($_whichOneof(2));
+
+  FieldChangesetPayload_OneOfFrozen whichOneOfFrozen() => _FieldChangesetPayload_OneOfFrozenByTag[$_whichOneof(3)]!;
+  void clearOneOfFrozen() => clearField($_whichOneof(3));
+
+  FieldChangesetPayload_OneOfVisibility whichOneOfVisibility() => _FieldChangesetPayload_OneOfVisibilityByTag[$_whichOneof(4)]!;
+  void clearOneOfVisibility() => clearField($_whichOneof(4));
+
+  FieldChangesetPayload_OneOfWidth whichOneOfWidth() => _FieldChangesetPayload_OneOfWidthByTag[$_whichOneof(5)]!;
+  void clearOneOfWidth() => clearField($_whichOneof(5));
+
+  FieldChangesetPayload_OneOfTypeOptionData whichOneOfTypeOptionData() => _FieldChangesetPayload_OneOfTypeOptionDataByTag[$_whichOneof(6)]!;
+  void clearOneOfTypeOptionData() => clearField($_whichOneof(6));
+
+  @$pb.TagNumber(1)
+  $core.String get fieldId => $_getSZ(0);
+  @$pb.TagNumber(1)
+  set fieldId($core.String v) { $_setString(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasFieldId() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearFieldId() => clearField(1);
+
+  @$pb.TagNumber(2)
+  $core.String get gridId => $_getSZ(1);
+  @$pb.TagNumber(2)
+  set gridId($core.String v) { $_setString(1, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasGridId() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearGridId() => clearField(2);
+
+  @$pb.TagNumber(3)
+  $core.String get name => $_getSZ(2);
+  @$pb.TagNumber(3)
+  set name($core.String v) { $_setString(2, v); }
+  @$pb.TagNumber(3)
+  $core.bool hasName() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearName() => clearField(3);
+
+  @$pb.TagNumber(4)
+  $core.String get desc => $_getSZ(3);
+  @$pb.TagNumber(4)
+  set desc($core.String v) { $_setString(3, v); }
+  @$pb.TagNumber(4)
+  $core.bool hasDesc() => $_has(3);
+  @$pb.TagNumber(4)
+  void clearDesc() => clearField(4);
+
+  @$pb.TagNumber(5)
+  FieldType get fieldType => $_getN(4);
+  @$pb.TagNumber(5)
+  set fieldType(FieldType v) { setField(5, v); }
+  @$pb.TagNumber(5)
+  $core.bool hasFieldType() => $_has(4);
+  @$pb.TagNumber(5)
+  void clearFieldType() => clearField(5);
+
+  @$pb.TagNumber(6)
+  $core.bool get frozen => $_getBF(5);
+  @$pb.TagNumber(6)
+  set frozen($core.bool v) { $_setBool(5, v); }
+  @$pb.TagNumber(6)
+  $core.bool hasFrozen() => $_has(5);
+  @$pb.TagNumber(6)
+  void clearFrozen() => clearField(6);
+
+  @$pb.TagNumber(7)
+  $core.bool get visibility => $_getBF(6);
+  @$pb.TagNumber(7)
+  set visibility($core.bool v) { $_setBool(6, v); }
+  @$pb.TagNumber(7)
+  $core.bool hasVisibility() => $_has(6);
+  @$pb.TagNumber(7)
+  void clearVisibility() => clearField(7);
+
+  @$pb.TagNumber(8)
+  $core.int get width => $_getIZ(7);
+  @$pb.TagNumber(8)
+  set width($core.int v) { $_setSignedInt32(7, v); }
+  @$pb.TagNumber(8)
+  $core.bool hasWidth() => $_has(7);
+  @$pb.TagNumber(8)
+  void clearWidth() => clearField(8);
+
+  @$pb.TagNumber(9)
+  $core.List<$core.int> get typeOptionData => $_getN(8);
+  @$pb.TagNumber(9)
+  set typeOptionData($core.List<$core.int> v) { $_setBytes(8, v); }
+  @$pb.TagNumber(9)
+  $core.bool hasTypeOptionData() => $_has(8);
+  @$pb.TagNumber(9)
+  void clearTypeOptionData() => clearField(9);
+}
+

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

@@ -0,0 +1,36 @@
+///
+//  Generated code. Do not modify.
+//  source: field.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 FieldType URL = FieldType._(6, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'URL');
+
+  static const $core.List<FieldType> values = <FieldType> [
+    RichText,
+    Number,
+    DateTime,
+    SingleSelect,
+    MultiSelect,
+    Checkbox,
+    URL,
+  ];
+
+  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);
+}
+

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

@@ -0,0 +1,215 @@
+///
+//  Generated code. Do not modify.
+//  source: field.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},
+    const {'1': 'URL', '2': 6},
+  ],
+};
+
+/// Descriptor for `FieldType`. Decode as a `google.protobuf.EnumDescriptorProto`.
+final $typed_data.Uint8List fieldTypeDescriptor = $convert.base64Decode('CglGaWVsZFR5cGUSDAoIUmljaFRleHQQABIKCgZOdW1iZXIQARIMCghEYXRlVGltZRACEhAKDFNpbmdsZVNlbGVjdBADEg8KC011bHRpU2VsZWN0EAQSDAoIQ2hlY2tib3gQBRIHCgNVUkwQBg==');
+@$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': 'is_primary', '3': 8, '4': 1, '5': 8, '10': 'isPrimary'},
+  ],
+};
+
+/// Descriptor for `Field`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List fieldDescriptor = $convert.base64Decode('CgVGaWVsZBIOCgJpZBgBIAEoCVICaWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEikKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVSCWZpZWxkVHlwZRIWCgZmcm96ZW4YBSABKAhSBmZyb3plbhIeCgp2aXNpYmlsaXR5GAYgASgIUgp2aXNpYmlsaXR5EhQKBXdpZHRoGAcgASgFUgV3aWR0aBIdCgppc19wcmltYXJ5GAggASgIUglpc1ByaW1hcnk=');
+@$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'},
+  ],
+};
+
+/// Descriptor for `FieldOrder`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List fieldOrderDescriptor = $convert.base64Decode('CgpGaWVsZE9yZGVyEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElk');
+@$core.Deprecated('Use gridFieldChangesetDescriptor instead')
+const GridFieldChangeset$json = const {
+  '1': 'GridFieldChangeset',
+  '2': const [
+    const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'},
+    const {'1': 'inserted_fields', '3': 2, '4': 3, '5': 11, '6': '.IndexField', '10': 'insertedFields'},
+    const {'1': 'deleted_fields', '3': 3, '4': 3, '5': 11, '6': '.FieldOrder', '10': 'deletedFields'},
+    const {'1': 'updated_fields', '3': 4, '4': 3, '5': 11, '6': '.Field', '10': 'updatedFields'},
+  ],
+};
+
+/// Descriptor for `GridFieldChangeset`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List gridFieldChangesetDescriptor = $convert.base64Decode('ChJHcmlkRmllbGRDaGFuZ2VzZXQSFwoHZ3JpZF9pZBgBIAEoCVIGZ3JpZElkEjQKD2luc2VydGVkX2ZpZWxkcxgCIAMoCzILLkluZGV4RmllbGRSDmluc2VydGVkRmllbGRzEjIKDmRlbGV0ZWRfZmllbGRzGAMgAygLMgsuRmllbGRPcmRlclINZGVsZXRlZEZpZWxkcxItCg51cGRhdGVkX2ZpZWxkcxgEIAMoCzIGLkZpZWxkUg11cGRhdGVkRmllbGRz');
+@$core.Deprecated('Use indexFieldDescriptor instead')
+const IndexField$json = const {
+  '1': 'IndexField',
+  '2': const [
+    const {'1': 'field', '3': 1, '4': 1, '5': 11, '6': '.Field', '10': 'field'},
+    const {'1': 'index', '3': 2, '4': 1, '5': 5, '10': 'index'},
+  ],
+};
+
+/// Descriptor for `IndexField`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List indexFieldDescriptor = $convert.base64Decode('CgpJbmRleEZpZWxkEhwKBWZpZWxkGAEgASgLMgYuRmllbGRSBWZpZWxkEhQKBWluZGV4GAIgASgFUgVpbmRleA==');
+@$core.Deprecated('Use getEditFieldContextPayloadDescriptor instead')
+const GetEditFieldContextPayload$json = const {
+  '1': 'GetEditFieldContextPayload',
+  '2': const [
+    const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'},
+    const {'1': 'field_id', '3': 2, '4': 1, '5': 9, '9': 0, '10': 'fieldId'},
+    const {'1': 'field_type', '3': 3, '4': 1, '5': 14, '6': '.FieldType', '10': 'fieldType'},
+  ],
+  '8': const [
+    const {'1': 'one_of_field_id'},
+  ],
+};
+
+/// Descriptor for `GetEditFieldContextPayload`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List getEditFieldContextPayloadDescriptor = $convert.base64Decode('ChpHZXRFZGl0RmllbGRDb250ZXh0UGF5bG9hZBIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSGwoIZmllbGRfaWQYAiABKAlIAFIHZmllbGRJZBIpCgpmaWVsZF90eXBlGAMgASgOMgouRmllbGRUeXBlUglmaWVsZFR5cGVCEQoPb25lX29mX2ZpZWxkX2lk');
+@$core.Deprecated('Use editFieldPayloadDescriptor instead')
+const EditFieldPayload$json = const {
+  '1': 'EditFieldPayload',
+  '2': const [
+    const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'},
+    const {'1': 'field_id', '3': 2, '4': 1, '5': 9, '10': 'fieldId'},
+    const {'1': 'field_type', '3': 3, '4': 1, '5': 14, '6': '.FieldType', '10': 'fieldType'},
+    const {'1': 'create_if_not_exist', '3': 4, '4': 1, '5': 8, '10': 'createIfNotExist'},
+  ],
+};
+
+/// Descriptor for `EditFieldPayload`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List editFieldPayloadDescriptor = $convert.base64Decode('ChBFZGl0RmllbGRQYXlsb2FkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIZCghmaWVsZF9pZBgCIAEoCVIHZmllbGRJZBIpCgpmaWVsZF90eXBlGAMgASgOMgouRmllbGRUeXBlUglmaWVsZFR5cGUSLQoTY3JlYXRlX2lmX25vdF9leGlzdBgEIAEoCFIQY3JlYXRlSWZOb3RFeGlzdA==');
+@$core.Deprecated('Use fieldTypeOptionContextDescriptor instead')
+const FieldTypeOptionContext$json = const {
+  '1': 'FieldTypeOptionContext',
+  '2': const [
+    const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'},
+    const {'1': 'grid_field', '3': 2, '4': 1, '5': 11, '6': '.Field', '10': 'gridField'},
+    const {'1': 'type_option_data', '3': 3, '4': 1, '5': 12, '10': 'typeOptionData'},
+  ],
+};
+
+/// Descriptor for `FieldTypeOptionContext`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List fieldTypeOptionContextDescriptor = $convert.base64Decode('ChZGaWVsZFR5cGVPcHRpb25Db250ZXh0EhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIlCgpncmlkX2ZpZWxkGAIgASgLMgYuRmllbGRSCWdyaWRGaWVsZBIoChB0eXBlX29wdGlvbl9kYXRhGAMgASgMUg50eXBlT3B0aW9uRGF0YQ==');
+@$core.Deprecated('Use fieldTypeOptionDataDescriptor instead')
+const FieldTypeOptionData$json = const {
+  '1': 'FieldTypeOptionData',
+  '2': const [
+    const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'},
+    const {'1': 'field', '3': 2, '4': 1, '5': 11, '6': '.Field', '10': 'field'},
+    const {'1': 'type_option_data', '3': 3, '4': 1, '5': 12, '10': 'typeOptionData'},
+  ],
+};
+
+/// Descriptor for `FieldTypeOptionData`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List fieldTypeOptionDataDescriptor = $convert.base64Decode('ChNGaWVsZFR5cGVPcHRpb25EYXRhEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIcCgVmaWVsZBgCIAEoCzIGLkZpZWxkUgVmaWVsZBIoChB0eXBlX29wdGlvbl9kYXRhGAMgASgMUg50eXBlT3B0aW9uRGF0YQ==');
+@$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 repeatedFieldOrderDescriptor instead')
+const RepeatedFieldOrder$json = const {
+  '1': 'RepeatedFieldOrder',
+  '2': const [
+    const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.FieldOrder', '10': 'items'},
+  ],
+};
+
+/// Descriptor for `RepeatedFieldOrder`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List repeatedFieldOrderDescriptor = $convert.base64Decode('ChJSZXBlYXRlZEZpZWxkT3JkZXISIQoFaXRlbXMYASADKAsyCy5GaWVsZE9yZGVyUgVpdGVtcw==');
+@$core.Deprecated('Use insertFieldPayloadDescriptor instead')
+const InsertFieldPayload$json = const {
+  '1': 'InsertFieldPayload',
+  '2': const [
+    const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'},
+    const {'1': 'field', '3': 2, '4': 1, '5': 11, '6': '.Field', '10': 'field'},
+    const {'1': 'type_option_data', '3': 3, '4': 1, '5': 12, '10': 'typeOptionData'},
+    const {'1': 'start_field_id', '3': 4, '4': 1, '5': 9, '9': 0, '10': 'startFieldId'},
+  ],
+  '8': const [
+    const {'1': 'one_of_start_field_id'},
+  ],
+};
+
+/// Descriptor for `InsertFieldPayload`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List insertFieldPayloadDescriptor = $convert.base64Decode('ChJJbnNlcnRGaWVsZFBheWxvYWQSFwoHZ3JpZF9pZBgBIAEoCVIGZ3JpZElkEhwKBWZpZWxkGAIgASgLMgYuRmllbGRSBWZpZWxkEigKEHR5cGVfb3B0aW9uX2RhdGEYAyABKAxSDnR5cGVPcHRpb25EYXRhEiYKDnN0YXJ0X2ZpZWxkX2lkGAQgASgJSABSDHN0YXJ0RmllbGRJZEIXChVvbmVfb2Zfc3RhcnRfZmllbGRfaWQ=');
+@$core.Deprecated('Use updateFieldTypeOptionPayloadDescriptor instead')
+const UpdateFieldTypeOptionPayload$json = const {
+  '1': 'UpdateFieldTypeOptionPayload',
+  '2': const [
+    const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'},
+    const {'1': 'field_id', '3': 2, '4': 1, '5': 9, '10': 'fieldId'},
+    const {'1': 'type_option_data', '3': 3, '4': 1, '5': 12, '10': 'typeOptionData'},
+  ],
+};
+
+/// Descriptor for `UpdateFieldTypeOptionPayload`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List updateFieldTypeOptionPayloadDescriptor = $convert.base64Decode('ChxVcGRhdGVGaWVsZFR5cGVPcHRpb25QYXlsb2FkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIZCghmaWVsZF9pZBgCIAEoCVIHZmllbGRJZBIoChB0eXBlX29wdGlvbl9kYXRhGAMgASgMUg50eXBlT3B0aW9uRGF0YQ==');
+@$core.Deprecated('Use queryFieldPayloadDescriptor instead')
+const QueryFieldPayload$json = const {
+  '1': 'QueryFieldPayload',
+  '2': const [
+    const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'},
+    const {'1': 'field_orders', '3': 2, '4': 1, '5': 11, '6': '.RepeatedFieldOrder', '10': 'fieldOrders'},
+  ],
+};
+
+/// Descriptor for `QueryFieldPayload`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List queryFieldPayloadDescriptor = $convert.base64Decode('ChFRdWVyeUZpZWxkUGF5bG9hZBIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSNgoMZmllbGRfb3JkZXJzGAIgASgLMhMuUmVwZWF0ZWRGaWVsZE9yZGVyUgtmaWVsZE9yZGVycw==');
+@$core.Deprecated('Use fieldChangesetPayloadDescriptor instead')
+const FieldChangesetPayload$json = const {
+  '1': 'FieldChangesetPayload',
+  '2': const [
+    const {'1': 'field_id', '3': 1, '4': 1, '5': 9, '10': 'fieldId'},
+    const {'1': 'grid_id', '3': 2, '4': 1, '5': 9, '10': 'gridId'},
+    const {'1': 'name', '3': 3, '4': 1, '5': 9, '9': 0, '10': 'name'},
+    const {'1': 'desc', '3': 4, '4': 1, '5': 9, '9': 1, '10': 'desc'},
+    const {'1': 'field_type', '3': 5, '4': 1, '5': 14, '6': '.FieldType', '9': 2, '10': 'fieldType'},
+    const {'1': 'frozen', '3': 6, '4': 1, '5': 8, '9': 3, '10': 'frozen'},
+    const {'1': 'visibility', '3': 7, '4': 1, '5': 8, '9': 4, '10': 'visibility'},
+    const {'1': 'width', '3': 8, '4': 1, '5': 5, '9': 5, '10': 'width'},
+    const {'1': 'type_option_data', '3': 9, '4': 1, '5': 12, '9': 6, '10': 'typeOptionData'},
+  ],
+  '8': const [
+    const {'1': 'one_of_name'},
+    const {'1': 'one_of_desc'},
+    const {'1': 'one_of_field_type'},
+    const {'1': 'one_of_frozen'},
+    const {'1': 'one_of_visibility'},
+    const {'1': 'one_of_width'},
+    const {'1': 'one_of_type_option_data'},
+  ],
+};
+
+/// Descriptor for `FieldChangesetPayload`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List fieldChangesetPayloadDescriptor = $convert.base64Decode('ChVGaWVsZENoYW5nZXNldFBheWxvYWQSGQoIZmllbGRfaWQYASABKAlSB2ZpZWxkSWQSFwoHZ3JpZF9pZBgCIAEoCVIGZ3JpZElkEhQKBG5hbWUYAyABKAlIAFIEbmFtZRIUCgRkZXNjGAQgASgJSAFSBGRlc2MSKwoKZmllbGRfdHlwZRgFIAEoDjIKLkZpZWxkVHlwZUgCUglmaWVsZFR5cGUSGAoGZnJvemVuGAYgASgISANSBmZyb3plbhIgCgp2aXNpYmlsaXR5GAcgASgISARSCnZpc2liaWxpdHkSFgoFd2lkdGgYCCABKAVIBVIFd2lkdGgSKgoQdHlwZV9vcHRpb25fZGF0YRgJIAEoDEgGUg50eXBlT3B0aW9uRGF0YUINCgtvbmVfb2ZfbmFtZUINCgtvbmVfb2ZfZGVzY0ITChFvbmVfb2ZfZmllbGRfdHlwZUIPCg1vbmVfb2ZfZnJvemVuQhMKEW9uZV9vZl92aXNpYmlsaXR5Qg4KDG9uZV9vZl93aWR0aEIZChdvbmVfb2ZfdHlwZV9vcHRpb25fZGF0YQ==');

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

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

File diff suppressed because it is too large
+ 7 - 986
frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart


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

@@ -24,28 +24,3 @@ class MoveItemType extends $pb.ProtobufEnum {
   const MoveItemType._($core.int v, $core.String n) : super(v, n);
 }
 
-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 FieldType URL = FieldType._(6, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'URL');
-
-  static const $core.List<FieldType> values = <FieldType> [
-    RichText,
-    Number,
-    DateTime,
-    SingleSelect,
-    MultiSelect,
-    Checkbox,
-    URL,
-  ];
-
-  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);
-}
-

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

@@ -19,22 +19,6 @@ const MoveItemType$json = const {
 
 /// Descriptor for `MoveItemType`. Decode as a `google.protobuf.EnumDescriptorProto`.
 final $typed_data.Uint8List moveItemTypeDescriptor = $convert.base64Decode('CgxNb3ZlSXRlbVR5cGUSDQoJTW92ZUZpZWxkEAASCwoHTW92ZVJvdxAB');
-@$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},
-    const {'1': 'URL', '2': 6},
-  ],
-};
-
-/// Descriptor for `FieldType`. Decode as a `google.protobuf.EnumDescriptorProto`.
-final $typed_data.Uint8List fieldTypeDescriptor = $convert.base64Decode('CglGaWVsZFR5cGUSDAoIUmljaFRleHQQABIKCgZOdW1iZXIQARIMCghEYXRlVGltZRACEhAKDFNpbmdsZVNlbGVjdBADEg8KC011bHRpU2VsZWN0EAQSDAoIQ2hlY2tib3gQBRIHCgNVUkwQBg==');
 @$core.Deprecated('Use gridDescriptor instead')
 const Grid$json = const {
   '1': 'Grid',
@@ -47,129 +31,6 @@ const Grid$json = const {
 
 /// Descriptor for `Grid`. Decode as a `google.protobuf.DescriptorProto`.
 final $typed_data.Uint8List gridDescriptor = $convert.base64Decode('CgRHcmlkEg4KAmlkGAEgASgJUgJpZBIuCgxmaWVsZF9vcmRlcnMYAiADKAsyCy5GaWVsZE9yZGVyUgtmaWVsZE9yZGVycxIyCgxibG9ja19vcmRlcnMYAyADKAsyDy5HcmlkQmxvY2tPcmRlclILYmxvY2tPcmRlcnM=');
-@$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': 'is_primary', '3': 8, '4': 1, '5': 8, '10': 'isPrimary'},
-  ],
-};
-
-/// Descriptor for `Field`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List fieldDescriptor = $convert.base64Decode('CgVGaWVsZBIOCgJpZBgBIAEoCVICaWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEikKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVSCWZpZWxkVHlwZRIWCgZmcm96ZW4YBSABKAhSBmZyb3plbhIeCgp2aXNpYmlsaXR5GAYgASgIUgp2aXNpYmlsaXR5EhQKBXdpZHRoGAcgASgFUgV3aWR0aBIdCgppc19wcmltYXJ5GAggASgIUglpc1ByaW1hcnk=');
-@$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'},
-  ],
-};
-
-/// Descriptor for `FieldOrder`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List fieldOrderDescriptor = $convert.base64Decode('CgpGaWVsZE9yZGVyEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElk');
-@$core.Deprecated('Use gridFieldChangesetDescriptor instead')
-const GridFieldChangeset$json = const {
-  '1': 'GridFieldChangeset',
-  '2': const [
-    const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'},
-    const {'1': 'inserted_fields', '3': 2, '4': 3, '5': 11, '6': '.IndexField', '10': 'insertedFields'},
-    const {'1': 'deleted_fields', '3': 3, '4': 3, '5': 11, '6': '.FieldOrder', '10': 'deletedFields'},
-    const {'1': 'updated_fields', '3': 4, '4': 3, '5': 11, '6': '.Field', '10': 'updatedFields'},
-  ],
-};
-
-/// Descriptor for `GridFieldChangeset`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List gridFieldChangesetDescriptor = $convert.base64Decode('ChJHcmlkRmllbGRDaGFuZ2VzZXQSFwoHZ3JpZF9pZBgBIAEoCVIGZ3JpZElkEjQKD2luc2VydGVkX2ZpZWxkcxgCIAMoCzILLkluZGV4RmllbGRSDmluc2VydGVkRmllbGRzEjIKDmRlbGV0ZWRfZmllbGRzGAMgAygLMgsuRmllbGRPcmRlclINZGVsZXRlZEZpZWxkcxItCg51cGRhdGVkX2ZpZWxkcxgEIAMoCzIGLkZpZWxkUg11cGRhdGVkRmllbGRz');
-@$core.Deprecated('Use indexFieldDescriptor instead')
-const IndexField$json = const {
-  '1': 'IndexField',
-  '2': const [
-    const {'1': 'field', '3': 1, '4': 1, '5': 11, '6': '.Field', '10': 'field'},
-    const {'1': 'index', '3': 2, '4': 1, '5': 5, '10': 'index'},
-  ],
-};
-
-/// Descriptor for `IndexField`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List indexFieldDescriptor = $convert.base64Decode('CgpJbmRleEZpZWxkEhwKBWZpZWxkGAEgASgLMgYuRmllbGRSBWZpZWxkEhQKBWluZGV4GAIgASgFUgVpbmRleA==');
-@$core.Deprecated('Use getEditFieldContextPayloadDescriptor instead')
-const GetEditFieldContextPayload$json = const {
-  '1': 'GetEditFieldContextPayload',
-  '2': const [
-    const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'},
-    const {'1': 'field_id', '3': 2, '4': 1, '5': 9, '9': 0, '10': 'fieldId'},
-    const {'1': 'field_type', '3': 3, '4': 1, '5': 14, '6': '.FieldType', '10': 'fieldType'},
-  ],
-  '8': const [
-    const {'1': 'one_of_field_id'},
-  ],
-};
-
-/// Descriptor for `GetEditFieldContextPayload`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List getEditFieldContextPayloadDescriptor = $convert.base64Decode('ChpHZXRFZGl0RmllbGRDb250ZXh0UGF5bG9hZBIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSGwoIZmllbGRfaWQYAiABKAlIAFIHZmllbGRJZBIpCgpmaWVsZF90eXBlGAMgASgOMgouRmllbGRUeXBlUglmaWVsZFR5cGVCEQoPb25lX29mX2ZpZWxkX2lk');
-@$core.Deprecated('Use editFieldPayloadDescriptor instead')
-const EditFieldPayload$json = const {
-  '1': 'EditFieldPayload',
-  '2': const [
-    const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'},
-    const {'1': 'field_id', '3': 2, '4': 1, '5': 9, '10': 'fieldId'},
-    const {'1': 'field_type', '3': 3, '4': 1, '5': 14, '6': '.FieldType', '10': 'fieldType'},
-    const {'1': 'create_if_not_exist', '3': 4, '4': 1, '5': 8, '10': 'createIfNotExist'},
-  ],
-};
-
-/// Descriptor for `EditFieldPayload`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List editFieldPayloadDescriptor = $convert.base64Decode('ChBFZGl0RmllbGRQYXlsb2FkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIZCghmaWVsZF9pZBgCIAEoCVIHZmllbGRJZBIpCgpmaWVsZF90eXBlGAMgASgOMgouRmllbGRUeXBlUglmaWVsZFR5cGUSLQoTY3JlYXRlX2lmX25vdF9leGlzdBgEIAEoCFIQY3JlYXRlSWZOb3RFeGlzdA==');
-@$core.Deprecated('Use fieldTypeOptionContextDescriptor instead')
-const FieldTypeOptionContext$json = const {
-  '1': 'FieldTypeOptionContext',
-  '2': const [
-    const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'},
-    const {'1': 'grid_field', '3': 2, '4': 1, '5': 11, '6': '.Field', '10': 'gridField'},
-    const {'1': 'type_option_data', '3': 3, '4': 1, '5': 12, '10': 'typeOptionData'},
-  ],
-};
-
-/// Descriptor for `FieldTypeOptionContext`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List fieldTypeOptionContextDescriptor = $convert.base64Decode('ChZGaWVsZFR5cGVPcHRpb25Db250ZXh0EhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIlCgpncmlkX2ZpZWxkGAIgASgLMgYuRmllbGRSCWdyaWRGaWVsZBIoChB0eXBlX29wdGlvbl9kYXRhGAMgASgMUg50eXBlT3B0aW9uRGF0YQ==');
-@$core.Deprecated('Use fieldTypeOptionDataDescriptor instead')
-const FieldTypeOptionData$json = const {
-  '1': 'FieldTypeOptionData',
-  '2': const [
-    const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'},
-    const {'1': 'field', '3': 2, '4': 1, '5': 11, '6': '.Field', '10': 'field'},
-    const {'1': 'type_option_data', '3': 3, '4': 1, '5': 12, '10': 'typeOptionData'},
-  ],
-};
-
-/// Descriptor for `FieldTypeOptionData`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List fieldTypeOptionDataDescriptor = $convert.base64Decode('ChNGaWVsZFR5cGVPcHRpb25EYXRhEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIcCgVmaWVsZBgCIAEoCzIGLkZpZWxkUgVmaWVsZBIoChB0eXBlX29wdGlvbl9kYXRhGAMgASgMUg50eXBlT3B0aW9uRGF0YQ==');
-@$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 repeatedFieldOrderDescriptor instead')
-const RepeatedFieldOrder$json = const {
-  '1': 'RepeatedFieldOrder',
-  '2': const [
-    const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.FieldOrder', '10': 'items'},
-  ],
-};
-
-/// Descriptor for `RepeatedFieldOrder`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List repeatedFieldOrderDescriptor = $convert.base64Decode('ChJSZXBlYXRlZEZpZWxkT3JkZXISIQoFaXRlbXMYASADKAsyCy5GaWVsZE9yZGVyUgVpdGVtcw==');
 @$core.Deprecated('Use rowOrderDescriptor instead')
 const RowOrder$json = const {
   '1': 'RowOrder',
@@ -350,45 +211,6 @@ const CreateRowPayload$json = const {
 
 /// Descriptor for `CreateRowPayload`. Decode as a `google.protobuf.DescriptorProto`.
 final $typed_data.Uint8List createRowPayloadDescriptor = $convert.base64Decode('ChBDcmVhdGVSb3dQYXlsb2FkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIiCgxzdGFydF9yb3dfaWQYAiABKAlIAFIKc3RhcnRSb3dJZEIVChNvbmVfb2Zfc3RhcnRfcm93X2lk');
-@$core.Deprecated('Use insertFieldPayloadDescriptor instead')
-const InsertFieldPayload$json = const {
-  '1': 'InsertFieldPayload',
-  '2': const [
-    const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'},
-    const {'1': 'field', '3': 2, '4': 1, '5': 11, '6': '.Field', '10': 'field'},
-    const {'1': 'type_option_data', '3': 3, '4': 1, '5': 12, '10': 'typeOptionData'},
-    const {'1': 'start_field_id', '3': 4, '4': 1, '5': 9, '9': 0, '10': 'startFieldId'},
-  ],
-  '8': const [
-    const {'1': 'one_of_start_field_id'},
-  ],
-};
-
-/// Descriptor for `InsertFieldPayload`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List insertFieldPayloadDescriptor = $convert.base64Decode('ChJJbnNlcnRGaWVsZFBheWxvYWQSFwoHZ3JpZF9pZBgBIAEoCVIGZ3JpZElkEhwKBWZpZWxkGAIgASgLMgYuRmllbGRSBWZpZWxkEigKEHR5cGVfb3B0aW9uX2RhdGEYAyABKAxSDnR5cGVPcHRpb25EYXRhEiYKDnN0YXJ0X2ZpZWxkX2lkGAQgASgJSABSDHN0YXJ0RmllbGRJZEIXChVvbmVfb2Zfc3RhcnRfZmllbGRfaWQ=');
-@$core.Deprecated('Use updateFieldTypeOptionPayloadDescriptor instead')
-const UpdateFieldTypeOptionPayload$json = const {
-  '1': 'UpdateFieldTypeOptionPayload',
-  '2': const [
-    const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'},
-    const {'1': 'field_id', '3': 2, '4': 1, '5': 9, '10': 'fieldId'},
-    const {'1': 'type_option_data', '3': 3, '4': 1, '5': 12, '10': 'typeOptionData'},
-  ],
-};
-
-/// Descriptor for `UpdateFieldTypeOptionPayload`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List updateFieldTypeOptionPayloadDescriptor = $convert.base64Decode('ChxVcGRhdGVGaWVsZFR5cGVPcHRpb25QYXlsb2FkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIZCghmaWVsZF9pZBgCIAEoCVIHZmllbGRJZBIoChB0eXBlX29wdGlvbl9kYXRhGAMgASgMUg50eXBlT3B0aW9uRGF0YQ==');
-@$core.Deprecated('Use queryFieldPayloadDescriptor instead')
-const QueryFieldPayload$json = const {
-  '1': 'QueryFieldPayload',
-  '2': const [
-    const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'},
-    const {'1': 'field_orders', '3': 2, '4': 1, '5': 11, '6': '.RepeatedFieldOrder', '10': 'fieldOrders'},
-  ],
-};
-
-/// Descriptor for `QueryFieldPayload`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List queryFieldPayloadDescriptor = $convert.base64Decode('ChFRdWVyeUZpZWxkUGF5bG9hZBIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSNgoMZmllbGRfb3JkZXJzGAIgASgLMhMuUmVwZWF0ZWRGaWVsZE9yZGVyUgtmaWVsZE9yZGVycw==');
 @$core.Deprecated('Use queryGridBlocksPayloadDescriptor instead')
 const QueryGridBlocksPayload$json = const {
   '1': 'QueryGridBlocksPayload',
@@ -400,33 +222,6 @@ const QueryGridBlocksPayload$json = const {
 
 /// Descriptor for `QueryGridBlocksPayload`. Decode as a `google.protobuf.DescriptorProto`.
 final $typed_data.Uint8List queryGridBlocksPayloadDescriptor = $convert.base64Decode('ChZRdWVyeUdyaWRCbG9ja3NQYXlsb2FkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIyCgxibG9ja19vcmRlcnMYAiADKAsyDy5HcmlkQmxvY2tPcmRlclILYmxvY2tPcmRlcnM=');
-@$core.Deprecated('Use fieldChangesetPayloadDescriptor instead')
-const FieldChangesetPayload$json = const {
-  '1': 'FieldChangesetPayload',
-  '2': const [
-    const {'1': 'field_id', '3': 1, '4': 1, '5': 9, '10': 'fieldId'},
-    const {'1': 'grid_id', '3': 2, '4': 1, '5': 9, '10': 'gridId'},
-    const {'1': 'name', '3': 3, '4': 1, '5': 9, '9': 0, '10': 'name'},
-    const {'1': 'desc', '3': 4, '4': 1, '5': 9, '9': 1, '10': 'desc'},
-    const {'1': 'field_type', '3': 5, '4': 1, '5': 14, '6': '.FieldType', '9': 2, '10': 'fieldType'},
-    const {'1': 'frozen', '3': 6, '4': 1, '5': 8, '9': 3, '10': 'frozen'},
-    const {'1': 'visibility', '3': 7, '4': 1, '5': 8, '9': 4, '10': 'visibility'},
-    const {'1': 'width', '3': 8, '4': 1, '5': 5, '9': 5, '10': 'width'},
-    const {'1': 'type_option_data', '3': 9, '4': 1, '5': 12, '9': 6, '10': 'typeOptionData'},
-  ],
-  '8': const [
-    const {'1': 'one_of_name'},
-    const {'1': 'one_of_desc'},
-    const {'1': 'one_of_field_type'},
-    const {'1': 'one_of_frozen'},
-    const {'1': 'one_of_visibility'},
-    const {'1': 'one_of_width'},
-    const {'1': 'one_of_type_option_data'},
-  ],
-};
-
-/// Descriptor for `FieldChangesetPayload`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List fieldChangesetPayloadDescriptor = $convert.base64Decode('ChVGaWVsZENoYW5nZXNldFBheWxvYWQSGQoIZmllbGRfaWQYASABKAlSB2ZpZWxkSWQSFwoHZ3JpZF9pZBgCIAEoCVIGZ3JpZElkEhQKBG5hbWUYAyABKAlIAFIEbmFtZRIUCgRkZXNjGAQgASgJSAFSBGRlc2MSKwoKZmllbGRfdHlwZRgFIAEoDjIKLkZpZWxkVHlwZUgCUglmaWVsZFR5cGUSGAoGZnJvemVuGAYgASgISANSBmZyb3plbhIgCgp2aXNpYmlsaXR5GAcgASgISARSCnZpc2liaWxpdHkSFgoFd2lkdGgYCCABKAVIBVIFd2lkdGgSKgoQdHlwZV9vcHRpb25fZGF0YRgJIAEoDEgGUg50eXBlT3B0aW9uRGF0YUINCgtvbmVfb2ZfbmFtZUINCgtvbmVfb2ZfZGVzY0ITChFvbmVfb2ZfZmllbGRfdHlwZUIPCg1vbmVfb2ZfZnJvemVuQhMKEW9uZV9vZl92aXNpYmlsaXR5Qg4KDG9uZV9vZl93aWR0aEIZChdvbmVfb2ZfdHlwZV9vcHRpb25fZGF0YQ==');
 @$core.Deprecated('Use moveItemPayloadDescriptor instead')
 const MoveItemPayload$json = const {
   '1': 'MoveItemPayload',

+ 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 './field.pb.dart';

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

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

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

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

+ 3 - 20
frontend/rust-lib/flowy-folder/src/services/view/controller.rs

@@ -259,26 +259,9 @@ impl ViewController {
         Ok(view_rev)
     }
 
-    #[tracing::instrument(level = "debug", skip(self, params), err)]
-    pub(crate) async fn update_view_info(&self, params: UpdateViewInfoParams) -> Result<ViewRevision, FlowyError> {
-        let changeset = ViewChangeset::new(params.clone());
-        let view_id = changeset.id.clone();
-        let view_rev = self
-            .persistence
-            .begin_transaction(|transaction| {
-                let _ = transaction.update_view(changeset)?;
-                let view_rev = transaction.read_view(&view_id)?;
-                let view: View = view_rev.clone().into();
-                send_dart_notification(&view_id, FolderNotification::ViewUpdated)
-                    .payload(view)
-                    .send();
-                let _ = notify_views_changed(&view_rev.belong_to_id, self.trash_controller.clone(), &transaction)?;
-                Ok(view_rev)
-            })
-            .await?;
-
-        let _ = self.update_view_on_server(params);
-        Ok(view_rev)
+    #[tracing::instrument(level = "debug", skip(self, _params), err)]
+    pub(crate) async fn update_view_info(&self, _params: UpdateViewInfoParams) -> Result<(), FlowyError> {
+        todo!()
     }
 
     pub(crate) async fn latest_visit_view(&self) -> FlowyResult<Option<ViewRevision>> {

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

@@ -4,6 +4,7 @@ use crate::services::field::type_options::*;
 use crate::services::field::{default_type_option_builder_from_type, type_option_builder_from_json_str};
 use flowy_error::{ErrorCode, FlowyError, FlowyResult};
 use flowy_grid_data_model::entities::*;
+use flowy_grid_data_model::revision::FieldRevision;
 use lib_dispatch::prelude::{data_result, AppData, Data, DataResult};
 use std::sync::Arc;
 
@@ -42,8 +43,8 @@ pub(crate) async fn get_fields_handler(
     let params: QueryFieldParams = data.into_inner().try_into()?;
     let editor = manager.get_grid_editor(&params.grid_id)?;
     let field_orders = params.field_orders.items;
-    let field_metas = editor.get_field_metas(Some(field_orders)).await?;
-    let repeated_field: RepeatedField = field_metas.into_iter().map(Field::from).collect::<Vec<_>>().into();
+    let field_revs = editor.get_field_revs(Some(field_orders)).await?;
+    let repeated_field: RepeatedField = field_revs.into_iter().map(Field::from).collect::<Vec<_>>().into();
     data_result(repeated_field)
 }
 
@@ -105,15 +106,15 @@ pub(crate) async fn switch_to_field_handler(
         .await?;
 
     // Get the FieldMeta with field_id, if it doesn't exist, we create the default FieldMeta from the FieldType.
-    let field_meta = editor
-        .get_field_meta(&params.field_id)
+    let field_rev = editor
+        .get_field_rev(&params.field_id)
         .await
-        .unwrap_or(editor.next_field_meta(&params.field_type).await?);
+        .unwrap_or(editor.next_field_rev(&params.field_type).await?);
 
-    let type_option_data = get_type_option_data(&field_meta, &params.field_type).await?;
+    let type_option_data = get_type_option_data(&field_rev, &params.field_type).await?;
     let data = FieldTypeOptionData {
         grid_id: params.grid_id,
-        field: field_meta.into(),
+        field: field_rev.into(),
         type_option_data,
     };
 
@@ -139,13 +140,13 @@ pub(crate) async fn get_field_type_option_data_handler(
 ) -> DataResult<FieldTypeOptionData, FlowyError> {
     let params: EditFieldParams = data.into_inner().try_into()?;
     let editor = manager.get_grid_editor(&params.grid_id)?;
-    match editor.get_field_meta(&params.field_id).await {
+    match editor.get_field_rev(&params.field_id).await {
         None => Err(FlowyError::record_not_found()),
-        Some(field_meta) => {
-            let type_option_data = get_type_option_data(&field_meta, &field_meta.field_type).await?;
+        Some(field_rev) => {
+            let type_option_data = get_type_option_data(&field_rev, &field_rev.field_type).await?;
             let data = FieldTypeOptionData {
                 grid_id: params.grid_id,
-                field: field_meta.into(),
+                field: field_rev.into(),
                 type_option_data,
             };
             data_result(data)
@@ -161,12 +162,12 @@ pub(crate) async fn create_field_type_option_data_handler(
 ) -> DataResult<FieldTypeOptionData, FlowyError> {
     let params: CreateFieldParams = data.into_inner().try_into()?;
     let editor = manager.get_grid_editor(&params.grid_id)?;
-    let field_meta = editor.create_next_field_meta(&params.field_type).await?;
-    let type_option_data = get_type_option_data(&field_meta, &field_meta.field_type).await?;
+    let field_rev = editor.create_next_field_rev(&params.field_type).await?;
+    let type_option_data = get_type_option_data(&field_rev, &field_rev.field_type).await?;
 
     data_result(FieldTypeOptionData {
         grid_id: params.grid_id,
-        field: field_meta.into(),
+        field: field_rev.into(),
         type_option_data,
     })
 }
@@ -183,11 +184,11 @@ pub(crate) async fn move_item_handler(
 }
 
 /// The FieldMeta contains multiple data, each of them belongs to a specific FieldType.
-async fn get_type_option_data(field_meta: &FieldMeta, field_type: &FieldType) -> FlowyResult<Vec<u8>> {
-    let s = field_meta
+async fn get_type_option_data(field_rev: &FieldRevision, field_type: &FieldType) -> FlowyResult<Vec<u8>> {
+    let s = field_rev
         .get_type_option_str(field_type)
         .unwrap_or_else(|| default_type_option_builder_from_type(field_type).entry().json_str());
-    let builder = type_option_builder_from_json_str(&s, &field_meta.field_type);
+    let builder = type_option_builder_from_json_str(&s, &field_rev.field_type);
     let type_option_data = builder.entry().protobuf_bytes().to_vec();
 
     Ok(type_option_data)
@@ -270,10 +271,10 @@ pub(crate) async fn new_select_option_handler(
 ) -> DataResult<SelectOption, FlowyError> {
     let params: CreateSelectOptionParams = data.into_inner().try_into()?;
     let editor = manager.get_grid_editor(&params.grid_id)?;
-    match editor.get_field_meta(&params.field_id).await {
+    match editor.get_field_rev(&params.field_id).await {
         None => Err(ErrorCode::InvalidData.into()),
-        Some(field_meta) => {
-            let type_option = select_option_operation(&field_meta)?;
+        Some(field_rev) => {
+            let type_option = select_option_operation(&field_rev)?;
             let select_option = type_option.create_option(&params.option_name);
             data_result(select_option)
         }
@@ -288,8 +289,8 @@ pub(crate) async fn update_select_option_handler(
     let changeset: SelectOptionChangeset = data.into_inner().try_into()?;
     let editor = manager.get_grid_editor(&changeset.cell_identifier.grid_id)?;
 
-    if let Some(mut field_meta) = editor.get_field_meta(&changeset.cell_identifier.field_id).await {
-        let mut type_option = select_option_operation(&field_meta)?;
+    if let Some(mut field_rev) = editor.get_field_rev(&changeset.cell_identifier.field_id).await {
+        let mut type_option = select_option_operation(&field_rev)?;
         let mut cell_content_changeset = None;
 
         if let Some(option) = changeset.insert_option {
@@ -306,8 +307,8 @@ pub(crate) async fn update_select_option_handler(
             type_option.delete_option(option);
         }
 
-        field_meta.insert_type_option_entry(&*type_option);
-        let _ = editor.replace_field(field_meta).await?;
+        field_rev.insert_type_option_entry(&*type_option);
+        let _ = editor.replace_field(field_rev).await?;
 
         let changeset = CellChangeset {
             grid_id: changeset.cell_identifier.grid_id,
@@ -327,15 +328,15 @@ pub(crate) async fn get_select_option_handler(
 ) -> DataResult<SelectOptionCellData, FlowyError> {
     let params: CellIdentifier = data.into_inner().try_into()?;
     let editor = manager.get_grid_editor(&params.grid_id)?;
-    match editor.get_field_meta(&params.field_id).await {
+    match editor.get_field_rev(&params.field_id).await {
         None => {
             tracing::error!("Can't find the select option field with id: {}", params.field_id);
             data_result(SelectOptionCellData::default())
         }
-        Some(field_meta) => {
-            let cell_meta = editor.get_cell_meta(&params.row_id, &params.field_id).await?;
-            let type_option = select_option_operation(&field_meta)?;
-            let option_context = type_option.select_option_cell_data(&cell_meta);
+        Some(field_rev) => {
+            let cell_rev = editor.get_cell_rev(&params.row_id, &params.field_id).await?;
+            let type_option = select_option_operation(&field_rev)?;
+            let option_context = type_option.select_option_cell_data(&cell_rev);
             data_result(option_context)
         }
     }

+ 3 - 3
frontend/rust-lib/flowy-grid/src/macros.rs

@@ -28,9 +28,9 @@ macro_rules! impl_builder_from_json_str_and_from_bytes {
 #[macro_export]
 macro_rules! impl_type_option {
     ($target: ident, $field_type:expr) => {
-        impl std::convert::From<&FieldMeta> for $target {
-            fn from(field_meta: &FieldMeta) -> $target {
-                match field_meta.get_type_option_entry::<$target>(&$field_type) {
+        impl std::convert::From<&FieldRevision> for $target {
+            fn from(field_rev: &FieldRevision) -> $target {
+                match field_rev.get_type_option_entry::<$target>(&$field_type) {
                     None => $target::default(),
                     Some(target) => target,
                 }

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

@@ -6,7 +6,7 @@ use bytes::Bytes;
 use dashmap::DashMap;
 use flowy_database::ConnectionPool;
 use flowy_error::{FlowyError, FlowyResult};
-use flowy_grid_data_model::entities::{BuildGridContext, GridMeta};
+use flowy_grid_data_model::revision::{BuildGridContext, GridRevision};
 use flowy_revision::disk::{SQLiteGridBlockMetaRevisionPersistence, SQLiteGridRevisionPersistence};
 use flowy_revision::{RevisionManager, RevisionPersistence, RevisionWebSocket};
 use flowy_sync::client_grid::{make_block_meta_delta, make_grid_delta};
@@ -156,14 +156,14 @@ pub async fn make_grid_view_data(
     grid_manager: Arc<GridManager>,
     build_context: BuildGridContext,
 ) -> FlowyResult<Bytes> {
-    let grid_meta = GridMeta {
+    let grid_rev = GridRevision {
         grid_id: view_id.to_string(),
-        fields: build_context.field_metas,
+        fields: build_context.field_revs,
         blocks: build_context.blocks,
     };
 
     // Create grid
-    let grid_meta_delta = make_grid_delta(&grid_meta);
+    let grid_meta_delta = make_grid_delta(&grid_rev);
     let grid_delta_data = grid_meta_delta.to_delta_bytes();
     let repeated_revision: RepeatedRevision =
         Revision::initial_revision(user_id, view_id, grid_delta_data.clone()).into();

+ 46 - 44
frontend/rust-lib/flowy-grid/src/services/block_meta_manager.rs → frontend/rust-lib/flowy-grid/src/services/block_manager.rs

@@ -1,13 +1,15 @@
 use crate::dart_notification::{send_dart_notification, GridNotification};
 use crate::manager::GridUser;
-use crate::services::block_meta_editor::GridBlockMetaEditor;
+use crate::services::block_revision_editor::GridBlockRevisionEditor;
 use crate::services::persistence::block_index::BlockIndexCache;
 use crate::services::row::{group_row_orders, GridBlockSnapshot};
 use dashmap::DashMap;
 use flowy_error::FlowyResult;
 use flowy_grid_data_model::entities::{
-    CellChangeset, CellMeta, GridBlockMeta, GridBlockMetaChangeset, GridRowsChangeset, IndexRowOrder, Row, RowMeta,
-    RowMetaChangeset, RowOrder, UpdatedRowOrder,
+    CellChangeset, GridRowsChangeset, IndexRowOrder, Row, RowOrder, UpdatedRowOrder,
+};
+use flowy_grid_data_model::revision::{
+    CellRevision, GridBlockRevision, GridBlockRevisionChangeset, RowMetaChangeset, RowRevision,
 };
 use flowy_revision::disk::SQLiteGridBlockMetaRevisionPersistence;
 use flowy_revision::{RevisionManager, RevisionPersistence};
@@ -20,14 +22,14 @@ pub(crate) struct GridBlockManager {
     grid_id: String,
     user: Arc<dyn GridUser>,
     persistence: Arc<BlockIndexCache>,
-    block_editor_map: DashMap<BlockId, Arc<GridBlockMetaEditor>>,
+    block_editor_map: DashMap<BlockId, Arc<GridBlockRevisionEditor>>,
 }
 
 impl GridBlockManager {
     pub(crate) async fn new(
         grid_id: &str,
         user: &Arc<dyn GridUser>,
-        blocks: Vec<GridBlockMeta>,
+        blocks: Vec<GridBlockRevision>,
         persistence: Arc<BlockIndexCache>,
     ) -> FlowyResult<Self> {
         let editor_map = make_block_meta_editor_map(user, blocks).await?;
@@ -43,7 +45,7 @@ impl GridBlockManager {
     }
 
     // #[tracing::instrument(level = "trace", skip(self))]
-    pub(crate) async fn get_editor(&self, block_id: &str) -> FlowyResult<Arc<GridBlockMetaEditor>> {
+    pub(crate) async fn get_editor(&self, block_id: &str) -> FlowyResult<Arc<GridBlockRevisionEditor>> {
         debug_assert!(!block_id.is_empty());
         match self.block_editor_map.get(block_id) {
             None => {
@@ -56,7 +58,7 @@ impl GridBlockManager {
         }
     }
 
-    async fn get_editor_from_row_id(&self, row_id: &str) -> FlowyResult<Arc<GridBlockMetaEditor>> {
+    async fn get_editor_from_row_id(&self, row_id: &str) -> FlowyResult<Arc<GridBlockRevisionEditor>> {
         let block_id = self.persistence.get_block_id(row_id)?;
         Ok(self.get_editor(&block_id).await?)
     }
@@ -64,14 +66,14 @@ impl GridBlockManager {
     pub(crate) async fn create_row(
         &self,
         block_id: &str,
-        row_meta: RowMeta,
+        row_rev: RowRevision,
         start_row_id: Option<String>,
     ) -> FlowyResult<i32> {
-        let _ = self.persistence.insert(&row_meta.block_id, &row_meta.id)?;
-        let editor = self.get_editor(&row_meta.block_id).await?;
+        let _ = self.persistence.insert(&row_rev.block_id, &row_rev.id)?;
+        let editor = self.get_editor(&row_rev.block_id).await?;
 
-        let mut index_row_order = IndexRowOrder::from(&row_meta);
-        let (row_count, row_index) = editor.create_row(row_meta, start_row_id).await?;
+        let mut index_row_order = IndexRowOrder::from(&row_rev);
+        let (row_count, row_index) = editor.create_row(row_rev, start_row_id).await?;
         index_row_order.index = row_index;
 
         let _ = self
@@ -82,14 +84,14 @@ impl GridBlockManager {
 
     pub(crate) async fn insert_row(
         &self,
-        rows_by_block_id: HashMap<String, Vec<RowMeta>>,
-    ) -> FlowyResult<Vec<GridBlockMetaChangeset>> {
+        rows_by_block_id: HashMap<String, Vec<RowRevision>>,
+    ) -> FlowyResult<Vec<GridBlockRevisionChangeset>> {
         let mut changesets = vec![];
-        for (block_id, row_metas) in rows_by_block_id {
+        for (block_id, row_revs) in rows_by_block_id {
             let mut inserted_row_orders = vec![];
             let editor = self.get_editor(&block_id).await?;
             let mut row_count = 0;
-            for row in row_metas {
+            for row in row_revs {
                 let _ = self.persistence.insert(&row.block_id, &row.id)?;
                 let mut row_order = IndexRowOrder::from(&row);
                 let (count, index) = editor.create_row(row, None).await?;
@@ -97,7 +99,7 @@ impl GridBlockManager {
                 row_order.index = index;
                 inserted_row_orders.push(row_order);
             }
-            changesets.push(GridBlockMetaChangeset::from_row_count(&block_id, row_count));
+            changesets.push(GridBlockRevisionChangeset::from_row_count(&block_id, row_count));
 
             let _ = self
                 .notify_did_update_block(GridRowsChangeset::insert(&block_id, inserted_row_orders))
@@ -109,15 +111,15 @@ impl GridBlockManager {
 
     pub async fn update_row<F>(&self, changeset: RowMetaChangeset, row_builder: F) -> FlowyResult<()>
     where
-        F: FnOnce(Arc<RowMeta>) -> Option<Row>,
+        F: FnOnce(Arc<RowRevision>) -> Option<Row>,
     {
         let editor = self.get_editor_from_row_id(&changeset.row_id).await?;
         let _ = editor.update_row(changeset.clone()).await?;
-        match editor.get_row_meta(&changeset.row_id).await? {
+        match editor.get_row_rev(&changeset.row_id).await? {
             None => tracing::error!("Internal error: can't find the row with id: {}", changeset.row_id),
-            Some(row_meta) => {
-                if let Some(row) = row_builder(row_meta.clone()) {
-                    let row_order = UpdatedRowOrder::new(&row_meta, row);
+            Some(row_rev) => {
+                if let Some(row) = row_builder(row_rev.clone()) {
+                    let row_order = UpdatedRowOrder::new(&row_rev, row);
                     let block_order_changeset = GridRowsChangeset::update(&editor.block_id, vec![row_order]);
                     let _ = self.notify_did_update_block(block_order_changeset).await?;
                 }
@@ -143,7 +145,7 @@ impl GridBlockManager {
         Ok(())
     }
 
-    pub(crate) async fn delete_rows(&self, row_orders: Vec<RowOrder>) -> FlowyResult<Vec<GridBlockMetaChangeset>> {
+    pub(crate) async fn delete_rows(&self, row_orders: Vec<RowOrder>) -> FlowyResult<Vec<GridBlockRevisionChangeset>> {
         let mut changesets = vec![];
         for block_order in group_row_orders(row_orders) {
             let editor = self.get_editor(&block_order.block_id).await?;
@@ -153,7 +155,7 @@ impl GridBlockManager {
                 .map(|row_order| Cow::Owned(row_order.row_id))
                 .collect::<Vec<Cow<String>>>();
             let row_count = editor.delete_rows(row_ids).await?;
-            let changeset = GridBlockMetaChangeset::from_row_count(&block_order.block_id, row_count);
+            let changeset = GridBlockRevisionChangeset::from_row_count(&block_order.block_id, row_count);
             changesets.push(changeset);
         }
 
@@ -164,10 +166,10 @@ impl GridBlockManager {
         let editor = self.get_editor_from_row_id(row_id).await?;
         let _ = editor.move_row(row_id, from, to).await?;
 
-        match editor.get_row_metas(Some(vec![Cow::Borrowed(row_id)])).await?.pop() {
+        match editor.get_row_revs(Some(vec![Cow::Borrowed(row_id)])).await?.pop() {
             None => {}
-            Some(row_meta) => {
-                let row_order = RowOrder::from(&row_meta);
+            Some(row_rev) => {
+                let row_order = RowOrder::from(&row_rev);
                 let insert_row = IndexRowOrder {
                     row_order: row_order.clone(),
                     index: Some(to as i32),
@@ -188,7 +190,7 @@ impl GridBlockManager {
 
     pub async fn update_cell<F>(&self, changeset: CellChangeset, row_builder: F) -> FlowyResult<()>
     where
-        F: FnOnce(Arc<RowMeta>) -> Option<Row>,
+        F: FnOnce(Arc<RowRevision>) -> Option<Row>,
     {
         let row_changeset: RowMetaChangeset = changeset.clone().into();
         let _ = self.update_row(row_changeset, row_builder).await?;
@@ -196,14 +198,14 @@ impl GridBlockManager {
         Ok(())
     }
 
-    pub async fn get_row_meta(&self, row_id: &str) -> FlowyResult<Option<Arc<RowMeta>>> {
+    pub async fn get_row_rev(&self, row_id: &str) -> FlowyResult<Option<Arc<RowRevision>>> {
         let editor = self.get_editor_from_row_id(row_id).await?;
         let row_ids = vec![Cow::Borrowed(row_id)];
-        let mut row_metas = editor.get_row_metas(Some(row_ids)).await?;
-        if row_metas.is_empty() {
+        let mut row_revs = editor.get_row_revs(Some(row_ids)).await?;
+        if row_revs.is_empty() {
             Ok(None)
         } else {
-            Ok(row_metas.pop())
+            Ok(row_revs.pop())
         }
     }
 
@@ -216,27 +218,27 @@ impl GridBlockManager {
         let mut snapshots = vec![];
         for block_id in block_ids {
             let editor = self.get_editor(&block_id).await?;
-            let row_metas = editor.get_row_metas::<&str>(None).await?;
-            snapshots.push(GridBlockSnapshot { block_id, row_metas });
+            let row_revs = editor.get_row_revs::<&str>(None).await?;
+            snapshots.push(GridBlockSnapshot { block_id, row_revs });
         }
         Ok(snapshots)
     }
 
     // Optimization: Using the shared memory(Arc, Cow,etc.) to reduce memory usage.
     #[allow(dead_code)]
-    pub async fn get_cell_metas(
+    pub async fn get_cell_revs(
         &self,
         block_ids: Vec<String>,
         field_id: &str,
         row_ids: Option<Vec<Cow<'_, String>>>,
-    ) -> FlowyResult<Vec<CellMeta>> {
-        let mut block_cell_metas = vec![];
+    ) -> FlowyResult<Vec<CellRevision>> {
+        let mut block_cell_revs = vec![];
         for block_id in block_ids {
             let editor = self.get_editor(&block_id).await?;
-            let cell_metas = editor.get_cell_metas(field_id, row_ids.clone()).await?;
-            block_cell_metas.extend(cell_metas);
+            let cell_revs = editor.get_cell_revs(field_id, row_ids.clone()).await?;
+            block_cell_revs.extend(cell_revs);
         }
-        Ok(block_cell_metas)
+        Ok(block_cell_revs)
     }
 
     async fn notify_did_update_block(&self, changeset: GridRowsChangeset) -> FlowyResult<()> {
@@ -255,8 +257,8 @@ impl GridBlockManager {
 
 async fn make_block_meta_editor_map(
     user: &Arc<dyn GridUser>,
-    blocks: Vec<GridBlockMeta>,
-) -> FlowyResult<DashMap<String, Arc<GridBlockMetaEditor>>> {
+    blocks: Vec<GridBlockRevision>,
+) -> FlowyResult<DashMap<String, Arc<GridBlockRevisionEditor>>> {
     let editor_map = DashMap::new();
     for block in blocks {
         let editor = make_block_meta_editor(user, &block.block_id).await?;
@@ -266,7 +268,7 @@ async fn make_block_meta_editor_map(
     Ok(editor_map)
 }
 
-async fn make_block_meta_editor(user: &Arc<dyn GridUser>, block_id: &str) -> FlowyResult<GridBlockMetaEditor> {
+async fn make_block_meta_editor(user: &Arc<dyn GridUser>, block_id: &str) -> FlowyResult<GridBlockRevisionEditor> {
     tracing::trace!("Open block:{} meta editor", block_id);
     let token = user.token()?;
     let user_id = user.user_id()?;
@@ -275,5 +277,5 @@ async fn make_block_meta_editor(user: &Arc<dyn GridUser>, block_id: &str) -> Flo
     let disk_cache = Arc::new(SQLiteGridBlockMetaRevisionPersistence::new(&user_id, pool));
     let rev_persistence = Arc::new(RevisionPersistence::new(&user_id, block_id, disk_cache));
     let rev_manager = RevisionManager::new(&user_id, block_id, rev_persistence);
-    GridBlockMetaEditor::new(&user_id, &token, block_id, rev_manager).await
+    GridBlockRevisionEditor::new(&user_id, &token, block_id, rev_manager).await
 }

+ 23 - 22
frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs → frontend/rust-lib/flowy-grid/src/services/block_revision_editor.rs

@@ -1,8 +1,9 @@
 use bytes::Bytes;
 use flowy_error::{FlowyError, FlowyResult};
-use flowy_grid_data_model::entities::{CellMeta, GridBlockMetaData, RowMeta, RowMetaChangeset, RowOrder};
+use flowy_grid_data_model::entities::RowOrder;
+use flowy_grid_data_model::revision::{CellRevision, GridBlockRevisionData, RowMetaChangeset, RowRevision};
 use flowy_revision::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder};
-use flowy_sync::client_grid::{GridBlockMetaChange, GridBlockMetaPad};
+use flowy_sync::client_grid::{GridBlockMetaChange, GridBlockRevisionPad};
 use flowy_sync::entities::revision::Revision;
 use flowy_sync::util::make_delta_from_revisions;
 use lib_infra::future::FutureResult;
@@ -11,14 +12,14 @@ use std::borrow::Cow;
 use std::sync::Arc;
 use tokio::sync::RwLock;
 
-pub struct GridBlockMetaEditor {
+pub struct GridBlockRevisionEditor {
     user_id: String,
     pub block_id: String,
-    pad: Arc<RwLock<GridBlockMetaPad>>,
+    pad: Arc<RwLock<GridBlockRevisionPad>>,
     rev_manager: Arc<RevisionManager>,
 }
 
-impl GridBlockMetaEditor {
+impl GridBlockRevisionEditor {
     pub async fn new(
         user_id: &str,
         token: &str,
@@ -41,14 +42,14 @@ impl GridBlockMetaEditor {
         })
     }
 
-    pub async fn duplicate_block_meta_data(&self, duplicated_block_id: &str) -> GridBlockMetaData {
+    pub async fn duplicate_block_meta_data(&self, duplicated_block_id: &str) -> GridBlockRevisionData {
         self.pad.read().await.duplicate_data(duplicated_block_id).await
     }
 
     /// return current number of rows and the inserted index. The inserted index will be None if the start_row_id is None
     pub(crate) async fn create_row(
         &self,
-        row: RowMeta,
+        row: RowRevision,
         start_row_id: Option<String>,
     ) -> FlowyResult<(i32, Option<i32>)> {
         let mut row_count = 0;
@@ -62,7 +63,7 @@ impl GridBlockMetaEditor {
                     }
                 }
 
-                let change = block_pad.add_row_meta(row, start_row_id)?;
+                let change = block_pad.add_row_rev(row, start_row_id)?;
                 row_count = block_pad.number_of_rows();
 
                 if row_index.is_none() {
@@ -99,27 +100,27 @@ impl GridBlockMetaEditor {
         Ok(())
     }
 
-    pub async fn get_row_meta(&self, row_id: &str) -> FlowyResult<Option<Arc<RowMeta>>> {
+    pub async fn get_row_rev(&self, row_id: &str) -> FlowyResult<Option<Arc<RowRevision>>> {
         let row_ids = vec![Cow::Borrowed(row_id)];
-        let row_meta = self.get_row_metas(Some(row_ids)).await?.pop();
-        Ok(row_meta)
+        let row_rev = self.get_row_revs(Some(row_ids)).await?.pop();
+        Ok(row_rev)
     }
 
-    pub async fn get_row_metas<T>(&self, row_ids: Option<Vec<Cow<'_, T>>>) -> FlowyResult<Vec<Arc<RowMeta>>>
+    pub async fn get_row_revs<T>(&self, row_ids: Option<Vec<Cow<'_, T>>>) -> FlowyResult<Vec<Arc<RowRevision>>>
     where
         T: AsRef<str> + ToOwned + ?Sized,
     {
-        let row_metas = self.pad.read().await.get_row_metas(row_ids)?;
-        Ok(row_metas)
+        let row_revs = self.pad.read().await.get_row_revs(row_ids)?;
+        Ok(row_revs)
     }
 
-    pub async fn get_cell_metas(
+    pub async fn get_cell_revs(
         &self,
         field_id: &str,
         row_ids: Option<Vec<Cow<'_, String>>>,
-    ) -> FlowyResult<Vec<CellMeta>> {
-        let cell_metas = self.pad.read().await.get_cell_metas(field_id, row_ids)?;
-        Ok(cell_metas)
+    ) -> FlowyResult<Vec<CellRevision>> {
+        let cell_revs = self.pad.read().await.get_cell_revs(field_id, row_ids)?;
+        Ok(cell_revs)
     }
 
     pub async fn get_row_order(&self, row_id: &str) -> FlowyResult<Option<RowOrder>> {
@@ -135,7 +136,7 @@ impl GridBlockMetaEditor {
             .pad
             .read()
             .await
-            .get_row_metas(row_ids)?
+            .get_row_revs(row_ids)?
             .iter()
             .map(RowOrder::from)
             .collect::<Vec<RowOrder>>();
@@ -144,7 +145,7 @@ impl GridBlockMetaEditor {
 
     async fn modify<F>(&self, f: F) -> FlowyResult<()>
     where
-        F: for<'a> FnOnce(&'a mut GridBlockMetaPad) -> FlowyResult<Option<GridBlockMetaChange>>,
+        F: for<'a> FnOnce(&'a mut GridBlockRevisionPad) -> FlowyResult<Option<GridBlockMetaChange>>,
     {
         let mut write_guard = self.pad.write().await;
         match f(&mut *write_guard)? {
@@ -191,10 +192,10 @@ impl RevisionCloudService for GridBlockMetaRevisionCloudService {
 
 struct GridBlockMetaPadBuilder();
 impl RevisionObjectBuilder for GridBlockMetaPadBuilder {
-    type Output = GridBlockMetaPad;
+    type Output = GridBlockRevisionPad;
 
     fn build_object(object_id: &str, revisions: Vec<Revision>) -> FlowyResult<Self::Output> {
-        let pad = GridBlockMetaPad::from_revisions(object_id, revisions)?;
+        let pad = GridBlockRevisionPad::from_revisions(object_id, revisions)?;
         Ok(pad)
     }
 }

+ 18 - 17
frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs

@@ -1,10 +1,11 @@
 use crate::services::field::type_options::*;
 use bytes::Bytes;
-use flowy_grid_data_model::entities::{Field, FieldMeta, FieldType, TypeOptionDataEntry};
+use flowy_grid_data_model::entities::{Field, FieldType};
+use flowy_grid_data_model::revision::{FieldRevision, TypeOptionDataEntry};
 use indexmap::IndexMap;
 
 pub struct FieldBuilder {
-    field_meta: FieldMeta,
+    field_rev: FieldRevision,
     type_option_builder: Box<dyn TypeOptionBuilder>,
 }
 
@@ -13,9 +14,9 @@ pub type BoxTypeOptionBuilder = Box<dyn TypeOptionBuilder + 'static>;
 impl FieldBuilder {
     pub fn new<T: Into<BoxTypeOptionBuilder>>(type_option_builder: T) -> Self {
         let type_option_builder = type_option_builder.into();
-        let field_meta = FieldMeta::new("", "", type_option_builder.field_type(), false);
+        let field_rev = FieldRevision::new("", "", type_option_builder.field_type(), false);
         Self {
-            field_meta,
+            field_rev,
             type_option_builder,
         }
     }
@@ -26,7 +27,7 @@ impl FieldBuilder {
     }
 
     pub fn from_field(field: Field, type_option_builder: Box<dyn TypeOptionBuilder>) -> Self {
-        let field_meta = FieldMeta {
+        let field_rev = FieldRevision {
             id: field.id,
             name: field.name,
             desc: field.desc,
@@ -38,46 +39,46 @@ impl FieldBuilder {
             is_primary: field.is_primary,
         };
         Self {
-            field_meta,
+            field_rev,
             type_option_builder,
         }
     }
 
     pub fn name(mut self, name: &str) -> Self {
-        self.field_meta.name = name.to_owned();
+        self.field_rev.name = name.to_owned();
         self
     }
 
     pub fn desc(mut self, desc: &str) -> Self {
-        self.field_meta.desc = desc.to_owned();
+        self.field_rev.desc = desc.to_owned();
         self
     }
 
     pub fn primary(mut self, is_primary: bool) -> Self {
-        self.field_meta.is_primary = is_primary;
+        self.field_rev.is_primary = is_primary;
         self
     }
 
     pub fn visibility(mut self, visibility: bool) -> Self {
-        self.field_meta.visibility = visibility;
+        self.field_rev.visibility = visibility;
         self
     }
 
     pub fn width(mut self, width: i32) -> Self {
-        self.field_meta.width = width;
+        self.field_rev.width = width;
         self
     }
 
     pub fn frozen(mut self, frozen: bool) -> Self {
-        self.field_meta.frozen = frozen;
+        self.field_rev.frozen = frozen;
         self
     }
 
-    pub fn build(self) -> FieldMeta {
-        debug_assert_eq!(self.field_meta.field_type, self.type_option_builder.field_type());
-        let mut field_meta = self.field_meta;
-        field_meta.insert_type_option_entry(self.type_option_builder.entry());
-        field_meta
+    pub fn build(self) -> FieldRevision {
+        debug_assert_eq!(self.field_rev.field_type, self.type_option_builder.field_type());
+        let mut field_rev = self.field_rev;
+        field_rev.insert_type_option_entry(self.type_option_builder.entry());
+        field_rev
     }
 }
 

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

@@ -4,10 +4,8 @@ use crate::services::row::{CellContentChangeset, CellDataOperation, DecodedCellD
 use bytes::Bytes;
 use flowy_derive::ProtoBuf;
 use flowy_error::{FlowyError, FlowyResult};
-use flowy_grid_data_model::entities::{
-    CellMeta, FieldMeta, FieldType, TypeOptionDataDeserializer, TypeOptionDataEntry,
-};
-
+use flowy_grid_data_model::entities::FieldType;
+use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry};
 use serde::{Deserialize, Serialize};
 
 #[derive(Default)]
@@ -47,7 +45,7 @@ impl CellDataOperation<String> for CheckboxTypeOption {
         &self,
         encoded_data: T,
         decoded_field_type: &FieldType,
-        _field_meta: &FieldMeta,
+        field_rev: &FieldRevision,
     ) -> FlowyResult<DecodedCellData>
     where
         T: Into<String>,
@@ -64,7 +62,7 @@ impl CellDataOperation<String> for CheckboxTypeOption {
         Ok(DecodedCellData::default())
     }
 
-    fn apply_changeset<C>(&self, changeset: C, _cell_meta: Option<CellMeta>) -> Result<String, FlowyError>
+    fn apply_changeset<C>(&self, changeset: C, _cell_rev: Option<CellRevision>) -> Result<String, FlowyError>
     where
         C: Into<CellContentChangeset>,
     {
@@ -101,40 +99,40 @@ mod tests {
 
     #[test]
     fn checkout_box_description_test() {
-        let field_meta = FieldBuilder::from_field_type(&FieldType::Checkbox).build();
-        let data = apply_cell_data_changeset("true", None, &field_meta).unwrap();
+        let field_rev = FieldBuilder::from_field_type(&FieldType::Checkbox).build();
+        let data = apply_cell_data_changeset("true", None, &field_rev).unwrap();
         assert_eq!(
-            decode_cell_data_from_type_option_cell_data(data, &field_meta, &field_meta.field_type).to_string(),
+            decode_cell_data_from_type_option_cell_data(data, &field_rev, &field_rev.field_type).to_string(),
             YES
         );
 
-        let data = apply_cell_data_changeset("1", None, &field_meta).unwrap();
+        let data = apply_cell_data_changeset("1", None, &field_rev).unwrap();
         assert_eq!(
-            decode_cell_data_from_type_option_cell_data(data, &field_meta, &field_meta.field_type).to_string(),
+            decode_cell_data_from_type_option_cell_data(data, &field_rev, &field_rev.field_type).to_string(),
             YES
         );
 
-        let data = apply_cell_data_changeset("yes", None, &field_meta).unwrap();
+        let data = apply_cell_data_changeset("yes", None, &field_rev).unwrap();
         assert_eq!(
-            decode_cell_data_from_type_option_cell_data(data, &field_meta, &field_meta.field_type).to_string(),
+            decode_cell_data_from_type_option_cell_data(data, &field_rev, &field_rev.field_type).to_string(),
             YES
         );
 
-        let data = apply_cell_data_changeset("false", None, &field_meta).unwrap();
+        let data = apply_cell_data_changeset("false", None, &field_rev).unwrap();
         assert_eq!(
-            decode_cell_data_from_type_option_cell_data(data, &field_meta, &field_meta.field_type).to_string(),
+            decode_cell_data_from_type_option_cell_data(data, &field_rev, &field_rev.field_type).to_string(),
             NO
         );
 
-        let data = apply_cell_data_changeset("no", None, &field_meta).unwrap();
+        let data = apply_cell_data_changeset("no", None, &field_rev).unwrap();
         assert_eq!(
-            decode_cell_data_from_type_option_cell_data(data, &field_meta, &field_meta.field_type).to_string(),
+            decode_cell_data_from_type_option_cell_data(data, &field_rev, &field_rev.field_type).to_string(),
             NO
         );
 
-        let data = apply_cell_data_changeset("12", None, &field_meta).unwrap();
+        let data = apply_cell_data_changeset("12", None, &field_rev).unwrap();
         assert_eq!(
-            decode_cell_data_from_type_option_cell_data(data, &field_meta, &field_meta.field_type).to_string(),
+            decode_cell_data_from_type_option_cell_data(data, &field_rev, &field_rev.field_type).to_string(),
             NO
         );
     }

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

@@ -7,9 +7,8 @@ use chrono::format::strftime::StrftimeItems;
 use chrono::{NaiveDateTime, Timelike};
 use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
 use flowy_error::{ErrorCode, FlowyError, FlowyResult};
-use flowy_grid_data_model::entities::{
-    CellChangeset, CellMeta, FieldMeta, FieldType, TypeOptionDataDeserializer, TypeOptionDataEntry,
-};
+use flowy_grid_data_model::entities::{CellChangeset, FieldType};
+use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry};
 use serde::{Deserialize, Serialize};
 use strum_macros::EnumIter;
 
@@ -121,7 +120,7 @@ impl CellDataOperation<String> for DateTypeOption {
         &self,
         encoded_data: T,
         decoded_field_type: &FieldType,
-        _field_meta: &FieldMeta,
+        field_rev: &FieldRevision,
     ) -> FlowyResult<DecodedCellData>
     where
         T: Into<String>,
@@ -139,7 +138,7 @@ impl CellDataOperation<String> for DateTypeOption {
         DecodedCellData::try_from_bytes(date)
     }
 
-    fn apply_changeset<C>(&self, changeset: C, _cell_meta: Option<CellMeta>) -> Result<String, FlowyError>
+    fn apply_changeset<C>(&self, changeset: C, _cell_rev: Option<CellRevision>) -> Result<String, FlowyError>
     where
         C: Into<CellContentChangeset>,
     {
@@ -358,14 +357,15 @@ mod tests {
     use crate::services::field::FieldBuilder;
     use crate::services::field::{DateCellContentChangeset, DateCellData, DateFormat, DateTypeOption, TimeFormat};
     use crate::services::row::CellDataOperation;
-    use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntry};
+    use flowy_grid_data_model::entities::FieldType;
+    use flowy_grid_data_model::revision::{FieldRevision, TypeOptionDataEntry};
     use strum::IntoEnumIterator;
 
     #[test]
     fn date_type_option_invalid_input_test() {
         let type_option = DateTypeOption::default();
         let field_type = FieldType::DateTime;
-        let field_meta = FieldBuilder::from_field_type(&field_type).build();
+        let field_rev = FieldBuilder::from_field_type(&field_type).build();
         assert_changeset_result(
             &type_option,
             DateCellContentChangeset {
@@ -373,7 +373,7 @@ mod tests {
                 time: Some("23:00".to_owned()),
             },
             &field_type,
-            &field_meta,
+            &field_rev,
             "",
         );
     }
@@ -381,21 +381,21 @@ mod tests {
     #[test]
     fn date_type_option_date_format_test() {
         let mut type_option = DateTypeOption::default();
-        let field_meta = FieldBuilder::from_field_type(&FieldType::DateTime).build();
+        let field_rev = FieldBuilder::from_field_type(&FieldType::DateTime).build();
         for date_format in DateFormat::iter() {
             type_option.date_format = date_format;
             match date_format {
                 DateFormat::Friendly => {
-                    assert_decode_timestamp(1647251762, &type_option, &field_meta, "Mar 14,2022");
+                    assert_decode_timestamp(1647251762, &type_option, &field_rev, "Mar 14,2022");
                 }
                 DateFormat::US => {
-                    assert_decode_timestamp(1647251762, &type_option, &field_meta, "2022/03/14");
+                    assert_decode_timestamp(1647251762, &type_option, &field_rev, "2022/03/14");
                 }
                 DateFormat::ISO => {
-                    assert_decode_timestamp(1647251762, &type_option, &field_meta, "2022-03-14");
+                    assert_decode_timestamp(1647251762, &type_option, &field_rev, "2022-03-14");
                 }
                 DateFormat::Local => {
-                    assert_decode_timestamp(1647251762, &type_option, &field_meta, "2022/03/14");
+                    assert_decode_timestamp(1647251762, &type_option, &field_rev, "2022/03/14");
                 }
             }
         }
@@ -405,7 +405,7 @@ mod tests {
     fn date_type_option_time_format_test() {
         let mut type_option = DateTypeOption::default();
         let field_type = FieldType::DateTime;
-        let field_meta = FieldBuilder::from_field_type(&field_type).build();
+        let field_rev = FieldBuilder::from_field_type(&field_type).build();
 
         for time_format in TimeFormat::iter() {
             type_option.time_format = time_format;
@@ -419,7 +419,7 @@ mod tests {
                             time: None,
                         },
                         &field_type,
-                        &field_meta,
+                        &field_rev,
                         "May 27,2022",
                     );
                     assert_changeset_result(
@@ -429,7 +429,7 @@ mod tests {
                             time: Some("23:00".to_owned()),
                         },
                         &field_type,
-                        &field_meta,
+                        &field_rev,
                         "May 27,2022 23:00",
                     );
                 }
@@ -441,7 +441,7 @@ mod tests {
                             time: None,
                         },
                         &field_type,
-                        &field_meta,
+                        &field_rev,
                         "May 27,2022",
                     );
                     //
@@ -452,7 +452,7 @@ mod tests {
                             time: Some("".to_owned()),
                         },
                         &field_type,
-                        &field_meta,
+                        &field_rev,
                         "May 27,2022",
                     );
 
@@ -463,7 +463,7 @@ mod tests {
                             time: Some("11:23 pm".to_owned()),
                         },
                         &field_type,
-                        &field_meta,
+                        &field_rev,
                         "May 27,2022 11:23 PM",
                     );
                 }
@@ -475,7 +475,7 @@ mod tests {
     fn date_type_option_apply_changeset_test() {
         let mut type_option = DateTypeOption::new();
         let field_type = FieldType::DateTime;
-        let field_meta = FieldBuilder::from_field_type(&field_type).build();
+        let field_rev = FieldBuilder::from_field_type(&field_type).build();
         let date_timestamp = "1653609600".to_owned();
 
         assert_changeset_result(
@@ -485,7 +485,7 @@ mod tests {
                 time: None,
             },
             &field_type,
-            &field_meta,
+            &field_rev,
             "May 27,2022",
         );
 
@@ -497,7 +497,7 @@ mod tests {
                 time: None,
             },
             &field_type,
-            &field_meta,
+            &field_rev,
             "May 27,2022",
         );
 
@@ -508,7 +508,7 @@ mod tests {
                 time: Some("1:00".to_owned()),
             },
             &field_type,
-            &field_meta,
+            &field_rev,
             "May 27,2022 01:00",
         );
 
@@ -520,7 +520,7 @@ mod tests {
                 time: Some("1:00 am".to_owned()),
             },
             &field_type,
-            &field_meta,
+            &field_rev,
             "May 27,2022 01:00 AM",
         );
     }
@@ -530,7 +530,7 @@ mod tests {
     fn date_type_option_apply_changeset_error_test() {
         let mut type_option = DateTypeOption::new();
         type_option.include_time = true;
-        let field_meta = FieldBuilder::from_field_type(&type_option.field_type()).build();
+        let field_rev = FieldBuilder::from_field_type(&type_option.field_type()).build();
         let date_timestamp = "1653609600".to_owned();
 
         assert_changeset_result(
@@ -540,7 +540,7 @@ mod tests {
                 time: Some("1:".to_owned()),
             },
             &type_option.field_type(),
-            &field_meta,
+            &field_rev,
             "May 27,2022 01:00",
         );
 
@@ -551,7 +551,7 @@ mod tests {
                 time: Some("1:00".to_owned()),
             },
             &type_option.field_type(),
-            &field_meta,
+            &field_rev,
             "May 27,2022 01:00",
         );
     }
@@ -561,7 +561,7 @@ mod tests {
     fn date_type_option_twelve_hours_to_twenty_four_hours() {
         let mut type_option = DateTypeOption::new();
         type_option.include_time = true;
-        let field_meta = FieldBuilder::from_field_type(&type_option.field_type()).build();
+        let field_rev = FieldBuilder::from_field_type(&type_option.field_type()).build();
         let date_timestamp = "1653609600".to_owned();
 
         assert_changeset_result(
@@ -571,7 +571,7 @@ mod tests {
                 time: Some("1:00 am".to_owned()),
             },
             &type_option.field_type(),
-            &field_meta,
+            &field_rev,
             "May 27,2022 01:00",
         );
     }
@@ -580,17 +580,22 @@ mod tests {
         type_option: &DateTypeOption,
         changeset: DateCellContentChangeset,
         _field_type: &FieldType,
-        field_meta: &FieldMeta,
+        field_rev: &FieldRevision,
         expected: &str,
     ) {
         let encoded_data = type_option.apply_changeset(changeset, None).unwrap();
         assert_eq!(
             expected.to_owned(),
-            decode_cell_data(encoded_data, type_option, field_meta)
+            decode_cell_data(encoded_data, type_option, field_rev)
         );
     }
 
-    fn assert_decode_timestamp(timestamp: i64, type_option: &DateTypeOption, field_meta: &FieldMeta, expected: &str) {
+    fn assert_decode_timestamp(
+        timestamp: i64,
+        type_option: &DateTypeOption,
+        field_rev: &FieldRevision,
+        expected: &str,
+    ) {
         let encoded_data = type_option
             .apply_changeset(
                 DateCellContentChangeset {
@@ -603,17 +608,17 @@ mod tests {
 
         assert_eq!(
             expected.to_owned(),
-            decode_cell_data(encoded_data, type_option, field_meta)
+            decode_cell_data(encoded_data, type_option, field_rev)
         );
     }
 
     fn decode_cell_data<T: Into<String>>(
         encoded_data: T,
         type_option: &DateTypeOption,
-        field_meta: &FieldMeta,
+        field_rev: &FieldRevision,
     ) -> String {
         let decoded_data = type_option
-            .decode_cell_data(encoded_data, &FieldType::DateTime, field_meta)
+            .decode_cell_data(encoded_data, &FieldType::DateTime, field_rev)
             .unwrap()
             .parse::<DateCellData>()
             .unwrap();

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

@@ -6,11 +6,9 @@ use crate::services::row::{CellContentChangeset, CellDataOperation, DecodedCellD
 use bytes::Bytes;
 use flowy_derive::ProtoBuf;
 use flowy_error::{FlowyError, FlowyResult};
-use flowy_grid_data_model::entities::{
-    CellMeta, FieldMeta, FieldType, TypeOptionDataDeserializer, TypeOptionDataEntry,
-};
+use flowy_grid_data_model::entities::FieldType;
+use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry};
 use rust_decimal::Decimal;
-
 use serde::{Deserialize, Serialize};
 use std::str::FromStr;
 
@@ -146,7 +144,7 @@ impl CellDataOperation<String> for NumberTypeOption {
         &self,
         encoded_data: T,
         decoded_field_type: &FieldType,
-        _field_meta: &FieldMeta,
+        field_rev: &FieldRevision,
     ) -> FlowyResult<DecodedCellData>
     where
         T: Into<String>,
@@ -181,7 +179,7 @@ impl CellDataOperation<String> for NumberTypeOption {
         }
     }
 
-    fn apply_changeset<C>(&self, changeset: C, _cell_meta: Option<CellMeta>) -> Result<String, FlowyError>
+    fn apply_changeset<C>(&self, changeset: C, _cell_rev: Option<CellRevision>) -> Result<String, FlowyError>
     where
         C: Into<CellContentChangeset>,
     {
@@ -211,16 +209,17 @@ mod tests {
     use crate::services::field::FieldBuilder;
     use crate::services::field::{NumberFormat, NumberTypeOption};
     use crate::services::row::CellDataOperation;
-    use flowy_grid_data_model::entities::{FieldMeta, FieldType};
+    use flowy_grid_data_model::entities::FieldType;
+    use flowy_grid_data_model::revision::FieldRevision;
     use strum::IntoEnumIterator;
 
     #[test]
     fn number_type_option_invalid_input_test() {
         let type_option = NumberTypeOption::default();
         let field_type = FieldType::Number;
-        let field_meta = FieldBuilder::from_field_type(&field_type).build();
-        assert_equal(&type_option, "", "", &field_type, &field_meta);
-        assert_equal(&type_option, "abc", "", &field_type, &field_meta);
+        let field_rev = FieldBuilder::from_field_type(&field_type).build();
+        assert_equal(&type_option, "", "", &field_type, &field_rev);
+        assert_equal(&type_option, "abc", "", &field_type, &field_rev);
     }
 
     #[test]
@@ -237,25 +236,25 @@ mod tests {
     fn number_type_option_format_number_test() {
         let mut type_option = NumberTypeOption::default();
         let field_type = FieldType::Number;
-        let field_meta = FieldBuilder::from_field_type(&field_type).build();
+        let field_rev = FieldBuilder::from_field_type(&field_type).build();
 
         for format in NumberFormat::iter() {
             type_option.format = format;
             match format {
                 NumberFormat::Number => {
-                    assert_equal(&type_option, "18443", "18443", &field_type, &field_meta);
+                    assert_equal(&type_option, "18443", "18443", &field_type, &field_rev);
                 }
                 NumberFormat::USD => {
-                    assert_equal(&type_option, "18443", "$18,443", &field_type, &field_meta);
+                    assert_equal(&type_option, "18443", "$18,443", &field_type, &field_rev);
                 }
                 NumberFormat::Yen => {
-                    assert_equal(&type_option, "18443", "¥18,443", &field_type, &field_meta);
+                    assert_equal(&type_option, "18443", "¥18,443", &field_type, &field_rev);
                 }
                 NumberFormat::Yuan => {
-                    assert_equal(&type_option, "18443", "CN¥18,443", &field_type, &field_meta);
+                    assert_equal(&type_option, "18443", "CN¥18,443", &field_type, &field_rev);
                 }
                 NumberFormat::EUR => {
-                    assert_equal(&type_option, "18443", "€18.443", &field_type, &field_meta);
+                    assert_equal(&type_option, "18443", "€18.443", &field_type, &field_rev);
                 }
                 _ => {}
             }
@@ -266,33 +265,33 @@ mod tests {
     fn number_type_option_format_str_test() {
         let mut type_option = NumberTypeOption::default();
         let field_type = FieldType::Number;
-        let field_meta = FieldBuilder::from_field_type(&field_type).build();
+        let field_rev = FieldBuilder::from_field_type(&field_type).build();
 
         for format in NumberFormat::iter() {
             type_option.format = format;
             match format {
                 NumberFormat::Number => {
-                    assert_equal(&type_option, "18443", "18443", &field_type, &field_meta);
-                    assert_equal(&type_option, "0.2", "0.2", &field_type, &field_meta);
+                    assert_equal(&type_option, "18443", "18443", &field_type, &field_rev);
+                    assert_equal(&type_option, "0.2", "0.2", &field_type, &field_rev);
                 }
                 NumberFormat::USD => {
-                    assert_equal(&type_option, "$18,44", "$1,844", &field_type, &field_meta);
-                    assert_equal(&type_option, "$0.2", "$0.2", &field_type, &field_meta);
-                    assert_equal(&type_option, "", "", &field_type, &field_meta);
-                    assert_equal(&type_option, "abc", "", &field_type, &field_meta);
+                    assert_equal(&type_option, "$18,44", "$1,844", &field_type, &field_rev);
+                    assert_equal(&type_option, "$0.2", "$0.2", &field_type, &field_rev);
+                    assert_equal(&type_option, "", "", &field_type, &field_rev);
+                    assert_equal(&type_option, "abc", "", &field_type, &field_rev);
                 }
                 NumberFormat::Yen => {
-                    assert_equal(&type_option, "¥18,44", "¥1,844", &field_type, &field_meta);
-                    assert_equal(&type_option, "¥1844", "¥1,844", &field_type, &field_meta);
+                    assert_equal(&type_option, "¥18,44", "¥1,844", &field_type, &field_rev);
+                    assert_equal(&type_option, "¥1844", "¥1,844", &field_type, &field_rev);
                 }
                 NumberFormat::Yuan => {
-                    assert_equal(&type_option, "CN¥18,44", "CN¥1,844", &field_type, &field_meta);
-                    assert_equal(&type_option, "CN¥1844", "CN¥1,844", &field_type, &field_meta);
+                    assert_equal(&type_option, "CN¥18,44", "CN¥1,844", &field_type, &field_rev);
+                    assert_equal(&type_option, "CN¥1844", "CN¥1,844", &field_type, &field_rev);
                 }
                 NumberFormat::EUR => {
-                    assert_equal(&type_option, "€18.44", "€18,44", &field_type, &field_meta);
-                    assert_equal(&type_option, "€0.5", "€0,5", &field_type, &field_meta);
-                    assert_equal(&type_option, "€1844", "€1.844", &field_type, &field_meta);
+                    assert_equal(&type_option, "€18.44", "€18,44", &field_type, &field_rev);
+                    assert_equal(&type_option, "€0.5", "€0,5", &field_type, &field_rev);
+                    assert_equal(&type_option, "€1844", "€1.844", &field_type, &field_rev);
                 }
                 _ => {}
             }
@@ -306,22 +305,22 @@ mod tests {
             ..Default::default()
         };
         let field_type = FieldType::Number;
-        let field_meta = FieldBuilder::from_field_type(&field_type).build();
+        let field_rev = FieldBuilder::from_field_type(&field_type).build();
 
         for format in NumberFormat::iter() {
             type_option.format = format;
             match format {
                 NumberFormat::Number => {
-                    assert_equal(&type_option, "18443", "18443", &field_type, &field_meta);
+                    assert_equal(&type_option, "18443", "18443", &field_type, &field_rev);
                 }
                 NumberFormat::USD => {
-                    assert_equal(&type_option, "18443", "-$18,443", &field_type, &field_meta);
+                    assert_equal(&type_option, "18443", "-$18,443", &field_type, &field_rev);
                 }
                 NumberFormat::Yen => {
-                    assert_equal(&type_option, "18443", "-¥18,443", &field_type, &field_meta);
+                    assert_equal(&type_option, "18443", "-¥18,443", &field_type, &field_rev);
                 }
                 NumberFormat::EUR => {
-                    assert_equal(&type_option, "18443", "-€18.443", &field_type, &field_meta);
+                    assert_equal(&type_option, "18443", "-€18.443", &field_type, &field_rev);
                 }
                 _ => {}
             }
@@ -333,11 +332,11 @@ mod tests {
         cell_data: &str,
         expected_str: &str,
         field_type: &FieldType,
-        field_meta: &FieldMeta,
+        field_rev: &FieldRevision,
     ) {
         assert_eq!(
             type_option
-                .decode_cell_data(cell_data, field_type, field_meta)
+                .decode_cell_data(cell_data, field_type, field_rev)
                 .unwrap()
                 .to_string(),
             expected_str.to_owned()

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

@@ -6,10 +6,9 @@ use crate::services::row::{CellContentChangeset, CellDataOperation, DecodedCellD
 use bytes::Bytes;
 use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
 use flowy_error::{ErrorCode, FlowyError, FlowyResult};
-use flowy_grid_data_model::entities::{
-    CellChangeset, CellMeta, FieldMeta, FieldType, TypeOptionDataDeserializer, TypeOptionDataEntry,
-};
+use flowy_grid_data_model::entities::{CellChangeset, FieldType};
 use flowy_grid_data_model::parser::NotEmptyStr;
+use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry};
 use nanoid::nanoid;
 use serde::{Deserialize, Serialize};
 use std::str::FromStr;
@@ -42,21 +41,21 @@ pub trait SelectOptionOperation: TypeOptionDataEntry + Send + Sync {
         SelectOption::with_color(name, color)
     }
 
-    fn select_option_cell_data(&self, cell_meta: &Option<CellMeta>) -> SelectOptionCellData;
+    fn select_option_cell_data(&self, cell_rev: &Option<CellRevision>) -> SelectOptionCellData;
 
     fn options(&self) -> &Vec<SelectOption>;
 
     fn mut_options(&mut self) -> &mut Vec<SelectOption>;
 }
 
-pub fn select_option_operation(field_meta: &FieldMeta) -> FlowyResult<Box<dyn SelectOptionOperation>> {
-    match &field_meta.field_type {
+pub fn select_option_operation(field_rev: &FieldRevision) -> FlowyResult<Box<dyn SelectOptionOperation>> {
+    match &field_rev.field_type {
         FieldType::SingleSelect => {
-            let type_option = SingleSelectTypeOption::from(field_meta);
+            let type_option = SingleSelectTypeOption::from(field_rev);
             Ok(Box::new(type_option))
         }
         FieldType::MultiSelect => {
-            let type_option = MultiSelectTypeOption::from(field_meta);
+            let type_option = MultiSelectTypeOption::from(field_rev);
             Ok(Box::new(type_option))
         }
         ty => {
@@ -78,8 +77,8 @@ pub struct SingleSelectTypeOption {
 impl_type_option!(SingleSelectTypeOption, FieldType::SingleSelect);
 
 impl SelectOptionOperation for SingleSelectTypeOption {
-    fn select_option_cell_data(&self, cell_meta: &Option<CellMeta>) -> SelectOptionCellData {
-        let select_options = make_select_context_from(cell_meta, &self.options);
+    fn select_option_cell_data(&self, cell_rev: &Option<CellRevision>) -> SelectOptionCellData {
+        let select_options = make_select_context_from(cell_rev, &self.options);
         SelectOptionCellData {
             options: self.options.clone(),
             select_options,
@@ -100,7 +99,7 @@ impl CellDataOperation<String> for SingleSelectTypeOption {
         &self,
         encoded_data: T,
         decoded_field_type: &FieldType,
-        _field_meta: &FieldMeta,
+        field_rev: &FieldRevision,
     ) -> FlowyResult<DecodedCellData>
     where
         T: Into<String>,
@@ -123,7 +122,7 @@ impl CellDataOperation<String> for SingleSelectTypeOption {
         DecodedCellData::try_from_bytes(cell_data)
     }
 
-    fn apply_changeset<C>(&self, changeset: C, _cell_meta: Option<CellMeta>) -> Result<String, FlowyError>
+    fn apply_changeset<C>(&self, changeset: C, _cell_rev: Option<CellRevision>) -> Result<String, FlowyError>
     where
         C: Into<CellContentChangeset>,
     {
@@ -176,8 +175,8 @@ pub struct MultiSelectTypeOption {
 impl_type_option!(MultiSelectTypeOption, FieldType::MultiSelect);
 
 impl SelectOptionOperation for MultiSelectTypeOption {
-    fn select_option_cell_data(&self, cell_meta: &Option<CellMeta>) -> SelectOptionCellData {
-        let select_options = make_select_context_from(cell_meta, &self.options);
+    fn select_option_cell_data(&self, cell_rev: &Option<CellRevision>) -> SelectOptionCellData {
+        let select_options = make_select_context_from(cell_rev, &self.options);
         SelectOptionCellData {
             options: self.options.clone(),
             select_options,
@@ -198,7 +197,7 @@ impl CellDataOperation<String> for MultiSelectTypeOption {
         &self,
         encoded_data: T,
         decoded_field_type: &FieldType,
-        _field_meta: &FieldMeta,
+        field_rev: &FieldRevision,
     ) -> FlowyResult<DecodedCellData>
     where
         T: Into<String>,
@@ -221,18 +220,18 @@ impl CellDataOperation<String> for MultiSelectTypeOption {
         DecodedCellData::try_from_bytes(cell_data)
     }
 
-    fn apply_changeset<T>(&self, changeset: T, cell_meta: Option<CellMeta>) -> Result<String, FlowyError>
+    fn apply_changeset<T>(&self, changeset: T, cell_rev: Option<CellRevision>) -> Result<String, FlowyError>
     where
         T: Into<CellContentChangeset>,
     {
         let content_changeset: SelectOptionCellContentChangeset = serde_json::from_str(&changeset.into())?;
         let new_cell_data: String;
-        match cell_meta {
+        match cell_rev {
             None => {
                 new_cell_data = content_changeset.insert_option_id.unwrap_or_else(|| "".to_owned());
             }
-            Some(cell_meta) => {
-                let cell_data = get_cell_data(&cell_meta);
+            Some(cell_rev) => {
+                let cell_data = get_cell_data(&cell_rev);
                 let mut selected_options = select_option_ids(cell_data);
                 if let Some(insert_option_id) = content_changeset.insert_option_id {
                     tracing::trace!("Insert multi select option: {}", &insert_option_id);
@@ -485,11 +484,11 @@ impl std::default::Default for SelectOptionColor {
     }
 }
 
-fn make_select_context_from(cell_meta: &Option<CellMeta>, options: &[SelectOption]) -> Vec<SelectOption> {
-    match cell_meta {
+fn make_select_context_from(cell_rev: &Option<CellRevision>, options: &[SelectOption]) -> Vec<SelectOption> {
+    match cell_rev {
         None => vec![],
-        Some(cell_meta) => {
-            if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&cell_meta.data) {
+        Some(cell_rev) => {
+            if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&cell_rev.data) {
                 select_option_ids(type_option_cell_data.data)
                     .into_iter()
                     .flat_map(|option_id| options.iter().find(|option| option.id == option_id).cloned())
@@ -509,7 +508,7 @@ mod tests {
         SelectOptionCellData, SingleSelectTypeOption, SingleSelectTypeOptionBuilder, SELECTION_IDS_SEPARATOR,
     };
     use crate::services::row::CellDataOperation;
-    use flowy_grid_data_model::entities::FieldMeta;
+    use flowy_grid_data_model::revision::FieldRevision;
 
     #[test]
     fn single_select_test() {
@@ -521,34 +520,34 @@ mod tests {
             .option(facebook_option.clone())
             .option(twitter_option);
 
-        let field_meta = FieldBuilder::new(single_select)
+        let field_rev = FieldBuilder::new(single_select)
             .name("Platform")
             .visibility(true)
             .build();
 
-        let type_option = SingleSelectTypeOption::from(&field_meta);
+        let type_option = SingleSelectTypeOption::from(&field_rev);
 
         let option_ids = vec![google_option.id.clone(), facebook_option.id].join(SELECTION_IDS_SEPARATOR);
         let data = SelectOptionCellContentChangeset::from_insert(&option_ids).to_str();
         let cell_data = type_option.apply_changeset(data, None).unwrap();
-        assert_single_select_options(cell_data, &type_option, &field_meta, vec![google_option.clone()]);
+        assert_single_select_options(cell_data, &type_option, &field_rev, vec![google_option.clone()]);
 
         let data = SelectOptionCellContentChangeset::from_insert(&google_option.id).to_str();
         let cell_data = type_option.apply_changeset(data, None).unwrap();
-        assert_single_select_options(cell_data, &type_option, &field_meta, vec![google_option]);
+        assert_single_select_options(cell_data, &type_option, &field_rev, vec![google_option]);
 
         // Invalid option id
         let cell_data = type_option
             .apply_changeset(SelectOptionCellContentChangeset::from_insert("").to_str(), None)
             .unwrap();
-        assert_single_select_options(cell_data, &type_option, &field_meta, vec![]);
+        assert_single_select_options(cell_data, &type_option, &field_rev, vec![]);
 
         // Invalid option id
         let cell_data = type_option
             .apply_changeset(SelectOptionCellContentChangeset::from_insert("123").to_str(), None)
             .unwrap();
 
-        assert_single_select_options(cell_data, &type_option, &field_meta, vec![]);
+        assert_single_select_options(cell_data, &type_option, &field_rev, vec![]);
 
         // Invalid changeset
         assert!(type_option.apply_changeset("123", None).is_err());
@@ -564,12 +563,12 @@ mod tests {
             .option(facebook_option.clone())
             .option(twitter_option);
 
-        let field_meta = FieldBuilder::new(multi_select)
+        let field_rev = FieldBuilder::new(multi_select)
             .name("Platform")
             .visibility(true)
             .build();
 
-        let type_option = MultiSelectTypeOption::from(&field_meta);
+        let type_option = MultiSelectTypeOption::from(&field_rev);
 
         let option_ids = vec![google_option.id.clone(), facebook_option.id.clone()].join(SELECTION_IDS_SEPARATOR);
         let data = SelectOptionCellContentChangeset::from_insert(&option_ids).to_str();
@@ -577,25 +576,25 @@ mod tests {
         assert_multi_select_options(
             cell_data,
             &type_option,
-            &field_meta,
+            &field_rev,
             vec![google_option.clone(), facebook_option],
         );
 
         let data = SelectOptionCellContentChangeset::from_insert(&google_option.id).to_str();
         let cell_data = type_option.apply_changeset(data, None).unwrap();
-        assert_multi_select_options(cell_data, &type_option, &field_meta, vec![google_option]);
+        assert_multi_select_options(cell_data, &type_option, &field_rev, vec![google_option]);
 
         // Invalid option id
         let cell_data = type_option
             .apply_changeset(SelectOptionCellContentChangeset::from_insert("").to_str(), None)
             .unwrap();
-        assert_multi_select_options(cell_data, &type_option, &field_meta, vec![]);
+        assert_multi_select_options(cell_data, &type_option, &field_rev, vec![]);
 
         // Invalid option id
         let cell_data = type_option
             .apply_changeset(SelectOptionCellContentChangeset::from_insert("123,456").to_str(), None)
             .unwrap();
-        assert_multi_select_options(cell_data, &type_option, &field_meta, vec![]);
+        assert_multi_select_options(cell_data, &type_option, &field_rev, vec![]);
 
         // Invalid changeset
         assert!(type_option.apply_changeset("123", None).is_err());
@@ -604,13 +603,13 @@ mod tests {
     fn assert_multi_select_options(
         cell_data: String,
         type_option: &MultiSelectTypeOption,
-        field_meta: &FieldMeta,
+        field_rev: &FieldRevision,
         expected: Vec<SelectOption>,
     ) {
         assert_eq!(
             expected,
             type_option
-                .decode_cell_data(cell_data, &field_meta.field_type, field_meta)
+                .decode_cell_data(cell_data, &field_rev.field_type, field_rev)
                 .unwrap()
                 .parse::<SelectOptionCellData>()
                 .unwrap()
@@ -621,13 +620,13 @@ mod tests {
     fn assert_single_select_options(
         cell_data: String,
         type_option: &SingleSelectTypeOption,
-        field_meta: &FieldMeta,
+        field_rev: &FieldRevision,
         expected: Vec<SelectOption>,
     ) {
         assert_eq!(
             expected,
             type_option
-                .decode_cell_data(cell_data, &field_meta.field_type, field_meta)
+                .decode_cell_data(cell_data, &field_rev.field_type, field_rev)
                 .unwrap()
                 .parse::<SelectOptionCellData>()
                 .unwrap()

+ 14 - 15
frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs

@@ -4,9 +4,8 @@ use crate::services::row::{decode_cell_data, CellContentChangeset, CellDataOpera
 use bytes::Bytes;
 use flowy_derive::ProtoBuf;
 use flowy_error::{FlowyError, FlowyResult};
-use flowy_grid_data_model::entities::{
-    CellMeta, FieldMeta, FieldType, TypeOptionDataDeserializer, TypeOptionDataEntry,
-};
+use flowy_grid_data_model::entities::FieldType;
+use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry};
 use serde::{Deserialize, Serialize};
 
 #[derive(Default)]
@@ -36,7 +35,7 @@ impl CellDataOperation<String> for RichTextTypeOption {
         &self,
         encoded_data: T,
         decoded_field_type: &FieldType,
-        field_meta: &FieldMeta,
+        field_rev: &FieldRevision,
     ) -> FlowyResult<DecodedCellData>
     where
         T: Into<String>,
@@ -46,14 +45,14 @@ impl CellDataOperation<String> for RichTextTypeOption {
             || decoded_field_type.is_multi_select()
             || decoded_field_type.is_number()
         {
-            decode_cell_data(encoded_data, decoded_field_type, decoded_field_type, field_meta)
+            decode_cell_data(encoded_data, decoded_field_type, decoded_field_type, field_rev)
         } else {
             let cell_data = encoded_data.into();
             Ok(DecodedCellData::new(cell_data))
         }
     }
 
-    fn apply_changeset<C>(&self, changeset: C, _cell_meta: Option<CellMeta>) -> Result<String, FlowyError>
+    fn apply_changeset<C>(&self, changeset: C, _cell_rev: Option<CellRevision>) -> Result<String, FlowyError>
     where
         C: Into<CellContentChangeset>,
     {
@@ -79,11 +78,11 @@ mod tests {
 
         // date
         let field_type = FieldType::DateTime;
-        let date_time_field_meta = FieldBuilder::from_field_type(&field_type).build();
+        let date_time_field_rev = FieldBuilder::from_field_type(&field_type).build();
 
         assert_eq!(
             type_option
-                .decode_cell_data(1647251762.to_string(), &field_type, &date_time_field_meta)
+                .decode_cell_data(1647251762.to_string(), &field_type, &date_time_field_rev)
                 .unwrap()
                 .parse::<DateCellData>()
                 .unwrap()
@@ -95,11 +94,11 @@ mod tests {
         let done_option = SelectOption::new("Done");
         let done_option_id = done_option.id.clone();
         let single_select = SingleSelectTypeOptionBuilder::default().option(done_option.clone());
-        let single_select_field_meta = FieldBuilder::new(single_select).build();
+        let single_select_field_rev = FieldBuilder::new(single_select).build();
 
         assert_eq!(
             type_option
-                .decode_cell_data(done_option_id, &FieldType::SingleSelect, &single_select_field_meta)
+                .decode_cell_data(done_option_id, &FieldType::SingleSelect, &single_select_field_rev)
                 .unwrap()
                 .parse::<SelectOptionCellData>()
                 .unwrap()
@@ -115,12 +114,12 @@ mod tests {
         let multi_select = MultiSelectTypeOptionBuilder::default()
             .option(google_option.clone())
             .option(facebook_option.clone());
-        let multi_select_field_meta = FieldBuilder::new(multi_select).build();
-        let multi_type_option = MultiSelectTypeOption::from(&multi_select_field_meta);
+        let multi_select_field_rev = FieldBuilder::new(multi_select).build();
+        let multi_type_option = MultiSelectTypeOption::from(&multi_select_field_rev);
         let cell_data = multi_type_option.apply_changeset(cell_data_changeset, None).unwrap();
         assert_eq!(
             type_option
-                .decode_cell_data(cell_data, &FieldType::MultiSelect, &multi_select_field_meta)
+                .decode_cell_data(cell_data, &FieldType::MultiSelect, &multi_select_field_rev)
                 .unwrap()
                 .parse::<SelectOptionCellData>()
                 .unwrap()
@@ -130,10 +129,10 @@ mod tests {
 
         //Number
         let number = NumberTypeOptionBuilder::default().set_format(NumberFormat::USD);
-        let number_field_meta = FieldBuilder::new(number).build();
+        let number_field_rev = FieldBuilder::new(number).build();
         assert_eq!(
             type_option
-                .decode_cell_data("18443".to_owned(), &FieldType::Number, &number_field_meta)
+                .decode_cell_data("18443".to_owned(), &FieldType::Number, &number_field_rev)
                 .unwrap()
                 .to_string(),
             "$18,443".to_owned()

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

@@ -5,9 +5,8 @@ use bytes::Bytes;
 use fancy_regex::Regex;
 use flowy_derive::ProtoBuf;
 use flowy_error::{internal_error, FlowyError, FlowyResult};
-use flowy_grid_data_model::entities::{
-    CellMeta, FieldMeta, FieldType, TypeOptionDataDeserializer, TypeOptionDataEntry,
-};
+use flowy_grid_data_model::entities::FieldType;
+use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry};
 use lazy_static::lazy_static;
 use serde::{Deserialize, Serialize};
 use std::str::FromStr;
@@ -39,7 +38,7 @@ impl CellDataOperation<EncodedCellData<URLCellData>> for URLTypeOption {
         &self,
         encoded_data: T,
         decoded_field_type: &FieldType,
-        _field_meta: &FieldMeta,
+        field_rev: &FieldRevision,
     ) -> FlowyResult<DecodedCellData>
     where
         T: Into<EncodedCellData<URLCellData>>,
@@ -51,7 +50,7 @@ impl CellDataOperation<EncodedCellData<URLCellData>> for URLTypeOption {
         DecodedCellData::try_from_bytes(cell_data)
     }
 
-    fn apply_changeset<C>(&self, changeset: C, _cell_meta: Option<CellMeta>) -> Result<String, FlowyError>
+    fn apply_changeset<C>(&self, changeset: C, _cell_rev: Option<CellRevision>) -> Result<String, FlowyError>
     where
         C: Into<CellContentChangeset>,
     {
@@ -126,26 +125,27 @@ mod tests {
     use crate::services::field::FieldBuilder;
     use crate::services::field::{URLCellData, URLTypeOption};
     use crate::services::row::{CellDataOperation, EncodedCellData};
-    use flowy_grid_data_model::entities::{FieldMeta, FieldType};
+    use flowy_grid_data_model::entities::FieldType;
+    use flowy_grid_data_model::revision::FieldRevision;
 
     #[test]
     fn url_type_option_test_no_url() {
         let type_option = URLTypeOption::default();
         let field_type = FieldType::URL;
-        let field_meta = FieldBuilder::from_field_type(&field_type).build();
-        assert_changeset(&type_option, "123", &field_type, &field_meta, "123", "");
+        let field_rev = FieldBuilder::from_field_type(&field_type).build();
+        assert_changeset(&type_option, "123", &field_type, &field_rev, "123", "");
     }
 
     #[test]
     fn url_type_option_test_contains_url() {
         let type_option = URLTypeOption::default();
         let field_type = FieldType::URL;
-        let field_meta = FieldBuilder::from_field_type(&field_type).build();
+        let field_rev = FieldBuilder::from_field_type(&field_type).build();
         assert_changeset(
             &type_option,
             "AppFlowy website - https://www.appflowy.io",
             &field_type,
-            &field_meta,
+            &field_rev,
             "AppFlowy website - https://www.appflowy.io",
             "https://www.appflowy.io/",
         );
@@ -154,7 +154,7 @@ mod tests {
             &type_option,
             "AppFlowy website appflowy.io",
             &field_type,
-            &field_meta,
+            &field_rev,
             "AppFlowy website appflowy.io",
             "https://appflowy.io",
         );
@@ -164,12 +164,12 @@ mod tests {
         type_option: &URLTypeOption,
         cell_data: &str,
         field_type: &FieldType,
-        field_meta: &FieldMeta,
+        field_rev: &FieldRevision,
         expected: &str,
         expected_url: &str,
     ) {
         let encoded_data = type_option.apply_changeset(cell_data, None).unwrap();
-        let decode_cell_data = decode_cell_data(encoded_data, type_option, field_meta, field_type);
+        let decode_cell_data = decode_cell_data(encoded_data, type_option, field_rev, field_type);
         assert_eq!(expected.to_owned(), decode_cell_data.content);
         assert_eq!(expected_url.to_owned(), decode_cell_data.url);
     }
@@ -177,11 +177,11 @@ mod tests {
     fn decode_cell_data<T: Into<EncodedCellData<URLCellData>>>(
         encoded_data: T,
         type_option: &URLTypeOption,
-        field_meta: &FieldMeta,
+        field_rev: &FieldRevision,
         field_type: &FieldType,
     ) -> URLCellData {
         type_option
-            .decode_cell_data(encoded_data, field_type, field_meta)
+            .decode_cell_data(encoded_data, field_type, field_rev)
             .unwrap()
             .parse::<URLCellData>()
             .unwrap()

+ 3 - 3
frontend/rust-lib/flowy-grid/src/services/field/type_options/util.rs

@@ -1,9 +1,9 @@
 use crate::services::row::TypeOptionCellData;
-use flowy_grid_data_model::entities::CellMeta;
+use flowy_grid_data_model::revision::CellRevision;
 use std::str::FromStr;
 
-pub fn get_cell_data(cell_meta: &CellMeta) -> String {
-    match TypeOptionCellData::from_str(&cell_meta.data) {
+pub fn get_cell_data(cell_rev: &CellRevision) -> String {
+    match TypeOptionCellData::from_str(&cell_rev.data) {
         Ok(type_option) => type_option.data,
         Err(_) => String::new(),
     }

+ 89 - 90
frontend/rust-lib/flowy-grid/src/services/grid_editor.rs

@@ -1,15 +1,16 @@
 use crate::dart_notification::{send_dart_notification, GridNotification};
 use crate::entities::CellIdentifier;
 use crate::manager::GridUser;
-use crate::services::block_meta_manager::GridBlockManager;
+use crate::services::block_manager::GridBlockManager;
 use crate::services::field::{default_type_option_builder_from_type, type_option_builder_from_bytes, FieldBuilder};
 use crate::services::persistence::block_index::BlockIndexCache;
 use crate::services::row::*;
 use bytes::Bytes;
 use flowy_error::{ErrorCode, FlowyError, FlowyResult};
 use flowy_grid_data_model::entities::*;
+use flowy_grid_data_model::revision::*;
 use flowy_revision::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder};
-use flowy_sync::client_grid::{GridChangeset, GridMetaPad, JsonDeserializer};
+use flowy_sync::client_grid::{GridChangeset, GridRevisionPad, JsonDeserializer};
 use flowy_sync::entities::revision::Revision;
 use flowy_sync::errors::CollaborateResult;
 use flowy_sync::util::make_delta_from_revisions;
@@ -22,7 +23,7 @@ use tokio::sync::RwLock;
 pub struct GridMetaEditor {
     grid_id: String,
     user: Arc<dyn GridUser>,
-    grid_pad: Arc<RwLock<GridMetaPad>>,
+    grid_pad: Arc<RwLock<GridRevisionPad>>,
     rev_manager: Arc<RevisionManager>,
     block_manager: Arc<GridBlockManager>,
 }
@@ -80,7 +81,7 @@ impl GridMetaEditor {
                         width: Some(field.width),
                         type_option_data: Some(type_option_data),
                     };
-                    Ok(grid.update_field_meta(changeset, deserializer)?)
+                    Ok(grid.update_field_rev(changeset, deserializer)?)
                 })
                 .await?;
             let _ = self.notify_did_update_grid_field(&field_id).await?;
@@ -88,9 +89,9 @@ impl GridMetaEditor {
             let _ = self
                 .modify(|grid| {
                     let builder = type_option_builder_from_bytes(type_option_data, &field.field_type);
-                    let field_meta = FieldBuilder::from_field(field, builder).build();
+                    let field_rev = FieldBuilder::from_field(field, builder).build();
 
-                    Ok(grid.create_field_meta(field_meta, start_field_id)?)
+                    Ok(grid.create_field_rev(field_rev, start_field_id)?)
                 })
                 .await?;
             let _ = self.notify_did_insert_grid_field(&field_id).await?;
@@ -105,42 +106,42 @@ impl GridMetaEditor {
         field_id: &str,
         type_option_data: Vec<u8>,
     ) -> FlowyResult<()> {
-        let result = self.get_field_meta(field_id).await;
+        let result = self.get_field_rev(field_id).await;
         if result.is_none() {
             tracing::warn!("Can't find the field with id: {}", field_id);
             return Ok(());
         }
-        let field_meta = result.unwrap();
+        let field_rev = result.unwrap();
         let _ = self
             .modify(|grid| {
-                let deserializer = TypeOptionJsonDeserializer(field_meta.field_type.clone());
+                let deserializer = TypeOptionJsonDeserializer(field_rev.field_type.clone());
                 let changeset = FieldChangesetParams {
                     field_id: field_id.to_owned(),
                     grid_id: grid_id.to_owned(),
                     type_option_data: Some(type_option_data),
                     ..Default::default()
                 };
-                Ok(grid.update_field_meta(changeset, deserializer)?)
+                Ok(grid.update_field_rev(changeset, deserializer)?)
             })
             .await?;
         let _ = self.notify_did_update_grid_field(field_id).await?;
         Ok(())
     }
 
-    pub async fn next_field_meta(&self, field_type: &FieldType) -> FlowyResult<FieldMeta> {
+    pub async fn next_field_rev(&self, field_type: &FieldType) -> FlowyResult<FieldRevision> {
         let name = format!("Property {}", self.grid_pad.read().await.fields().len() + 1);
-        let field_meta = FieldBuilder::from_field_type(field_type).name(&name).build();
-        Ok(field_meta)
+        let field_rev = FieldBuilder::from_field_type(field_type).name(&name).build();
+        Ok(field_rev)
     }
 
-    pub async fn create_next_field_meta(&self, field_type: &FieldType) -> FlowyResult<FieldMeta> {
-        let field_meta = self.next_field_meta(field_type).await?;
+    pub async fn create_next_field_rev(&self, field_type: &FieldType) -> FlowyResult<FieldRevision> {
+        let field_rev = self.next_field_rev(field_type).await?;
         let _ = self
-            .modify(|grid| Ok(grid.create_field_meta(field_meta.clone(), None)?))
+            .modify(|grid| Ok(grid.create_field_rev(field_rev.clone(), None)?))
             .await?;
-        let _ = self.notify_did_insert_grid_field(&field_meta.id).await?;
+        let _ = self.notify_did_insert_grid_field(&field_rev.id).await?;
 
-        Ok(field_meta)
+        Ok(field_rev)
     }
 
     pub async fn contain_field(&self, field_id: &str) -> bool {
@@ -149,28 +150,28 @@ impl GridMetaEditor {
 
     pub async fn update_field(&self, params: FieldChangesetParams) -> FlowyResult<()> {
         let field_id = params.field_id.clone();
-        let json_deserializer = match self.grid_pad.read().await.get_field_meta(params.field_id.as_str()) {
+        let json_deserializer = match self.grid_pad.read().await.get_field_rev(params.field_id.as_str()) {
             None => return Err(ErrorCode::FieldDoesNotExist.into()),
-            Some((_, field_meta)) => TypeOptionJsonDeserializer(field_meta.field_type.clone()),
+            Some((_, field_rev)) => TypeOptionJsonDeserializer(field_rev.field_type.clone()),
         };
 
         let _ = self
-            .modify(|grid| Ok(grid.update_field_meta(params, json_deserializer)?))
+            .modify(|grid| Ok(grid.update_field_rev(params, json_deserializer)?))
             .await?;
 
         let _ = self.notify_did_update_grid_field(&field_id).await?;
         Ok(())
     }
 
-    pub async fn replace_field(&self, field_meta: FieldMeta) -> FlowyResult<()> {
-        let field_id = field_meta.id.clone();
-        let _ = self.modify(|pad| Ok(pad.replace_field_meta(field_meta)?)).await?;
+    pub async fn replace_field(&self, field_rev: FieldRevision) -> FlowyResult<()> {
+        let field_id = field_rev.id.clone();
+        let _ = self.modify(|pad| Ok(pad.replace_field_rev(field_rev)?)).await?;
         let _ = self.notify_did_update_grid_field(&field_id).await?;
         Ok(())
     }
 
     pub async fn delete_field(&self, field_id: &str) -> FlowyResult<()> {
-        let _ = self.modify(|grid| Ok(grid.delete_field_meta(field_id)?)).await?;
+        let _ = self.modify(|grid| Ok(grid.delete_field_rev(field_id)?)).await?;
         let field_order = FieldOrder::from(field_id);
         let notified_changeset = GridFieldChangeset::delete(&self.grid_id, vec![field_order]);
         let _ = self.notify_did_update_grid(notified_changeset).await?;
@@ -184,9 +185,9 @@ impl GridMetaEditor {
         //     .into_iter()
         //     .map(|block_meta| block_meta.block_id)
         //     .collect();
-        // let cell_metas = self
+        // let cell_revs = self
         //     .block_meta_manager
-        //     .get_cell_metas(block_ids, field_id, None)
+        //     .get_cell_revs(block_ids, field_id, None)
         //     .await?;
 
         let type_option_json_builder = |field_type: &FieldType| -> String {
@@ -205,80 +206,80 @@ impl GridMetaEditor {
     pub async fn duplicate_field(&self, field_id: &str) -> FlowyResult<()> {
         let duplicated_field_id = gen_field_id();
         let _ = self
-            .modify(|grid| Ok(grid.duplicate_field_meta(field_id, &duplicated_field_id)?))
+            .modify(|grid| Ok(grid.duplicate_field_rev(field_id, &duplicated_field_id)?))
             .await?;
 
         let _ = self.notify_did_insert_grid_field(&duplicated_field_id).await?;
         Ok(())
     }
 
-    pub async fn get_field_meta(&self, field_id: &str) -> Option<FieldMeta> {
-        let field_meta = self.grid_pad.read().await.get_field_meta(field_id)?.1.clone();
-        Some(field_meta)
+    pub async fn get_field_rev(&self, field_id: &str) -> Option<FieldRevision> {
+        let field_rev = self.grid_pad.read().await.get_field_rev(field_id)?.1.clone();
+        Some(field_rev)
     }
 
-    pub async fn get_field_metas<T>(&self, field_ids: Option<Vec<T>>) -> FlowyResult<Vec<FieldMeta>>
+    pub async fn get_field_revs<T>(&self, field_ids: Option<Vec<T>>) -> FlowyResult<Vec<FieldRevision>>
     where
         T: Into<FieldOrder>,
     {
         if field_ids.is_none() {
-            let field_metas = self.grid_pad.read().await.get_field_metas(None)?;
-            return Ok(field_metas);
+            let field_revs = self.grid_pad.read().await.get_field_revs(None)?;
+            return Ok(field_revs);
         }
 
         let to_field_orders = |item: Vec<T>| item.into_iter().map(|data| data.into()).collect();
         let field_orders = field_ids.map_or(vec![], to_field_orders);
         let expected_len = field_orders.len();
-        let field_metas = self.grid_pad.read().await.get_field_metas(Some(field_orders))?;
-        if expected_len != 0 && field_metas.len() != expected_len {
+        let field_revs = self.grid_pad.read().await.get_field_revs(Some(field_orders))?;
+        if expected_len != 0 && field_revs.len() != expected_len {
             tracing::error!(
-                "This is a bug. The len of the field_metas should equal to {}",
+                "This is a bug. The len of the field_revs should equal to {}",
                 expected_len
             );
-            debug_assert!(field_metas.len() == expected_len);
+            debug_assert!(field_revs.len() == expected_len);
         }
-        Ok(field_metas)
+        Ok(field_revs)
     }
 
-    pub async fn create_block(&self, grid_block: GridBlockMeta) -> FlowyResult<()> {
+    pub async fn create_block(&self, grid_block: GridBlockRevision) -> FlowyResult<()> {
         let _ = self.modify(|grid| Ok(grid.create_block_meta(grid_block)?)).await?;
         Ok(())
     }
 
-    pub async fn update_block(&self, changeset: GridBlockMetaChangeset) -> FlowyResult<()> {
+    pub async fn update_block(&self, changeset: GridBlockRevisionChangeset) -> FlowyResult<()> {
         let _ = self.modify(|grid| Ok(grid.update_block_meta(changeset)?)).await?;
         Ok(())
     }
 
     pub async fn create_row(&self, start_row_id: Option<String>) -> FlowyResult<RowOrder> {
-        let field_metas = self.grid_pad.read().await.get_field_metas(None)?;
+        let field_revs = self.grid_pad.read().await.get_field_revs(None)?;
         let block_id = self.block_id().await?;
 
         // insert empty row below the row whose id is upper_row_id
-        let row_meta_ctx = CreateRowMetaBuilder::new(&field_metas).build();
-        let row_meta = make_row_meta_from_context(&block_id, row_meta_ctx);
-        let row_order = RowOrder::from(&row_meta);
+        let row_rev_ctx = CreateRowMetaBuilder::new(&field_revs).build();
+        let row_rev = make_row_rev_from_context(&block_id, row_rev_ctx);
+        let row_order = RowOrder::from(&row_rev);
 
         // insert the row
-        let row_count = self.block_manager.create_row(&block_id, row_meta, start_row_id).await?;
+        let row_count = self.block_manager.create_row(&block_id, row_rev, start_row_id).await?;
 
         // update block row count
-        let changeset = GridBlockMetaChangeset::from_row_count(&block_id, row_count);
+        let changeset = GridBlockRevisionChangeset::from_row_count(&block_id, row_count);
         let _ = self.update_block(changeset).await?;
         Ok(row_order)
     }
 
     pub async fn insert_rows(&self, contexts: Vec<CreateRowMetaPayload>) -> FlowyResult<Vec<RowOrder>> {
         let block_id = self.block_id().await?;
-        let mut rows_by_block_id: HashMap<String, Vec<RowMeta>> = HashMap::new();
+        let mut rows_by_block_id: HashMap<String, Vec<RowRevision>> = HashMap::new();
         let mut row_orders = vec![];
         for ctx in contexts {
-            let row_meta = make_row_meta_from_context(&block_id, ctx);
-            row_orders.push(RowOrder::from(&row_meta));
+            let row_rev = make_row_rev_from_context(&block_id, ctx);
+            row_orders.push(RowOrder::from(&row_rev));
             rows_by_block_id
                 .entry(block_id.clone())
                 .or_insert_with(Vec::new)
-                .push(row_meta);
+                .push(row_rev);
         }
         let changesets = self.block_manager.insert_row(rows_by_block_id).await?;
         for changeset in changesets {
@@ -288,9 +289,9 @@ impl GridMetaEditor {
     }
 
     pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult<()> {
-        let field_metas = self.get_field_metas::<FieldOrder>(None).await?;
+        let field_revs = self.get_field_revs::<FieldOrder>(None).await?;
         self.block_manager
-            .update_row(changeset, |row_meta| make_row_from_row_meta(&field_metas, row_meta))
+            .update_row(changeset, |row_rev| make_row_from_row_rev(&field_revs, row_rev))
             .await
     }
 
@@ -303,8 +304,8 @@ impl GridMetaEditor {
         debug_assert_eq!(grid_block_snapshot.len(), 1);
         if grid_block_snapshot.len() == 1 {
             let snapshot = grid_block_snapshot.pop().unwrap();
-            let field_metas = self.get_field_metas::<FieldOrder>(None).await?;
-            let rows = make_rows_from_row_metas(&field_metas, &snapshot.row_metas);
+            let field_revs = self.get_field_revs::<FieldOrder>(None).await?;
+            let rows = make_rows_from_row_revs(&field_revs, &snapshot.row_revs);
             Ok(rows.into())
         } else {
             Ok(vec![].into())
@@ -312,12 +313,12 @@ impl GridMetaEditor {
     }
 
     pub async fn get_row(&self, row_id: &str) -> FlowyResult<Option<Row>> {
-        match self.block_manager.get_row_meta(row_id).await? {
+        match self.block_manager.get_row_rev(row_id).await? {
             None => Ok(None),
-            Some(row_meta) => {
-                let field_metas = self.get_field_metas::<FieldOrder>(None).await?;
-                let row_metas = vec![row_meta];
-                let mut rows = make_rows_from_row_metas(&field_metas, &row_metas);
+            Some(row_rev) => {
+                let field_revs = self.get_field_revs::<FieldOrder>(None).await?;
+                let row_revs = vec![row_rev];
+                let mut rows = make_rows_from_row_revs(&field_revs, &row_revs);
                 debug_assert!(rows.len() == 1);
                 Ok(rows.pop())
             }
@@ -333,18 +334,18 @@ impl GridMetaEditor {
     }
 
     pub async fn get_cell(&self, params: &CellIdentifier) -> Option<Cell> {
-        let field_meta = self.get_field_meta(&params.field_id).await?;
-        let row_meta = self.block_manager.get_row_meta(&params.row_id).await.ok()??;
-        make_cell(&params.field_id, &field_meta, &row_meta)
+        let field_rev = self.get_field_rev(&params.field_id).await?;
+        let row_rev = self.block_manager.get_row_rev(&params.row_id).await.ok()??;
+        make_cell(&params.field_id, &field_rev, &row_rev)
     }
 
-    pub async fn get_cell_meta(&self, row_id: &str, field_id: &str) -> FlowyResult<Option<CellMeta>> {
-        let row_meta = self.block_manager.get_row_meta(row_id).await?;
-        match row_meta {
+    pub async fn get_cell_rev(&self, row_id: &str, field_id: &str) -> FlowyResult<Option<CellRevision>> {
+        let row_rev = self.block_manager.get_row_rev(row_id).await?;
+        match row_rev {
             None => Ok(None),
-            Some(row_meta) => {
-                let cell_meta = row_meta.cells.get(field_id).cloned();
-                Ok(cell_meta)
+            Some(row_rev) => {
+                let cell_rev = row_rev.cells.get(field_id).cloned();
+                Ok(cell_rev)
             }
         }
     }
@@ -362,22 +363,22 @@ impl GridMetaEditor {
             mut cell_content_changeset,
         } = cell_changeset;
 
-        match self.grid_pad.read().await.get_field_meta(&field_id) {
+        match self.grid_pad.read().await.get_field_rev(&field_id) {
             None => {
                 let msg = format!("Field not found with id: {}", &field_id);
                 Err(FlowyError::internal().context(msg))
             }
-            Some((_, field_meta)) => {
+            Some((_, field_rev)) => {
                 tracing::trace!("field changeset: id:{} / value:{:?}", &field_id, cell_content_changeset);
 
-                let cell_meta = self.get_cell_meta(&row_id, &field_id).await?;
+                let cell_rev = self.get_cell_rev(&row_id, &field_id).await?;
                 // Update the changeset.data property with the return value.
                 cell_content_changeset = Some(apply_cell_data_changeset(
                     cell_content_changeset.unwrap(),
-                    cell_meta,
-                    field_meta,
+                    cell_rev,
+                    field_rev,
                 )?);
-                let field_metas = self.get_field_metas::<FieldOrder>(None).await?;
+                let field_revs = self.get_field_revs::<FieldOrder>(None).await?;
                 let cell_changeset = CellChangeset {
                     grid_id,
                     row_id,
@@ -386,9 +387,7 @@ impl GridMetaEditor {
                 };
                 let _ = self
                     .block_manager
-                    .update_cell(cell_changeset, |row_meta| {
-                        make_row_from_row_meta(&field_metas, row_meta)
-                    })
+                    .update_cell(cell_changeset, |row_rev| make_row_from_row_rev(&field_revs, row_rev))
                     .await?;
                 Ok(())
             }
@@ -400,7 +399,7 @@ impl GridMetaEditor {
         make_grid_blocks(block_ids, block_snapshots)
     }
 
-    pub async fn get_block_metas(&self) -> FlowyResult<Vec<GridBlockMeta>> {
+    pub async fn get_block_metas(&self) -> FlowyResult<Vec<GridBlockRevision>> {
         let grid_blocks = self.grid_pad.read().await.get_block_metas();
         Ok(grid_blocks)
     }
@@ -463,9 +462,9 @@ impl GridMetaEditor {
         let _ = self
             .modify(|grid_pad| Ok(grid_pad.move_field(field_id, from as usize, to as usize)?))
             .await?;
-        if let Some((index, field_meta)) = self.grid_pad.read().await.get_field_meta(field_id) {
+        if let Some((index, field_rev)) = self.grid_pad.read().await.get_field_rev(field_id) {
             let delete_field_order = FieldOrder::from(field_id);
-            let insert_field = IndexField::from_field_meta(field_meta, index);
+            let insert_field = IndexField::from_field_rev(field_rev, index);
             let notified_changeset = GridFieldChangeset {
                 grid_id: self.grid_id.clone(),
                 inserted_fields: vec![insert_field],
@@ -510,7 +509,7 @@ impl GridMetaEditor {
         drop(grid_pad);
 
         Ok(BuildGridContext {
-            field_metas: duplicated_fields,
+            field_revs: duplicated_fields,
             blocks: duplicated_blocks,
             blocks_meta_data,
         })
@@ -518,7 +517,7 @@ impl GridMetaEditor {
 
     async fn modify<F>(&self, f: F) -> FlowyResult<()>
     where
-        F: for<'a> FnOnce(&'a mut GridMetaPad) -> FlowyResult<Option<GridChangeset>>,
+        F: for<'a> FnOnce(&'a mut GridRevisionPad) -> FlowyResult<Option<GridChangeset>>,
     {
         let mut write_guard = self.grid_pad.write().await;
         if let Some(changeset) = f(&mut *write_guard)? {
@@ -556,8 +555,8 @@ impl GridMetaEditor {
 
     #[tracing::instrument(level = "trace", skip_all, err)]
     async fn notify_did_insert_grid_field(&self, field_id: &str) -> FlowyResult<()> {
-        if let Some((index, field_meta)) = self.grid_pad.read().await.get_field_meta(field_id) {
-            let index_field = IndexField::from_field_meta(field_meta, index);
+        if let Some((index, field_rev)) = self.grid_pad.read().await.get_field_rev(field_id) {
+            let index_field = IndexField::from_field_rev(field_rev, index);
             let notified_changeset = GridFieldChangeset::insert(&self.grid_id, vec![index_field]);
             let _ = self.notify_did_update_grid(notified_changeset).await?;
         }
@@ -566,14 +565,14 @@ impl GridMetaEditor {
 
     #[tracing::instrument(level = "trace", skip_all, err)]
     async fn notify_did_update_grid_field(&self, field_id: &str) -> FlowyResult<()> {
-        if let Some((_, field_meta)) = self
+        if let Some((_, field_rev)) = self
             .grid_pad
             .read()
             .await
-            .get_field_meta(field_id)
+            .get_field_rev(field_id)
             .map(|(index, field)| (index, field.clone()))
         {
-            let updated_field = Field::from(field_meta);
+            let updated_field = Field::from(field_rev);
             let notified_changeset = GridFieldChangeset::update(&self.grid_id, vec![updated_field.clone()]);
             let _ = self.notify_did_update_grid(notified_changeset).await?;
 
@@ -602,10 +601,10 @@ impl GridMetaEditor {
 
 pub struct GridPadBuilder();
 impl RevisionObjectBuilder for GridPadBuilder {
-    type Output = GridMetaPad;
+    type Output = GridRevisionPad;
 
     fn build_object(object_id: &str, revisions: Vec<Revision>) -> FlowyResult<Self::Output> {
-        let pad = GridMetaPad::from_revisions(object_id, revisions)?;
+        let pad = GridRevisionPad::from_revisions(object_id, revisions)?;
         Ok(pad)
     }
 }

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

@@ -1,7 +1,7 @@
 mod util;
 
-pub mod block_meta_editor;
-mod block_meta_manager;
+mod block_manager;
+pub mod block_revision_editor;
 pub mod field;
 pub mod grid_editor;
 pub mod persistence;

+ 32 - 31
frontend/rust-lib/flowy-grid/src/services/row/cell_data_operation.rs

@@ -1,7 +1,8 @@
 use crate::services::field::*;
 use bytes::Bytes;
 use flowy_error::{internal_error, ErrorCode, FlowyError, FlowyResult};
-use flowy_grid_data_model::entities::{CellMeta, FieldMeta, FieldType};
+use flowy_grid_data_model::entities::FieldType;
+use flowy_grid_data_model::revision::{CellRevision, FieldRevision};
 use serde::{Deserialize, Serialize};
 use std::fmt::Formatter;
 use std::str::FromStr;
@@ -11,7 +12,7 @@ pub trait CellDataOperation<ED> {
         &self,
         encoded_data: T,
         decoded_field_type: &FieldType,
-        field_meta: &FieldMeta,
+        field_rev: &FieldRevision,
     ) -> FlowyResult<DecodedCellData>
     where
         T: Into<ED>;
@@ -20,7 +21,7 @@ pub trait CellDataOperation<ED> {
     fn apply_changeset<C: Into<CellContentChangeset>>(
         &self,
         changeset: C,
-        cell_meta: Option<CellMeta>,
+        cell_rev: Option<CellRevision>,
     ) -> FlowyResult<String>;
 }
 
@@ -122,30 +123,30 @@ impl TypeOptionCellData {
 /// For example, it's String on FieldType::RichText, and SelectOptionChangeset on FieldType::SingleSelect
 pub fn apply_cell_data_changeset<T: Into<CellContentChangeset>>(
     changeset: T,
-    cell_meta: Option<CellMeta>,
-    field_meta: &FieldMeta,
+    cell_rev: Option<CellRevision>,
+    field_rev: &FieldRevision,
 ) -> Result<String, FlowyError> {
-    let s = match field_meta.field_type {
-        FieldType::RichText => RichTextTypeOption::from(field_meta).apply_changeset(changeset, cell_meta),
-        FieldType::Number => NumberTypeOption::from(field_meta).apply_changeset(changeset, cell_meta),
-        FieldType::DateTime => DateTypeOption::from(field_meta).apply_changeset(changeset, cell_meta),
-        FieldType::SingleSelect => SingleSelectTypeOption::from(field_meta).apply_changeset(changeset, cell_meta),
-        FieldType::MultiSelect => MultiSelectTypeOption::from(field_meta).apply_changeset(changeset, cell_meta),
-        FieldType::Checkbox => CheckboxTypeOption::from(field_meta).apply_changeset(changeset, cell_meta),
-        FieldType::URL => URLTypeOption::from(field_meta).apply_changeset(changeset, cell_meta),
+    let s = match field_rev.field_type {
+        FieldType::RichText => RichTextTypeOption::from(field_rev).apply_changeset(changeset, cell_rev),
+        FieldType::Number => NumberTypeOption::from(field_rev).apply_changeset(changeset, cell_rev),
+        FieldType::DateTime => DateTypeOption::from(field_rev).apply_changeset(changeset, cell_rev),
+        FieldType::SingleSelect => SingleSelectTypeOption::from(field_rev).apply_changeset(changeset, cell_rev),
+        FieldType::MultiSelect => MultiSelectTypeOption::from(field_rev).apply_changeset(changeset, cell_rev),
+        FieldType::Checkbox => CheckboxTypeOption::from(field_rev).apply_changeset(changeset, cell_rev),
+        FieldType::URL => URLTypeOption::from(field_rev).apply_changeset(changeset, cell_rev),
     }?;
 
-    Ok(TypeOptionCellData::new(s, field_meta.field_type.clone()).json())
+    Ok(TypeOptionCellData::new(s, field_rev.field_type.clone()).json())
 }
 
 pub fn decode_cell_data_from_type_option_cell_data<T: TryInto<TypeOptionCellData>>(
     data: T,
-    field_meta: &FieldMeta,
+    field_rev: &FieldRevision,
     field_type: &FieldType,
 ) -> DecodedCellData {
     if let Ok(type_option_cell_data) = data.try_into() {
         let (encoded_data, s_field_type) = type_option_cell_data.split();
-        match decode_cell_data(encoded_data, &s_field_type, field_type, field_meta) {
+        match decode_cell_data(encoded_data, &s_field_type, field_type, field_rev) {
             Ok(cell_data) => cell_data,
             Err(e) => {
                 tracing::error!("Decode cell data failed, {:?}", e);
@@ -162,32 +163,32 @@ pub fn decode_cell_data<T: Into<String>>(
     encoded_data: T,
     s_field_type: &FieldType,
     t_field_type: &FieldType,
-    field_meta: &FieldMeta,
+    field_rev: &FieldRevision,
 ) -> FlowyResult<DecodedCellData> {
     let encoded_data = encoded_data.into();
     let get_cell_data = || {
         let data = match t_field_type {
-            FieldType::RichText => field_meta
+            FieldType::RichText => field_rev
                 .get_type_option_entry::<RichTextTypeOption>(t_field_type)?
-                .decode_cell_data(encoded_data, s_field_type, field_meta),
-            FieldType::Number => field_meta
+                .decode_cell_data(encoded_data, s_field_type, field_rev),
+            FieldType::Number => field_rev
                 .get_type_option_entry::<NumberTypeOption>(t_field_type)?
-                .decode_cell_data(encoded_data, s_field_type, field_meta),
-            FieldType::DateTime => field_meta
+                .decode_cell_data(encoded_data, s_field_type, field_rev),
+            FieldType::DateTime => field_rev
                 .get_type_option_entry::<DateTypeOption>(t_field_type)?
-                .decode_cell_data(encoded_data, s_field_type, field_meta),
-            FieldType::SingleSelect => field_meta
+                .decode_cell_data(encoded_data, s_field_type, field_rev),
+            FieldType::SingleSelect => field_rev
                 .get_type_option_entry::<SingleSelectTypeOption>(t_field_type)?
-                .decode_cell_data(encoded_data, s_field_type, field_meta),
-            FieldType::MultiSelect => field_meta
+                .decode_cell_data(encoded_data, s_field_type, field_rev),
+            FieldType::MultiSelect => field_rev
                 .get_type_option_entry::<MultiSelectTypeOption>(t_field_type)?
-                .decode_cell_data(encoded_data, s_field_type, field_meta),
-            FieldType::Checkbox => field_meta
+                .decode_cell_data(encoded_data, s_field_type, field_rev),
+            FieldType::Checkbox => field_rev
                 .get_type_option_entry::<CheckboxTypeOption>(t_field_type)?
-                .decode_cell_data(encoded_data, s_field_type, field_meta),
-            FieldType::URL => field_meta
+                .decode_cell_data(encoded_data, s_field_type, field_rev),
+            FieldType::URL => field_rev
                 .get_type_option_entry::<URLTypeOption>(t_field_type)?
-                .decode_cell_data(encoded_data, s_field_type, field_meta),
+                .decode_cell_data(encoded_data, s_field_type, field_rev),
         };
         Some(data)
     };

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

@@ -1,21 +1,21 @@
 use crate::services::field::SelectOptionCellContentChangeset;
 use crate::services::row::apply_cell_data_changeset;
 use flowy_error::{FlowyError, FlowyResult};
-use flowy_grid_data_model::entities::{gen_row_id, CellMeta, FieldMeta, RowMeta, DEFAULT_ROW_HEIGHT};
+use flowy_grid_data_model::revision::{gen_row_id, CellRevision, FieldRevision, RowRevision, DEFAULT_ROW_HEIGHT};
 use indexmap::IndexMap;
 use std::collections::HashMap;
 
 pub struct CreateRowMetaBuilder<'a> {
-    field_meta_map: HashMap<&'a String, &'a FieldMeta>,
+    field_rev_map: HashMap<&'a String, &'a FieldRevision>,
     payload: CreateRowMetaPayload,
 }
 
 impl<'a> CreateRowMetaBuilder<'a> {
-    pub fn new(fields: &'a [FieldMeta]) -> Self {
-        let field_meta_map = fields
+    pub fn new(fields: &'a [FieldRevision]) -> Self {
+        let field_rev_map = fields
             .iter()
             .map(|field| (&field.id, field))
-            .collect::<HashMap<&String, &FieldMeta>>();
+            .collect::<HashMap<&String, &FieldRevision>>();
 
         let payload = CreateRowMetaPayload {
             row_id: gen_row_id(),
@@ -25,20 +25,20 @@ impl<'a> CreateRowMetaBuilder<'a> {
         };
 
         Self {
-            field_meta_map,
+            field_rev_map: field_rev_map,
             payload,
         }
     }
 
     pub fn add_cell(&mut self, field_id: &str, data: String) -> FlowyResult<()> {
-        match self.field_meta_map.get(&field_id.to_owned()) {
+        match self.field_rev_map.get(&field_id.to_owned()) {
             None => {
                 let msg = format!("Invalid field_id: {}", field_id);
                 Err(FlowyError::internal().context(msg))
             }
-            Some(field_meta) => {
-                let data = apply_cell_data_changeset(&data, None, field_meta)?;
-                let cell = CellMeta::new(data);
+            Some(field_rev) => {
+                let data = apply_cell_data_changeset(&data, None, field_rev)?;
+                let cell = CellRevision::new(data);
                 self.payload.cell_by_field_id.insert(field_id.to_owned(), cell);
                 Ok(())
             }
@@ -46,15 +46,15 @@ impl<'a> CreateRowMetaBuilder<'a> {
     }
 
     pub fn add_select_option_cell(&mut self, field_id: &str, data: String) -> FlowyResult<()> {
-        match self.field_meta_map.get(&field_id.to_owned()) {
+        match self.field_rev_map.get(&field_id.to_owned()) {
             None => {
                 let msg = format!("Invalid field_id: {}", field_id);
                 Err(FlowyError::internal().context(msg))
             }
-            Some(field_meta) => {
+            Some(field_rev) => {
                 let cell_data = SelectOptionCellContentChangeset::from_insert(&data).to_str();
-                let data = apply_cell_data_changeset(&cell_data, None, field_meta)?;
-                let cell = CellMeta::new(data);
+                let data = apply_cell_data_changeset(&cell_data, None, field_rev)?;
+                let cell = CellRevision::new(data);
                 self.payload.cell_by_field_id.insert(field_id.to_owned(), cell);
                 Ok(())
             }
@@ -78,8 +78,8 @@ impl<'a> CreateRowMetaBuilder<'a> {
     }
 }
 
-pub fn make_row_meta_from_context(block_id: &str, payload: CreateRowMetaPayload) -> RowMeta {
-    RowMeta {
+pub fn make_row_rev_from_context(block_id: &str, payload: CreateRowMetaPayload) -> RowRevision {
+    RowRevision {
         id: payload.row_id,
         block_id: block_id.to_owned(),
         cells: payload.cell_by_field_id,
@@ -90,7 +90,7 @@ pub fn make_row_meta_from_context(block_id: &str, payload: CreateRowMetaPayload)
 
 pub struct CreateRowMetaPayload {
     pub row_id: String,
-    pub cell_by_field_id: IndexMap<String, CellMeta>,
+    pub cell_by_field_id: IndexMap<String, CellRevision>,
     pub height: i32,
     pub visibility: bool,
 }

+ 29 - 30
frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs

@@ -1,14 +1,13 @@
 use crate::services::row::decode_cell_data_from_type_option_cell_data;
 use flowy_error::FlowyResult;
-use flowy_grid_data_model::entities::{
-    Cell, CellMeta, FieldMeta, GridBlock, GridBlockOrder, RepeatedGridBlock, Row, RowMeta, RowOrder,
-};
+use flowy_grid_data_model::entities::{Cell, GridBlock, GridBlockOrder, RepeatedGridBlock, Row, RowOrder};
+use flowy_grid_data_model::revision::{CellRevision, FieldRevision, RowRevision};
 use std::collections::HashMap;
 use std::sync::Arc;
 
 pub struct GridBlockSnapshot {
     pub(crate) block_id: String,
-    pub row_metas: Vec<Arc<RowMeta>>,
+    pub row_revs: Vec<Arc<RowRevision>>,
 }
 
 pub(crate) fn group_row_orders(row_orders: Vec<RowOrder>) -> Vec<GridBlockOrder> {
@@ -26,52 +25,52 @@ pub(crate) fn group_row_orders(row_orders: Vec<RowOrder>) -> Vec<GridBlockOrder>
 
 #[inline(always)]
 pub fn make_cell_by_field_id(
-    field_map: &HashMap<&String, &FieldMeta>,
+    field_map: &HashMap<&String, &FieldRevision>,
     field_id: String,
-    cell_meta: CellMeta,
+    cell_rev: CellRevision,
 ) -> Option<(String, Cell)> {
-    let field_meta = field_map.get(&field_id)?;
-    let data = decode_cell_data_from_type_option_cell_data(cell_meta.data, field_meta, &field_meta.field_type).data;
+    let field_rev = field_map.get(&field_id)?;
+    let data = decode_cell_data_from_type_option_cell_data(cell_rev.data, field_rev, &field_rev.field_type).data;
     let cell = Cell::new(&field_id, data);
     Some((field_id, cell))
 }
 
-pub fn make_cell(field_id: &str, field_meta: &FieldMeta, row_meta: &RowMeta) -> Option<Cell> {
-    let cell_meta = row_meta.cells.get(field_id)?.clone();
-    let data = decode_cell_data_from_type_option_cell_data(cell_meta.data, field_meta, &field_meta.field_type).data;
+pub fn make_cell(field_id: &str, field_rev: &FieldRevision, row_rev: &RowRevision) -> Option<Cell> {
+    let cell_rev = row_rev.cells.get(field_id)?.clone();
+    let data = decode_cell_data_from_type_option_cell_data(cell_rev.data, field_rev, &field_rev.field_type).data;
     Some(Cell::new(field_id, data))
 }
 
-pub(crate) fn make_row_orders_from_row_metas(row_metas: &[Arc<RowMeta>]) -> Vec<RowOrder> {
-    row_metas.iter().map(RowOrder::from).collect::<Vec<_>>()
+pub(crate) fn make_row_orders_from_row_revs(row_revs: &[Arc<RowRevision>]) -> Vec<RowOrder> {
+    row_revs.iter().map(RowOrder::from).collect::<Vec<_>>()
 }
 
-pub(crate) fn make_row_from_row_meta(fields: &[FieldMeta], row_meta: Arc<RowMeta>) -> Option<Row> {
-    make_rows_from_row_metas(fields, &[row_meta]).pop()
+pub(crate) fn make_row_from_row_rev(fields: &[FieldRevision], row_rev: Arc<RowRevision>) -> Option<Row> {
+    make_rows_from_row_revs(fields, &[row_rev]).pop()
 }
 
-pub(crate) fn make_rows_from_row_metas(fields: &[FieldMeta], row_metas: &[Arc<RowMeta>]) -> Vec<Row> {
-    let field_meta_map = fields
+pub(crate) fn make_rows_from_row_revs(fields: &[FieldRevision], row_revs: &[Arc<RowRevision>]) -> Vec<Row> {
+    let field_rev_map = fields
         .iter()
-        .map(|field_meta| (&field_meta.id, field_meta))
-        .collect::<HashMap<&String, &FieldMeta>>();
+        .map(|field_rev| (&field_rev.id, field_rev))
+        .collect::<HashMap<&String, &FieldRevision>>();
 
-    let make_row = |row_meta: &Arc<RowMeta>| {
-        let cell_by_field_id = row_meta
+    let make_row = |row_rev: &Arc<RowRevision>| {
+        let cell_by_field_id = row_rev
             .cells
             .clone()
             .into_iter()
-            .flat_map(|(field_id, cell_meta)| make_cell_by_field_id(&field_meta_map, field_id, cell_meta))
+            .flat_map(|(field_id, cell_rev)| make_cell_by_field_id(&field_rev_map, field_id, cell_rev))
             .collect::<HashMap<String, Cell>>();
 
         Row {
-            id: row_meta.id.clone(),
+            id: row_rev.id.clone(),
             cell_by_field_id,
-            height: row_meta.height,
+            height: row_rev.height,
         }
     };
 
-    row_metas.iter().map(make_row).collect::<Vec<_>>()
+    row_revs.iter().map(make_row).collect::<Vec<_>>()
 }
 
 pub(crate) fn make_grid_blocks(
@@ -82,23 +81,23 @@ pub(crate) fn make_grid_blocks(
         None => Ok(block_snapshots
             .into_iter()
             .map(|snapshot| {
-                let row_orders = make_row_orders_from_row_metas(&snapshot.row_metas);
+                let row_orders = make_row_orders_from_row_revs(&snapshot.row_revs);
                 GridBlock::new(&snapshot.block_id, row_orders)
             })
             .collect::<Vec<GridBlock>>()
             .into()),
         Some(block_ids) => {
-            let block_meta_data_map: HashMap<&String, &Vec<Arc<RowMeta>>> = block_snapshots
+            let block_meta_data_map: HashMap<&String, &Vec<Arc<RowRevision>>> = block_snapshots
                 .iter()
-                .map(|data| (&data.block_id, &data.row_metas))
+                .map(|data| (&data.block_id, &data.row_revs))
                 .collect();
 
             let mut grid_blocks = vec![];
             for block_id in block_ids {
                 match block_meta_data_map.get(&block_id) {
                     None => {}
-                    Some(row_metas) => {
-                        let row_orders = make_row_orders_from_row_metas(row_metas);
+                    Some(row_revs) => {
+                        let row_orders = make_row_orders_from_row_revs(row_revs);
                         grid_blocks.push(GridBlock::new(&block_id, row_orders));
                     }
                 }

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

@@ -1,5 +1,6 @@
 use crate::services::field::*;
-use flowy_grid_data_model::entities::{BuildGridContext, FieldType};
+use flowy_grid_data_model::entities::FieldType;
+use flowy_grid_data_model::revision::BuildGridContext;
 use flowy_sync::client_grid::GridBuilder;
 
 pub fn make_default_grid() -> BuildGridContext {

+ 36 - 36
frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs

@@ -6,15 +6,15 @@ use flowy_grid::services::field::{
     SingleSelectTypeOption, SELECTION_IDS_SEPARATOR,
 };
 use flowy_grid::services::row::{decode_cell_data_from_type_option_cell_data, CreateRowMetaBuilder};
-use flowy_grid_data_model::entities::{
-    CellChangeset, FieldChangesetParams, FieldType, GridBlockMeta, GridBlockMetaChangeset, RowMetaChangeset,
-    TypeOptionDataEntry,
+use flowy_grid_data_model::entities::{CellChangeset, FieldChangesetParams, FieldType};
+use flowy_grid_data_model::revision::{
+    GridBlockRevision, GridBlockRevisionChangeset, RowMetaChangeset, TypeOptionDataEntry,
 };
 
 #[tokio::test]
 async fn grid_create_field() {
     let mut test = GridEditorTest::new().await;
-    let (text_field_params, text_field_meta) = create_text_field(&test.grid_id);
+    let (text_field_params, text_field_rev) = create_text_field(&test.grid_id);
     let (single_select_params, single_select_field) = create_single_select_field(&test.grid_id);
     let scripts = vec![
         CreateField {
@@ -22,7 +22,7 @@ async fn grid_create_field() {
         },
         AssertFieldEqual {
             field_index: test.field_count,
-            field_meta: text_field_meta,
+            field_rev: text_field_rev,
         },
     ];
     test.run_scripts(scripts).await;
@@ -33,7 +33,7 @@ async fn grid_create_field() {
         },
         AssertFieldEqual {
             field_index: test.field_count,
-            field_meta: single_select_field,
+            field_rev: single_select_field,
         },
     ];
     test.run_scripts(scripts).await;
@@ -56,9 +56,9 @@ async fn grid_create_duplicate_field() {
 #[tokio::test]
 async fn grid_update_field_with_empty_change() {
     let mut test = GridEditorTest::new().await;
-    let (params, field_meta) = create_single_select_field(&test.grid_id);
+    let (params, field_rev) = create_single_select_field(&test.grid_id);
     let changeset = FieldChangesetParams {
-        field_id: field_meta.id.clone(),
+        field_id: field_rev.id.clone(),
         grid_id: test.grid_id.clone(),
         ..Default::default()
     };
@@ -68,7 +68,7 @@ async fn grid_update_field_with_empty_change() {
         UpdateField { changeset },
         AssertFieldEqual {
             field_index: test.field_count,
-            field_meta,
+            field_rev,
         },
     ];
     test.run_scripts(scripts).await;
@@ -102,7 +102,7 @@ async fn grid_update_field() {
         UpdateField { changeset },
         AssertFieldEqual {
             field_index: test.field_count,
-            field_meta: cloned_field,
+            field_rev: cloned_field,
         },
     ];
     test.run_scripts(scripts).await;
@@ -115,7 +115,7 @@ async fn grid_delete_field() {
     let (text_params, text_field) = create_text_field(&test.grid_id);
     let scripts = vec![
         CreateField { params: text_params },
-        DeleteField { field_meta: text_field },
+        DeleteField { field_rev: text_field },
         AssertFieldCount(expected_field_count),
     ];
     test.run_scripts(scripts).await;
@@ -123,7 +123,7 @@ async fn grid_delete_field() {
 
 #[tokio::test]
 async fn grid_create_block() {
-    let grid_block = GridBlockMeta::new();
+    let grid_block = GridBlockRevision::new();
     let scripts = vec![
         AssertBlockCount(1),
         CreateBlock { block: grid_block },
@@ -134,9 +134,9 @@ async fn grid_create_block() {
 
 #[tokio::test]
 async fn grid_update_block() {
-    let grid_block = GridBlockMeta::new();
+    let grid_block = GridBlockRevision::new();
     let mut cloned_grid_block = grid_block.clone();
-    let changeset = GridBlockMetaChangeset {
+    let changeset = GridBlockRevisionChangeset {
         block_id: grid_block.block_id.clone(),
         start_row_index: Some(2),
         row_count: Some(10),
@@ -167,7 +167,7 @@ async fn grid_create_row() {
 #[tokio::test]
 async fn grid_create_row2() {
     let mut test = GridEditorTest::new().await;
-    let create_row_context = CreateRowMetaBuilder::new(&test.field_metas).build();
+    let create_row_context = CreateRowMetaBuilder::new(&test.field_revs).build();
     let scripts = vec![
         AssertRowCount(3),
         CreateRow {
@@ -181,7 +181,7 @@ async fn grid_create_row2() {
 #[tokio::test]
 async fn grid_update_row() {
     let mut test = GridEditorTest::new().await;
-    let context = CreateRowMetaBuilder::new(&test.field_metas).build();
+    let context = CreateRowMetaBuilder::new(&test.field_revs).build();
     let changeset = RowMetaChangeset {
         row_id: context.row_id.clone(),
         height: None,
@@ -204,8 +204,8 @@ async fn grid_update_row() {
 #[tokio::test]
 async fn grid_delete_row() {
     let mut test = GridEditorTest::new().await;
-    let context_1 = CreateRowMetaBuilder::new(&test.field_metas).build();
-    let context_2 = CreateRowMetaBuilder::new(&test.field_metas).build();
+    let context_1 = CreateRowMetaBuilder::new(&test.field_revs).build();
+    let context_2 = CreateRowMetaBuilder::new(&test.field_revs).build();
     let row_ids = vec![context_1.row_id.clone(), context_2.row_id.clone()];
     let scripts = vec![
         AssertRowCount(3),
@@ -230,8 +230,8 @@ async fn grid_delete_row() {
 #[tokio::test]
 async fn grid_row_add_cells_test() {
     let mut test = GridEditorTest::new().await;
-    let mut builder = CreateRowMetaBuilder::new(&test.field_metas);
-    for field in &test.field_metas {
+    let mut builder = CreateRowMetaBuilder::new(&test.field_revs);
+    for field in &test.field_revs {
         match field.field_type {
             FieldType::RichText => {
                 builder.add_cell(&field.id, "hello world".to_owned()).unwrap();
@@ -275,10 +275,10 @@ async fn grid_row_add_cells_test() {
 #[tokio::test]
 async fn grid_row_add_date_cell_test() {
     let mut test = GridEditorTest::new().await;
-    let mut builder = CreateRowMetaBuilder::new(&test.field_metas);
+    let mut builder = CreateRowMetaBuilder::new(&test.field_revs);
     let mut date_field = None;
     let timestamp = 1647390674;
-    for field in &test.field_metas {
+    for field in &test.field_revs {
         if field.field_type == FieldType::DateTime {
             date_field = Some(field.clone());
             NaiveDateTime::from_timestamp(123, 0);
@@ -307,27 +307,27 @@ async fn grid_row_add_date_cell_test() {
 #[tokio::test]
 async fn grid_cell_update() {
     let mut test = GridEditorTest::new().await;
-    let field_metas = &test.field_metas;
-    let row_metas = &test.row_metas;
-    let grid_blocks = &test.grid_blocks;
-    assert_eq!(row_metas.len(), 3);
+    let field_revs = &test.field_revs;
+    let row_revs = &test.row_revs;
+    let grid_blocks = &test.grid_block_revs;
+    assert_eq!(row_revs.len(), 3);
     assert_eq!(grid_blocks.len(), 1);
 
     let block_id = &grid_blocks.first().unwrap().block_id;
     let mut scripts = vec![];
-    for (index, row_meta) in row_metas.iter().enumerate() {
-        for field_meta in field_metas {
+    for (index, row_rev) in row_revs.iter().enumerate() {
+        for field_rev in field_revs {
             if index == 0 {
-                let data = match field_meta.field_type {
+                let data = match field_rev.field_type {
                     FieldType::RichText => "".to_string(),
                     FieldType::Number => "123".to_string(),
                     FieldType::DateTime => make_date_cell_string("123"),
                     FieldType::SingleSelect => {
-                        let type_option = SingleSelectTypeOption::from(field_meta);
+                        let type_option = SingleSelectTypeOption::from(field_rev);
                         SelectOptionCellContentChangeset::from_insert(&type_option.options.first().unwrap().id).to_str()
                     }
                     FieldType::MultiSelect => {
-                        let type_option = MultiSelectTypeOption::from(field_meta);
+                        let type_option = MultiSelectTypeOption::from(field_rev);
                         SelectOptionCellContentChangeset::from_insert(&type_option.options.first().unwrap().id).to_str()
                     }
                     FieldType::Checkbox => "1".to_string(),
@@ -337,8 +337,8 @@ async fn grid_cell_update() {
                 scripts.push(UpdateCell {
                     changeset: CellChangeset {
                         grid_id: block_id.to_string(),
-                        row_id: row_meta.id.clone(),
-                        field_id: field_meta.id.clone(),
+                        row_id: row_rev.id.clone(),
+                        field_id: field_rev.id.clone(),
                         cell_content_changeset: Some(data),
                     },
                     is_err: false,
@@ -346,7 +346,7 @@ async fn grid_cell_update() {
             }
 
             if index == 1 {
-                let (data, is_err) = match field_meta.field_type {
+                let (data, is_err) = match field_rev.field_type {
                     FieldType::RichText => ("1".to_string().repeat(10001), true),
                     FieldType::Number => ("abc".to_string(), true),
                     FieldType::DateTime => ("abc".to_string(), true),
@@ -359,8 +359,8 @@ async fn grid_cell_update() {
                 scripts.push(UpdateCell {
                     changeset: CellChangeset {
                         grid_id: block_id.to_string(),
-                        row_id: row_meta.id.clone(),
-                        field_id: field_meta.id.clone(),
+                        row_id: row_rev.id.clone(),
+                        field_id: field_rev.id.clone(),
                         cell_content_changeset: Some(data),
                     },
                     is_err,

+ 72 - 78
frontend/rust-lib/flowy-grid/tests/grid/script.rs

@@ -3,8 +3,11 @@ use flowy_grid::services::field::*;
 use flowy_grid::services::grid_editor::{GridMetaEditor, GridPadBuilder};
 use flowy_grid::services::row::CreateRowMetaPayload;
 use flowy_grid_data_model::entities::{
-    BuildGridContext, CellChangeset, Field, FieldChangesetParams, FieldMeta, FieldOrder, FieldType, GridBlockMeta,
-    GridBlockMetaChangeset, InsertFieldParams, RowMeta, RowMetaChangeset, RowOrder, TypeOptionDataEntry,
+    CellChangeset, Field, FieldChangesetParams, FieldOrder, FieldType, InsertFieldParams, RowOrder,
+};
+use flowy_grid_data_model::revision::{
+    BuildGridContext, FieldRevision, GridBlockRevision, GridBlockRevisionChangeset, RowMetaChangeset, RowRevision,
+    TypeOptionDataEntry,
 };
 use flowy_revision::REVISION_WRITE_INTERVAL_IN_MILLIS;
 use flowy_sync::client_grid::GridBuilder;
@@ -24,18 +27,18 @@ pub enum EditorScript {
         changeset: FieldChangesetParams,
     },
     DeleteField {
-        field_meta: FieldMeta,
+        field_rev: FieldRevision,
     },
     AssertFieldCount(usize),
     AssertFieldEqual {
         field_index: usize,
-        field_meta: FieldMeta,
+        field_rev: FieldRevision,
     },
     CreateBlock {
-        block: GridBlockMeta,
+        block: GridBlockRevision,
     },
     UpdateBlock {
-        changeset: GridBlockMetaChangeset,
+        changeset: GridBlockRevisionChangeset,
     },
     AssertBlockCount(usize),
     AssertBlock {
@@ -45,7 +48,7 @@ pub enum EditorScript {
     },
     AssertBlockEqual {
         block_index: usize,
-        block: GridBlockMeta,
+        block: GridBlockRevision,
     },
     CreateEmptyRow,
     CreateRow {
@@ -73,9 +76,9 @@ pub struct GridEditorTest {
     pub sdk: FlowySDKTest,
     pub grid_id: String,
     pub editor: Arc<GridMetaEditor>,
-    pub field_metas: Vec<FieldMeta>,
-    pub grid_blocks: Vec<GridBlockMeta>,
-    pub row_metas: Vec<Arc<RowMeta>>,
+    pub field_revs: Vec<FieldRevision>,
+    pub grid_block_revs: Vec<GridBlockRevision>,
+    pub row_revs: Vec<Arc<RowRevision>>,
     pub field_count: usize,
 
     pub row_order_by_row_id: HashMap<String, RowOrder>,
@@ -89,18 +92,18 @@ impl GridEditorTest {
         let view_data: Bytes = build_context.into();
         let test = ViewTest::new_grid_view(&sdk, view_data.to_vec()).await;
         let editor = sdk.grid_manager.open_grid(&test.view.id).await.unwrap();
-        let field_metas = editor.get_field_metas::<FieldOrder>(None).await.unwrap();
+        let field_revs = editor.get_field_revs::<FieldOrder>(None).await.unwrap();
         let grid_blocks = editor.get_block_metas().await.unwrap();
-        let row_metas = get_row_metas(&editor).await;
+        let row_revs = get_row_revs(&editor).await;
 
         let grid_id = test.view.id;
         Self {
             sdk,
             grid_id,
             editor,
-            field_metas,
-            grid_blocks,
-            row_metas,
+            field_revs: field_revs,
+            grid_block_revs: grid_blocks,
+            row_revs: row_revs,
             field_count: FieldType::COUNT,
             row_order_by_row_id: HashMap::default(),
         }
@@ -125,38 +128,35 @@ impl GridEditorTest {
                 }
 
                 self.editor.insert_field(params).await.unwrap();
-                self.field_metas = self.editor.get_field_metas::<FieldOrder>(None).await.unwrap();
-                assert_eq!(self.field_count, self.field_metas.len());
+                self.field_revs = self.editor.get_field_revs::<FieldOrder>(None).await.unwrap();
+                assert_eq!(self.field_count, self.field_revs.len());
             }
             EditorScript::UpdateField { changeset: change } => {
                 self.editor.update_field(change).await.unwrap();
-                self.field_metas = self.editor.get_field_metas::<FieldOrder>(None).await.unwrap();
+                self.field_revs = self.editor.get_field_revs::<FieldOrder>(None).await.unwrap();
             }
-            EditorScript::DeleteField { field_meta } => {
-                if self.editor.contain_field(&field_meta.id).await {
+            EditorScript::DeleteField { field_rev } => {
+                if self.editor.contain_field(&field_rev.id).await {
                     self.field_count -= 1;
                 }
 
-                self.editor.delete_field(&field_meta.id).await.unwrap();
-                self.field_metas = self.editor.get_field_metas::<FieldOrder>(None).await.unwrap();
-                assert_eq!(self.field_count, self.field_metas.len());
+                self.editor.delete_field(&field_rev.id).await.unwrap();
+                self.field_revs = self.editor.get_field_revs::<FieldOrder>(None).await.unwrap();
+                assert_eq!(self.field_count, self.field_revs.len());
             }
             EditorScript::AssertFieldCount(count) => {
                 assert_eq!(
-                    self.editor.get_field_metas::<FieldOrder>(None).await.unwrap().len(),
+                    self.editor.get_field_revs::<FieldOrder>(None).await.unwrap().len(),
                     count
                 );
             }
-            EditorScript::AssertFieldEqual {
-                field_index,
-                field_meta,
-            } => {
-                let field_metas = self.editor.get_field_metas::<FieldOrder>(None).await.unwrap();
-                assert_eq!(field_metas[field_index].clone(), field_meta);
+            EditorScript::AssertFieldEqual { field_index, field_rev } => {
+                let field_revs = self.editor.get_field_revs::<FieldOrder>(None).await.unwrap();
+                assert_eq!(field_revs[field_index].clone(), field_rev);
             }
             EditorScript::CreateBlock { block } => {
                 self.editor.create_block(block).await.unwrap();
-                self.grid_blocks = self.editor.get_block_metas().await.unwrap();
+                self.grid_block_revs = self.editor.get_block_metas().await.unwrap();
             }
             EditorScript::UpdateBlock { changeset: change } => {
                 self.editor.update_block(change).await.unwrap();
@@ -169,8 +169,8 @@ impl GridEditorTest {
                 row_count,
                 start_row_index,
             } => {
-                assert_eq!(self.grid_blocks[block_index].row_count, row_count);
-                assert_eq!(self.grid_blocks[block_index].start_row_index, start_row_index);
+                assert_eq!(self.grid_block_revs[block_index].row_count, row_count);
+                assert_eq!(self.grid_block_revs[block_index].start_row_index, start_row_index);
             }
             EditorScript::AssertBlockEqual { block_index, block } => {
                 let blocks = self.editor.get_block_metas().await.unwrap();
@@ -180,16 +180,16 @@ impl GridEditorTest {
             EditorScript::CreateEmptyRow => {
                 let row_order = self.editor.create_row(None).await.unwrap();
                 self.row_order_by_row_id.insert(row_order.row_id.clone(), row_order);
-                self.row_metas = self.get_row_metas().await;
-                self.grid_blocks = self.editor.get_block_metas().await.unwrap();
+                self.row_revs = self.get_row_revs().await;
+                self.grid_block_revs = self.editor.get_block_metas().await.unwrap();
             }
             EditorScript::CreateRow { context } => {
                 let row_orders = self.editor.insert_rows(vec![context]).await.unwrap();
                 for row_order in row_orders {
                     self.row_order_by_row_id.insert(row_order.row_id.clone(), row_order);
                 }
-                self.row_metas = self.get_row_metas().await;
-                self.grid_blocks = self.editor.get_block_metas().await.unwrap();
+                self.row_revs = self.get_row_revs().await;
+                self.grid_block_revs = self.editor.get_block_metas().await.unwrap();
             }
             EditorScript::UpdateRow { changeset: change } => self.editor.update_row(change).await.unwrap(),
             EditorScript::DeleteRow { row_ids } => {
@@ -199,11 +199,11 @@ impl GridEditorTest {
                     .collect::<Vec<RowOrder>>();
 
                 self.editor.delete_rows(row_orders).await.unwrap();
-                self.row_metas = self.get_row_metas().await;
-                self.grid_blocks = self.editor.get_block_metas().await.unwrap();
+                self.row_revs = self.get_row_revs().await;
+                self.grid_block_revs = self.editor.get_block_metas().await.unwrap();
             }
             EditorScript::AssertRow { changeset } => {
-                let row = self.row_metas.iter().find(|row| row.id == changeset.row_id).unwrap();
+                let row = self.row_revs.iter().find(|row| row.id == changeset.row_id).unwrap();
 
                 if let Some(visibility) = changeset.visibility {
                     assert_eq!(row.visibility, visibility);
@@ -219,11 +219,11 @@ impl GridEditorTest {
                     assert!(result.is_err())
                 } else {
                     let _ = result.unwrap();
-                    self.row_metas = self.get_row_metas().await;
+                    self.row_revs = self.get_row_revs().await;
                 }
             }
             EditorScript::AssertRowCount(count) => {
-                assert_eq!(self.row_metas.len(), count);
+                assert_eq!(self.row_revs.len(), count);
             }
             EditorScript::AssertGridMetaPad => {
                 sleep(Duration::from_millis(2 * REVISION_WRITE_INTERVAL_IN_MILLIS)).await;
@@ -234,43 +234,37 @@ impl GridEditorTest {
         }
     }
 
-    async fn get_row_metas(&self) -> Vec<Arc<RowMeta>> {
-        get_row_metas(&self.editor).await
+    async fn get_row_revs(&self) -> Vec<Arc<RowRevision>> {
+        get_row_revs(&self.editor).await
     }
 }
 
-async fn get_row_metas(editor: &Arc<GridMetaEditor>) -> Vec<Arc<RowMeta>> {
-    editor
-        .grid_block_snapshots(None)
-        .await
-        .unwrap()
-        .pop()
-        .unwrap()
-        .row_metas
+async fn get_row_revs(editor: &Arc<GridMetaEditor>) -> Vec<Arc<RowRevision>> {
+    editor.grid_block_snapshots(None).await.unwrap().pop().unwrap().row_revs
 }
 
-pub fn create_text_field(grid_id: &str) -> (InsertFieldParams, FieldMeta) {
-    let field_meta = FieldBuilder::new(RichTextTypeOptionBuilder::default())
+pub fn create_text_field(grid_id: &str) -> (InsertFieldParams, FieldRevision) {
+    let field_rev = FieldBuilder::new(RichTextTypeOptionBuilder::default())
         .name("Name")
         .visibility(true)
         .build();
 
-    let cloned_field_meta = field_meta.clone();
+    let cloned_field_rev = field_rev.clone();
 
-    let type_option_data = field_meta
-        .get_type_option_entry::<RichTextTypeOption>(&field_meta.field_type)
+    let type_option_data = field_rev
+        .get_type_option_entry::<RichTextTypeOption>(&field_rev.field_type)
         .unwrap()
         .protobuf_bytes()
         .to_vec();
 
     let field = Field {
-        id: field_meta.id,
-        name: field_meta.name,
-        desc: field_meta.desc,
-        field_type: field_meta.field_type,
-        frozen: field_meta.frozen,
-        visibility: field_meta.visibility,
-        width: field_meta.width,
+        id: field_rev.id,
+        name: field_rev.name,
+        desc: field_rev.desc,
+        field_type: field_rev.field_type,
+        frozen: field_rev.frozen,
+        visibility: field_rev.visibility,
+        width: field_rev.width,
         is_primary: false,
     };
 
@@ -280,30 +274,30 @@ pub fn create_text_field(grid_id: &str) -> (InsertFieldParams, FieldMeta) {
         type_option_data,
         start_field_id: None,
     };
-    (params, cloned_field_meta)
+    (params, cloned_field_rev)
 }
 
-pub fn create_single_select_field(grid_id: &str) -> (InsertFieldParams, FieldMeta) {
+pub fn create_single_select_field(grid_id: &str) -> (InsertFieldParams, FieldRevision) {
     let single_select = SingleSelectTypeOptionBuilder::default()
         .option(SelectOption::new("Done"))
         .option(SelectOption::new("Progress"));
 
-    let field_meta = FieldBuilder::new(single_select).name("Name").visibility(true).build();
-    let cloned_field_meta = field_meta.clone();
-    let type_option_data = field_meta
-        .get_type_option_entry::<SingleSelectTypeOption>(&field_meta.field_type)
+    let field_rev = FieldBuilder::new(single_select).name("Name").visibility(true).build();
+    let cloned_field_rev = field_rev.clone();
+    let type_option_data = field_rev
+        .get_type_option_entry::<SingleSelectTypeOption>(&field_rev.field_type)
         .unwrap()
         .protobuf_bytes()
         .to_vec();
 
     let field = Field {
-        id: field_meta.id,
-        name: field_meta.name,
-        desc: field_meta.desc,
-        field_type: field_meta.field_type,
-        frozen: field_meta.frozen,
-        visibility: field_meta.visibility,
-        width: field_meta.width,
+        id: field_rev.id,
+        name: field_rev.name,
+        desc: field_rev.desc,
+        field_type: field_rev.field_type,
+        frozen: field_rev.frozen,
+        visibility: field_rev.visibility,
+        width: field_rev.width,
         is_primary: false,
     };
 
@@ -313,7 +307,7 @@ pub fn create_single_select_field(grid_id: &str) -> (InsertFieldParams, FieldMet
         type_option_data,
         start_field_id: None,
     };
-    (params, cloned_field_meta)
+    (params, cloned_field_rev)
 }
 
 fn make_template_1_grid() -> BuildGridContext {

+ 6 - 9
frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs

@@ -1,10 +1,6 @@
 use bytes::Bytes;
 use flowy_database::ConnectionPool;
-use flowy_sync::client_document::default::initial_quill_delta_string;
-use flowy_sync::entities::revision::{RepeatedRevision, Revision};
-use flowy_sync::entities::ws_data::ClientRevisionWSData;
-use flowy_text_block::TextBlockManager;
-
+use flowy_folder::entities::UpdateViewInfoParams;
 use flowy_folder::manager::{ViewDataProcessor, ViewDataProcessorMap};
 use flowy_folder::prelude::ViewDataType;
 use flowy_folder::{
@@ -14,20 +10,21 @@ use flowy_folder::{
 };
 use flowy_grid::manager::{make_grid_view_data, GridManager};
 use flowy_grid::util::make_default_grid;
-
+use flowy_grid_data_model::revision::BuildGridContext;
 use flowy_net::ClientServerConfiguration;
 use flowy_net::{
     http_server::folder::FolderHttpCloudService, local_server::LocalServer, ws::connection::FlowyWebSocketConnect,
 };
 use flowy_revision::{RevisionWebSocket, WSStateReceiver};
+use flowy_sync::client_document::default::initial_quill_delta_string;
+use flowy_sync::entities::revision::{RepeatedRevision, Revision};
+use flowy_sync::entities::ws_data::ClientRevisionWSData;
+use flowy_text_block::TextBlockManager;
 use flowy_user::services::UserSession;
 use futures_core::future::BoxFuture;
 use lib_infra::future::{BoxResultFuture, FutureResult};
 use lib_ws::{WSChannel, WSMessageReceiver, WebSocketRawMessage};
 use std::collections::HashMap;
-
-use flowy_folder::entities::UpdateViewInfoParams;
-use flowy_grid_data_model::entities::BuildGridContext;
 use std::convert::TryFrom;
 use std::{convert::TryInto, sync::Arc};
 

+ 6 - 3
shared-lib/flowy-error-code/src/protobuf/model/code.rs

@@ -68,6 +68,7 @@ pub enum ErrorCode {
     FieldInvalidOperation = 444,
     TypeOptionDataIsEmpty = 450,
     InvalidDateTimeFormat = 500,
+    UnexpectedEmptyString = 999,
     InvalidData = 1000,
 }
 
@@ -121,6 +122,7 @@ impl ::protobuf::ProtobufEnum for ErrorCode {
             444 => ::std::option::Option::Some(ErrorCode::FieldInvalidOperation),
             450 => ::std::option::Option::Some(ErrorCode::TypeOptionDataIsEmpty),
             500 => ::std::option::Option::Some(ErrorCode::InvalidDateTimeFormat),
+            999 => ::std::option::Option::Some(ErrorCode::UnexpectedEmptyString),
             1000 => ::std::option::Option::Some(ErrorCode::InvalidData),
             _ => ::std::option::Option::None
         }
@@ -171,6 +173,7 @@ impl ::protobuf::ProtobufEnum for ErrorCode {
             ErrorCode::FieldInvalidOperation,
             ErrorCode::TypeOptionDataIsEmpty,
             ErrorCode::InvalidDateTimeFormat,
+            ErrorCode::UnexpectedEmptyString,
             ErrorCode::InvalidData,
         ];
         values
@@ -200,7 +203,7 @@ impl ::protobuf::reflect::ProtobufValue for ErrorCode {
 }
 
 static file_descriptor_proto_data: &'static [u8] = b"\
-    \n\ncode.proto*\x81\x08\n\tErrorCode\x12\x0c\n\x08Internal\x10\0\x12\x14\
+    \n\ncode.proto*\x9d\x08\n\tErrorCode\x12\x0c\n\x08Internal\x10\0\x12\x14\
     \n\x10UserUnauthorized\x10\x02\x12\x12\n\x0eRecordNotFound\x10\x03\x12\
     \x11\n\rUserIdIsEmpty\x10\x04\x12\x18\n\x14WorkspaceNameInvalid\x10d\x12\
     \x16\n\x12WorkspaceIdInvalid\x10e\x12\x18\n\x14AppColorStyleInvalid\x10f\
@@ -224,8 +227,8 @@ static file_descriptor_proto_data: &'static [u8] = b"\
     \x10\xb9\x03\x12\x1c\n\x17SelectOptionNameIsEmpty\x10\xba\x03\x12\x13\n\
     \x0eFieldNotExists\x10\xbb\x03\x12\x1a\n\x15FieldInvalidOperation\x10\
     \xbc\x03\x12\x1a\n\x15TypeOptionDataIsEmpty\x10\xc2\x03\x12\x1a\n\x15Inv\
-    alidDateTimeFormat\x10\xf4\x03\x12\x10\n\x0bInvalidData\x10\xe8\x07b\x06\
-    proto3\
+    alidDateTimeFormat\x10\xf4\x03\x12\x1a\n\x15UnexpectedEmptyString\x10\
+    \xe7\x07\x12\x10\n\x0bInvalidData\x10\xe8\x07b\x06proto3\
 ";
 
 static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

+ 1 - 0
shared-lib/flowy-error-code/src/protobuf/proto/code.proto

@@ -44,5 +44,6 @@ enum ErrorCode {
     FieldInvalidOperation = 444;
     TypeOptionDataIsEmpty = 450;
     InvalidDateTimeFormat = 500;
+    UnexpectedEmptyString = 999;
     InvalidData = 1000;
 }

+ 533 - 101
shared-lib/flowy-folder-data-model/src/protobuf/model/view_info.rs

@@ -744,7 +744,7 @@ impl ::protobuf::reflect::ProtobufValue for ViewExtData {
 #[derive(PartialEq,Clone,Default)]
 pub struct ViewFilter {
     // message fields
-    pub field_id: ::std::string::String,
+    pub object_id: ::std::string::String,
     // special fields
     pub unknown_fields: ::protobuf::UnknownFields,
     pub cached_size: ::protobuf::CachedSize,
@@ -761,30 +761,30 @@ impl ViewFilter {
         ::std::default::Default::default()
     }
 
-    // string field_id = 1;
+    // string object_id = 1;
 
 
-    pub fn get_field_id(&self) -> &str {
-        &self.field_id
+    pub fn get_object_id(&self) -> &str {
+        &self.object_id
     }
-    pub fn clear_field_id(&mut self) {
-        self.field_id.clear();
+    pub fn clear_object_id(&mut self) {
+        self.object_id.clear();
     }
 
     // Param is passed by value, moved
-    pub fn set_field_id(&mut self, v: ::std::string::String) {
-        self.field_id = v;
+    pub fn set_object_id(&mut self, v: ::std::string::String) {
+        self.object_id = v;
     }
 
     // Mutable pointer to the field.
     // If field is not initialized, it is initialized with default value first.
-    pub fn mut_field_id(&mut self) -> &mut ::std::string::String {
-        &mut self.field_id
+    pub fn mut_object_id(&mut self) -> &mut ::std::string::String {
+        &mut self.object_id
     }
 
     // Take field
-    pub fn take_field_id(&mut self) -> ::std::string::String {
-        ::std::mem::replace(&mut self.field_id, ::std::string::String::new())
+    pub fn take_object_id(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.object_id, ::std::string::String::new())
     }
 }
 
@@ -798,7 +798,7 @@ impl ::protobuf::Message for ViewFilter {
             let (field_number, wire_type) = is.read_tag_unpack()?;
             match field_number {
                 1 => {
-                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?;
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.object_id)?;
                 },
                 _ => {
                     ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
@@ -812,8 +812,8 @@ impl ::protobuf::Message for ViewFilter {
     #[allow(unused_variables)]
     fn compute_size(&self) -> u32 {
         let mut my_size = 0;
-        if !self.field_id.is_empty() {
-            my_size += ::protobuf::rt::string_size(1, &self.field_id);
+        if !self.object_id.is_empty() {
+            my_size += ::protobuf::rt::string_size(1, &self.object_id);
         }
         my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
         self.cached_size.set(my_size);
@@ -821,8 +821,8 @@ impl ::protobuf::Message for ViewFilter {
     }
 
     fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
-        if !self.field_id.is_empty() {
-            os.write_string(1, &self.field_id)?;
+        if !self.object_id.is_empty() {
+            os.write_string(1, &self.object_id)?;
         }
         os.write_unknown_fields(self.get_unknown_fields())?;
         ::std::result::Result::Ok(())
@@ -863,9 +863,9 @@ impl ::protobuf::Message for ViewFilter {
         descriptor.get(|| {
             let mut fields = ::std::vec::Vec::new();
             fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
-                "field_id",
-                |m: &ViewFilter| { &m.field_id },
-                |m: &mut ViewFilter| { &mut m.field_id },
+                "object_id",
+                |m: &ViewFilter| { &m.object_id },
+                |m: &mut ViewFilter| { &mut m.object_id },
             ));
             ::protobuf::reflect::MessageDescriptor::new_pb_name::<ViewFilter>(
                 "ViewFilter",
@@ -883,7 +883,7 @@ impl ::protobuf::Message for ViewFilter {
 
 impl ::protobuf::Clear for ViewFilter {
     fn clear(&mut self) {
-        self.field_id.clear();
+        self.object_id.clear();
         self.unknown_fields.clear();
     }
 }
@@ -903,9 +903,9 @@ impl ::protobuf::reflect::ProtobufValue for ViewFilter {
 #[derive(PartialEq,Clone,Default)]
 pub struct ViewGroup {
     // message fields
-    pub group_field_id: ::std::string::String,
+    pub group_object_id: ::std::string::String,
     // message oneof groups
-    pub one_of_sub_group_field_id: ::std::option::Option<ViewGroup_oneof_one_of_sub_group_field_id>,
+    pub one_of_sub_group_object_id: ::std::option::Option<ViewGroup_oneof_one_of_sub_group_object_id>,
     // special fields
     pub unknown_fields: ::protobuf::UnknownFields,
     pub cached_size: ::protobuf::CachedSize,
@@ -918,8 +918,8 @@ impl<'a> ::std::default::Default for &'a ViewGroup {
 }
 
 #[derive(Clone,PartialEq,Debug)]
-pub enum ViewGroup_oneof_one_of_sub_group_field_id {
-    sub_group_field_id(::std::string::String),
+pub enum ViewGroup_oneof_one_of_sub_group_object_id {
+    sub_group_object_id(::std::string::String),
 }
 
 impl ViewGroup {
@@ -927,74 +927,74 @@ impl ViewGroup {
         ::std::default::Default::default()
     }
 
-    // string group_field_id = 1;
+    // string group_object_id = 1;
 
 
-    pub fn get_group_field_id(&self) -> &str {
-        &self.group_field_id
+    pub fn get_group_object_id(&self) -> &str {
+        &self.group_object_id
     }
-    pub fn clear_group_field_id(&mut self) {
-        self.group_field_id.clear();
+    pub fn clear_group_object_id(&mut self) {
+        self.group_object_id.clear();
     }
 
     // Param is passed by value, moved
-    pub fn set_group_field_id(&mut self, v: ::std::string::String) {
-        self.group_field_id = v;
+    pub fn set_group_object_id(&mut self, v: ::std::string::String) {
+        self.group_object_id = v;
     }
 
     // Mutable pointer to the field.
     // If field is not initialized, it is initialized with default value first.
-    pub fn mut_group_field_id(&mut self) -> &mut ::std::string::String {
-        &mut self.group_field_id
+    pub fn mut_group_object_id(&mut self) -> &mut ::std::string::String {
+        &mut self.group_object_id
     }
 
     // Take field
-    pub fn take_group_field_id(&mut self) -> ::std::string::String {
-        ::std::mem::replace(&mut self.group_field_id, ::std::string::String::new())
+    pub fn take_group_object_id(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.group_object_id, ::std::string::String::new())
     }
 
-    // string sub_group_field_id = 2;
+    // string sub_group_object_id = 2;
 
 
-    pub fn get_sub_group_field_id(&self) -> &str {
-        match self.one_of_sub_group_field_id {
-            ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_field_id::sub_group_field_id(ref v)) => v,
+    pub fn get_sub_group_object_id(&self) -> &str {
+        match self.one_of_sub_group_object_id {
+            ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_object_id::sub_group_object_id(ref v)) => v,
             _ => "",
         }
     }
-    pub fn clear_sub_group_field_id(&mut self) {
-        self.one_of_sub_group_field_id = ::std::option::Option::None;
+    pub fn clear_sub_group_object_id(&mut self) {
+        self.one_of_sub_group_object_id = ::std::option::Option::None;
     }
 
-    pub fn has_sub_group_field_id(&self) -> bool {
-        match self.one_of_sub_group_field_id {
-            ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_field_id::sub_group_field_id(..)) => true,
+    pub fn has_sub_group_object_id(&self) -> bool {
+        match self.one_of_sub_group_object_id {
+            ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_object_id::sub_group_object_id(..)) => true,
             _ => false,
         }
     }
 
     // Param is passed by value, moved
-    pub fn set_sub_group_field_id(&mut self, v: ::std::string::String) {
-        self.one_of_sub_group_field_id = ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_field_id::sub_group_field_id(v))
+    pub fn set_sub_group_object_id(&mut self, v: ::std::string::String) {
+        self.one_of_sub_group_object_id = ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_object_id::sub_group_object_id(v))
     }
 
     // Mutable pointer to the field.
-    pub fn mut_sub_group_field_id(&mut self) -> &mut ::std::string::String {
-        if let ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_field_id::sub_group_field_id(_)) = self.one_of_sub_group_field_id {
+    pub fn mut_sub_group_object_id(&mut self) -> &mut ::std::string::String {
+        if let ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_object_id::sub_group_object_id(_)) = self.one_of_sub_group_object_id {
         } else {
-            self.one_of_sub_group_field_id = ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_field_id::sub_group_field_id(::std::string::String::new()));
+            self.one_of_sub_group_object_id = ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_object_id::sub_group_object_id(::std::string::String::new()));
         }
-        match self.one_of_sub_group_field_id {
-            ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_field_id::sub_group_field_id(ref mut v)) => v,
+        match self.one_of_sub_group_object_id {
+            ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_object_id::sub_group_object_id(ref mut v)) => v,
             _ => panic!(),
         }
     }
 
     // Take field
-    pub fn take_sub_group_field_id(&mut self) -> ::std::string::String {
-        if self.has_sub_group_field_id() {
-            match self.one_of_sub_group_field_id.take() {
-                ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_field_id::sub_group_field_id(v)) => v,
+    pub fn take_sub_group_object_id(&mut self) -> ::std::string::String {
+        if self.has_sub_group_object_id() {
+            match self.one_of_sub_group_object_id.take() {
+                ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_object_id::sub_group_object_id(v)) => v,
                 _ => panic!(),
             }
         } else {
@@ -1013,13 +1013,13 @@ impl ::protobuf::Message for ViewGroup {
             let (field_number, wire_type) = is.read_tag_unpack()?;
             match field_number {
                 1 => {
-                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.group_field_id)?;
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.group_object_id)?;
                 },
                 2 => {
                     if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
                         return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
                     }
-                    self.one_of_sub_group_field_id = ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_field_id::sub_group_field_id(is.read_string()?));
+                    self.one_of_sub_group_object_id = ::std::option::Option::Some(ViewGroup_oneof_one_of_sub_group_object_id::sub_group_object_id(is.read_string()?));
                 },
                 _ => {
                     ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
@@ -1033,12 +1033,12 @@ impl ::protobuf::Message for ViewGroup {
     #[allow(unused_variables)]
     fn compute_size(&self) -> u32 {
         let mut my_size = 0;
-        if !self.group_field_id.is_empty() {
-            my_size += ::protobuf::rt::string_size(1, &self.group_field_id);
+        if !self.group_object_id.is_empty() {
+            my_size += ::protobuf::rt::string_size(1, &self.group_object_id);
         }
-        if let ::std::option::Option::Some(ref v) = self.one_of_sub_group_field_id {
+        if let ::std::option::Option::Some(ref v) = self.one_of_sub_group_object_id {
             match v {
-                &ViewGroup_oneof_one_of_sub_group_field_id::sub_group_field_id(ref v) => {
+                &ViewGroup_oneof_one_of_sub_group_object_id::sub_group_object_id(ref v) => {
                     my_size += ::protobuf::rt::string_size(2, &v);
                 },
             };
@@ -1049,12 +1049,12 @@ impl ::protobuf::Message for ViewGroup {
     }
 
     fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
-        if !self.group_field_id.is_empty() {
-            os.write_string(1, &self.group_field_id)?;
+        if !self.group_object_id.is_empty() {
+            os.write_string(1, &self.group_object_id)?;
         }
-        if let ::std::option::Option::Some(ref v) = self.one_of_sub_group_field_id {
+        if let ::std::option::Option::Some(ref v) = self.one_of_sub_group_object_id {
             match v {
-                &ViewGroup_oneof_one_of_sub_group_field_id::sub_group_field_id(ref v) => {
+                &ViewGroup_oneof_one_of_sub_group_object_id::sub_group_object_id(ref v) => {
                     os.write_string(2, v)?;
                 },
             };
@@ -1098,14 +1098,14 @@ impl ::protobuf::Message for ViewGroup {
         descriptor.get(|| {
             let mut fields = ::std::vec::Vec::new();
             fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
-                "group_field_id",
-                |m: &ViewGroup| { &m.group_field_id },
-                |m: &mut ViewGroup| { &mut m.group_field_id },
+                "group_object_id",
+                |m: &ViewGroup| { &m.group_object_id },
+                |m: &mut ViewGroup| { &mut m.group_object_id },
             ));
             fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>(
-                "sub_group_field_id",
-                ViewGroup::has_sub_group_field_id,
-                ViewGroup::get_sub_group_field_id,
+                "sub_group_object_id",
+                ViewGroup::has_sub_group_object_id,
+                ViewGroup::get_sub_group_object_id,
             ));
             ::protobuf::reflect::MessageDescriptor::new_pb_name::<ViewGroup>(
                 "ViewGroup",
@@ -1123,8 +1123,8 @@ impl ::protobuf::Message for ViewGroup {
 
 impl ::protobuf::Clear for ViewGroup {
     fn clear(&mut self) {
-        self.group_field_id.clear();
-        self.one_of_sub_group_field_id = ::std::option::Option::None;
+        self.group_object_id.clear();
+        self.one_of_sub_group_object_id = ::std::option::Option::None;
         self.unknown_fields.clear();
     }
 }
@@ -1144,7 +1144,7 @@ impl ::protobuf::reflect::ProtobufValue for ViewGroup {
 #[derive(PartialEq,Clone,Default)]
 pub struct ViewSort {
     // message fields
-    pub field_id: ::std::string::String,
+    pub object_id: ::std::string::String,
     // special fields
     pub unknown_fields: ::protobuf::UnknownFields,
     pub cached_size: ::protobuf::CachedSize,
@@ -1161,30 +1161,30 @@ impl ViewSort {
         ::std::default::Default::default()
     }
 
-    // string field_id = 1;
+    // string object_id = 1;
 
 
-    pub fn get_field_id(&self) -> &str {
-        &self.field_id
+    pub fn get_object_id(&self) -> &str {
+        &self.object_id
     }
-    pub fn clear_field_id(&mut self) {
-        self.field_id.clear();
+    pub fn clear_object_id(&mut self) {
+        self.object_id.clear();
     }
 
     // Param is passed by value, moved
-    pub fn set_field_id(&mut self, v: ::std::string::String) {
-        self.field_id = v;
+    pub fn set_object_id(&mut self, v: ::std::string::String) {
+        self.object_id = v;
     }
 
     // Mutable pointer to the field.
     // If field is not initialized, it is initialized with default value first.
-    pub fn mut_field_id(&mut self) -> &mut ::std::string::String {
-        &mut self.field_id
+    pub fn mut_object_id(&mut self) -> &mut ::std::string::String {
+        &mut self.object_id
     }
 
     // Take field
-    pub fn take_field_id(&mut self) -> ::std::string::String {
-        ::std::mem::replace(&mut self.field_id, ::std::string::String::new())
+    pub fn take_object_id(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.object_id, ::std::string::String::new())
     }
 }
 
@@ -1198,7 +1198,7 @@ impl ::protobuf::Message for ViewSort {
             let (field_number, wire_type) = is.read_tag_unpack()?;
             match field_number {
                 1 => {
-                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?;
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.object_id)?;
                 },
                 _ => {
                     ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
@@ -1212,8 +1212,8 @@ impl ::protobuf::Message for ViewSort {
     #[allow(unused_variables)]
     fn compute_size(&self) -> u32 {
         let mut my_size = 0;
-        if !self.field_id.is_empty() {
-            my_size += ::protobuf::rt::string_size(1, &self.field_id);
+        if !self.object_id.is_empty() {
+            my_size += ::protobuf::rt::string_size(1, &self.object_id);
         }
         my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
         self.cached_size.set(my_size);
@@ -1221,8 +1221,8 @@ impl ::protobuf::Message for ViewSort {
     }
 
     fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
-        if !self.field_id.is_empty() {
-            os.write_string(1, &self.field_id)?;
+        if !self.object_id.is_empty() {
+            os.write_string(1, &self.object_id)?;
         }
         os.write_unknown_fields(self.get_unknown_fields())?;
         ::std::result::Result::Ok(())
@@ -1263,9 +1263,9 @@ impl ::protobuf::Message for ViewSort {
         descriptor.get(|| {
             let mut fields = ::std::vec::Vec::new();
             fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
-                "field_id",
-                |m: &ViewSort| { &m.field_id },
-                |m: &mut ViewSort| { &mut m.field_id },
+                "object_id",
+                |m: &ViewSort| { &m.object_id },
+                |m: &mut ViewSort| { &mut m.object_id },
             ));
             ::protobuf::reflect::MessageDescriptor::new_pb_name::<ViewSort>(
                 "ViewSort",
@@ -1283,7 +1283,7 @@ impl ::protobuf::Message for ViewSort {
 
 impl ::protobuf::Clear for ViewSort {
     fn clear(&mut self) {
-        self.field_id.clear();
+        self.object_id.clear();
         self.unknown_fields.clear();
     }
 }
@@ -1300,6 +1300,433 @@ impl ::protobuf::reflect::ProtobufValue for ViewSort {
     }
 }
 
+#[derive(PartialEq,Clone,Default)]
+pub struct UpdateViewInfoPayload {
+    // message fields
+    pub view_id: ::std::string::String,
+    // message oneof groups
+    pub one_of_filter: ::std::option::Option<UpdateViewInfoPayload_oneof_one_of_filter>,
+    pub one_of_group: ::std::option::Option<UpdateViewInfoPayload_oneof_one_of_group>,
+    pub one_of_sort: ::std::option::Option<UpdateViewInfoPayload_oneof_one_of_sort>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a UpdateViewInfoPayload {
+    fn default() -> &'a UpdateViewInfoPayload {
+        <UpdateViewInfoPayload as ::protobuf::Message>::default_instance()
+    }
+}
+
+#[derive(Clone,PartialEq,Debug)]
+pub enum UpdateViewInfoPayload_oneof_one_of_filter {
+    filter(ViewFilter),
+}
+
+#[derive(Clone,PartialEq,Debug)]
+pub enum UpdateViewInfoPayload_oneof_one_of_group {
+    group(ViewGroup),
+}
+
+#[derive(Clone,PartialEq,Debug)]
+pub enum UpdateViewInfoPayload_oneof_one_of_sort {
+    sort(ViewSort),
+}
+
+impl UpdateViewInfoPayload {
+    pub fn new() -> UpdateViewInfoPayload {
+        ::std::default::Default::default()
+    }
+
+    // string view_id = 1;
+
+
+    pub fn get_view_id(&self) -> &str {
+        &self.view_id
+    }
+    pub fn clear_view_id(&mut self) {
+        self.view_id.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_view_id(&mut self, v: ::std::string::String) {
+        self.view_id = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_view_id(&mut self) -> &mut ::std::string::String {
+        &mut self.view_id
+    }
+
+    // Take field
+    pub fn take_view_id(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.view_id, ::std::string::String::new())
+    }
+
+    // .ViewFilter filter = 2;
+
+
+    pub fn get_filter(&self) -> &ViewFilter {
+        match self.one_of_filter {
+            ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_filter::filter(ref v)) => v,
+            _ => <ViewFilter as ::protobuf::Message>::default_instance(),
+        }
+    }
+    pub fn clear_filter(&mut self) {
+        self.one_of_filter = ::std::option::Option::None;
+    }
+
+    pub fn has_filter(&self) -> bool {
+        match self.one_of_filter {
+            ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_filter::filter(..)) => true,
+            _ => false,
+        }
+    }
+
+    // Param is passed by value, moved
+    pub fn set_filter(&mut self, v: ViewFilter) {
+        self.one_of_filter = ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_filter::filter(v))
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_filter(&mut self) -> &mut ViewFilter {
+        if let ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_filter::filter(_)) = self.one_of_filter {
+        } else {
+            self.one_of_filter = ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_filter::filter(ViewFilter::new()));
+        }
+        match self.one_of_filter {
+            ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_filter::filter(ref mut v)) => v,
+            _ => panic!(),
+        }
+    }
+
+    // Take field
+    pub fn take_filter(&mut self) -> ViewFilter {
+        if self.has_filter() {
+            match self.one_of_filter.take() {
+                ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_filter::filter(v)) => v,
+                _ => panic!(),
+            }
+        } else {
+            ViewFilter::new()
+        }
+    }
+
+    // .ViewGroup group = 3;
+
+
+    pub fn get_group(&self) -> &ViewGroup {
+        match self.one_of_group {
+            ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_group::group(ref v)) => v,
+            _ => <ViewGroup as ::protobuf::Message>::default_instance(),
+        }
+    }
+    pub fn clear_group(&mut self) {
+        self.one_of_group = ::std::option::Option::None;
+    }
+
+    pub fn has_group(&self) -> bool {
+        match self.one_of_group {
+            ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_group::group(..)) => true,
+            _ => false,
+        }
+    }
+
+    // Param is passed by value, moved
+    pub fn set_group(&mut self, v: ViewGroup) {
+        self.one_of_group = ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_group::group(v))
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_group(&mut self) -> &mut ViewGroup {
+        if let ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_group::group(_)) = self.one_of_group {
+        } else {
+            self.one_of_group = ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_group::group(ViewGroup::new()));
+        }
+        match self.one_of_group {
+            ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_group::group(ref mut v)) => v,
+            _ => panic!(),
+        }
+    }
+
+    // Take field
+    pub fn take_group(&mut self) -> ViewGroup {
+        if self.has_group() {
+            match self.one_of_group.take() {
+                ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_group::group(v)) => v,
+                _ => panic!(),
+            }
+        } else {
+            ViewGroup::new()
+        }
+    }
+
+    // .ViewSort sort = 4;
+
+
+    pub fn get_sort(&self) -> &ViewSort {
+        match self.one_of_sort {
+            ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_sort::sort(ref v)) => v,
+            _ => <ViewSort as ::protobuf::Message>::default_instance(),
+        }
+    }
+    pub fn clear_sort(&mut self) {
+        self.one_of_sort = ::std::option::Option::None;
+    }
+
+    pub fn has_sort(&self) -> bool {
+        match self.one_of_sort {
+            ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_sort::sort(..)) => true,
+            _ => false,
+        }
+    }
+
+    // Param is passed by value, moved
+    pub fn set_sort(&mut self, v: ViewSort) {
+        self.one_of_sort = ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_sort::sort(v))
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_sort(&mut self) -> &mut ViewSort {
+        if let ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_sort::sort(_)) = self.one_of_sort {
+        } else {
+            self.one_of_sort = ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_sort::sort(ViewSort::new()));
+        }
+        match self.one_of_sort {
+            ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_sort::sort(ref mut v)) => v,
+            _ => panic!(),
+        }
+    }
+
+    // Take field
+    pub fn take_sort(&mut self) -> ViewSort {
+        if self.has_sort() {
+            match self.one_of_sort.take() {
+                ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_sort::sort(v)) => v,
+                _ => panic!(),
+            }
+        } else {
+            ViewSort::new()
+        }
+    }
+}
+
+impl ::protobuf::Message for UpdateViewInfoPayload {
+    fn is_initialized(&self) -> bool {
+        if let Some(UpdateViewInfoPayload_oneof_one_of_filter::filter(ref v)) = self.one_of_filter {
+            if !v.is_initialized() {
+                return false;
+            }
+        }
+        if let Some(UpdateViewInfoPayload_oneof_one_of_group::group(ref v)) = self.one_of_group {
+            if !v.is_initialized() {
+                return false;
+            }
+        }
+        if let Some(UpdateViewInfoPayload_oneof_one_of_sort::sort(ref v)) = self.one_of_sort {
+            if !v.is_initialized() {
+                return false;
+            }
+        }
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.view_id)?;
+                },
+                2 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    self.one_of_filter = ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_filter::filter(is.read_message()?));
+                },
+                3 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    self.one_of_group = ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_group::group(is.read_message()?));
+                },
+                4 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    self.one_of_sort = ::std::option::Option::Some(UpdateViewInfoPayload_oneof_one_of_sort::sort(is.read_message()?));
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if !self.view_id.is_empty() {
+            my_size += ::protobuf::rt::string_size(1, &self.view_id);
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_filter {
+            match v {
+                &UpdateViewInfoPayload_oneof_one_of_filter::filter(ref v) => {
+                    let len = v.compute_size();
+                    my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+                },
+            };
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_group {
+            match v {
+                &UpdateViewInfoPayload_oneof_one_of_group::group(ref v) => {
+                    let len = v.compute_size();
+                    my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+                },
+            };
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_sort {
+            match v {
+                &UpdateViewInfoPayload_oneof_one_of_sort::sort(ref v) => {
+                    let len = v.compute_size();
+                    my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+                },
+            };
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+        if !self.view_id.is_empty() {
+            os.write_string(1, &self.view_id)?;
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_filter {
+            match v {
+                &UpdateViewInfoPayload_oneof_one_of_filter::filter(ref v) => {
+                    os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+                    os.write_raw_varint32(v.get_cached_size())?;
+                    v.write_to_with_cached_sizes(os)?;
+                },
+            };
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_group {
+            match v {
+                &UpdateViewInfoPayload_oneof_one_of_group::group(ref v) => {
+                    os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+                    os.write_raw_varint32(v.get_cached_size())?;
+                    v.write_to_with_cached_sizes(os)?;
+                },
+            };
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_sort {
+            match v {
+                &UpdateViewInfoPayload_oneof_one_of_sort::sort(ref v) => {
+                    os.write_tag(4, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+                    os.write_raw_varint32(v.get_cached_size())?;
+                    v.write_to_with_cached_sizes(os)?;
+                },
+            };
+        }
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &dyn (::std::any::Any) {
+        self as &dyn (::std::any::Any)
+    }
+    fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
+        self as &mut dyn (::std::any::Any)
+    }
+    fn into_any(self: ::std::boxed::Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> UpdateViewInfoPayload {
+        UpdateViewInfoPayload::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT;
+        descriptor.get(|| {
+            let mut fields = ::std::vec::Vec::new();
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "view_id",
+                |m: &UpdateViewInfoPayload| { &m.view_id },
+                |m: &mut UpdateViewInfoPayload| { &mut m.view_id },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, ViewFilter>(
+                "filter",
+                UpdateViewInfoPayload::has_filter,
+                UpdateViewInfoPayload::get_filter,
+            ));
+            fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, ViewGroup>(
+                "group",
+                UpdateViewInfoPayload::has_group,
+                UpdateViewInfoPayload::get_group,
+            ));
+            fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, ViewSort>(
+                "sort",
+                UpdateViewInfoPayload::has_sort,
+                UpdateViewInfoPayload::get_sort,
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<UpdateViewInfoPayload>(
+                "UpdateViewInfoPayload",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static UpdateViewInfoPayload {
+        static instance: ::protobuf::rt::LazyV2<UpdateViewInfoPayload> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(UpdateViewInfoPayload::new)
+    }
+}
+
+impl ::protobuf::Clear for UpdateViewInfoPayload {
+    fn clear(&mut self) {
+        self.view_id.clear();
+        self.one_of_filter = ::std::option::Option::None;
+        self.one_of_group = ::std::option::Option::None;
+        self.one_of_sort = ::std::option::Option::None;
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for UpdateViewInfoPayload {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for UpdateViewInfoPayload {
+    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+        ::protobuf::reflect::ReflectValueRef::Message(self)
+    }
+}
+
 static file_descriptor_proto_data: &'static [u8] = b"\
     \n\x0fview_info.proto\x1a\nview.proto\"\xe8\x01\n\x08ViewInfo\x12\x0e\n\
     \x02id\x18\x01\x20\x01(\tR\x02id\x12\x20\n\x0cbelong_to_id\x18\x02\x20\
@@ -1310,12 +1737,17 @@ static file_descriptor_proto_data: &'static [u8] = b"\
     \x01(\x0b2\x0c.ViewExtDataR\x07extData\"s\n\x0bViewExtData\x12#\n\x06fil\
     ter\x18\x01\x20\x01(\x0b2\x0b.ViewFilterR\x06filter\x12\x20\n\x05group\
     \x18\x02\x20\x01(\x0b2\n.ViewGroupR\x05group\x12\x1d\n\x04sort\x18\x03\
-    \x20\x01(\x0b2\t.ViewSortR\x04sort\"'\n\nViewFilter\x12\x19\n\x08field_i\
-    d\x18\x01\x20\x01(\tR\x07fieldId\"}\n\tViewGroup\x12$\n\x0egroup_field_i\
-    d\x18\x01\x20\x01(\tR\x0cgroupFieldId\x12-\n\x12sub_group_field_id\x18\
-    \x02\x20\x01(\tH\0R\x0fsubGroupFieldIdB\x1b\n\x19one_of_sub_group_field_\
-    id\"%\n\x08ViewSort\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\
-    b\x06proto3\
+    \x20\x01(\x0b2\t.ViewSortR\x04sort\")\n\nViewFilter\x12\x1b\n\tobject_id\
+    \x18\x01\x20\x01(\tR\x08objectId\"\x82\x01\n\tViewGroup\x12&\n\x0fgroup_\
+    object_id\x18\x01\x20\x01(\tR\rgroupObjectId\x12/\n\x13sub_group_object_\
+    id\x18\x02\x20\x01(\tH\0R\x10subGroupObjectIdB\x1c\n\x1aone_of_sub_group\
+    _object_id\"'\n\x08ViewSort\x12\x1b\n\tobject_id\x18\x01\x20\x01(\tR\x08\
+    objectId\"\xcc\x01\n\x15UpdateViewInfoPayload\x12\x17\n\x07view_id\x18\
+    \x01\x20\x01(\tR\x06viewId\x12%\n\x06filter\x18\x02\x20\x01(\x0b2\x0b.Vi\
+    ewFilterH\0R\x06filter\x12\"\n\x05group\x18\x03\x20\x01(\x0b2\n.ViewGrou\
+    pH\x01R\x05group\x12\x1f\n\x04sort\x18\x04\x20\x01(\x0b2\t.ViewSortH\x02\
+    R\x04sortB\x0f\n\rone_of_filterB\x0e\n\x0cone_of_groupB\r\n\x0bone_of_so\
+    rtb\x06proto3\
 ";
 
 static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

+ 10 - 4
shared-lib/flowy-folder-data-model/src/protobuf/proto/view_info.proto

@@ -16,12 +16,18 @@ message ViewExtData {
     ViewSort sort = 3;
 }
 message ViewFilter {
-    string field_id = 1;
+    string object_id = 1;
 }
 message ViewGroup {
-    string group_field_id = 1;
-    oneof one_of_sub_group_field_id { string sub_group_field_id = 2; };
+    string group_object_id = 1;
+    oneof one_of_sub_group_object_id { string sub_group_object_id = 2; };
 }
 message ViewSort {
-    string field_id = 1;
+    string object_id = 1;
+}
+message UpdateViewInfoPayload {
+    string view_id = 1;
+    oneof one_of_filter { ViewFilter filter = 2; };
+    oneof one_of_group { ViewGroup group = 3; };
+    oneof one_of_sort { ViewSort sort = 4; };
 }

+ 1 - 1
shared-lib/flowy-grid-data-model/Flowy.toml

@@ -1,3 +1,3 @@
 
-proto_crates = ["src/entities/grid.rs",]
+proto_crates = ["src/entities/",]
 event_files = []

+ 525 - 0
shared-lib/flowy-grid-data-model/src/entities/field.rs

@@ -0,0 +1,525 @@
+use crate::parser::NotEmptyStr;
+use crate::revision::{CellRevision, FieldRevision, RowMetaChangeset, RowRevision};
+use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
+use flowy_error_code::ErrorCode;
+
+use serde_repr::*;
+
+use strum_macros::{Display, EnumCount as EnumCountMacro, EnumIter, EnumString};
+
+#[derive(Debug, Clone, Default, ProtoBuf)]
+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 is_primary: bool,
+}
+
+#[derive(Debug, Clone, Default, ProtoBuf)]
+pub struct FieldOrder {
+    #[pb(index = 1)]
+    pub field_id: String,
+}
+
+impl std::convert::From<&str> for FieldOrder {
+    fn from(s: &str) -> Self {
+        FieldOrder { field_id: s.to_owned() }
+    }
+}
+
+impl std::convert::From<String> for FieldOrder {
+    fn from(s: String) -> Self {
+        FieldOrder { field_id: s }
+    }
+}
+
+#[derive(Debug, Clone, Default, ProtoBuf)]
+pub struct GridFieldChangeset {
+    #[pb(index = 1)]
+    pub grid_id: String,
+
+    #[pb(index = 2)]
+    pub inserted_fields: Vec<IndexField>,
+
+    #[pb(index = 3)]
+    pub deleted_fields: Vec<FieldOrder>,
+
+    #[pb(index = 4)]
+    pub updated_fields: Vec<Field>,
+}
+
+impl GridFieldChangeset {
+    pub fn insert(grid_id: &str, inserted_fields: Vec<IndexField>) -> Self {
+        Self {
+            grid_id: grid_id.to_owned(),
+            inserted_fields,
+            deleted_fields: vec![],
+            updated_fields: vec![],
+        }
+    }
+
+    pub fn delete(grid_id: &str, deleted_fields: Vec<FieldOrder>) -> Self {
+        Self {
+            grid_id: grid_id.to_string(),
+            inserted_fields: vec![],
+            deleted_fields,
+            updated_fields: vec![],
+        }
+    }
+
+    pub fn update(grid_id: &str, updated_fields: Vec<Field>) -> Self {
+        Self {
+            grid_id: grid_id.to_string(),
+            inserted_fields: vec![],
+            deleted_fields: vec![],
+            updated_fields,
+        }
+    }
+}
+
+#[derive(Debug, Clone, Default, ProtoBuf)]
+pub struct IndexField {
+    #[pb(index = 1)]
+    pub field: Field,
+
+    #[pb(index = 2)]
+    pub index: i32,
+}
+
+impl IndexField {
+    pub fn from_field_rev(field_rev: &FieldRevision, index: usize) -> Self {
+        Self {
+            field: Field::from(field_rev.clone()),
+            index: index as i32,
+        }
+    }
+}
+
+#[derive(Debug, Default, ProtoBuf)]
+pub struct GetEditFieldContextPayload {
+    #[pb(index = 1)]
+    pub grid_id: String,
+
+    #[pb(index = 2, one_of)]
+    pub field_id: Option<String>,
+
+    #[pb(index = 3)]
+    pub field_type: FieldType,
+}
+
+#[derive(Debug, Default, ProtoBuf)]
+pub struct EditFieldPayload {
+    #[pb(index = 1)]
+    pub grid_id: String,
+
+    #[pb(index = 2)]
+    pub field_id: String,
+
+    #[pb(index = 3)]
+    pub field_type: FieldType,
+
+    #[pb(index = 4)]
+    pub create_if_not_exist: bool,
+}
+
+pub struct EditFieldParams {
+    pub grid_id: String,
+    pub field_id: String,
+    pub field_type: FieldType,
+}
+
+impl TryInto<EditFieldParams> for EditFieldPayload {
+    type Error = ErrorCode;
+
+    fn try_into(self) -> Result<EditFieldParams, Self::Error> {
+        let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
+        let field_id = NotEmptyStr::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
+        Ok(EditFieldParams {
+            grid_id: grid_id.0,
+            field_id: field_id.0,
+            field_type: self.field_type,
+        })
+    }
+}
+
+pub struct CreateFieldParams {
+    pub grid_id: String,
+    pub field_type: FieldType,
+}
+
+impl TryInto<CreateFieldParams> for EditFieldPayload {
+    type Error = ErrorCode;
+
+    fn try_into(self) -> Result<CreateFieldParams, Self::Error> {
+        let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
+
+        Ok(CreateFieldParams {
+            grid_id: grid_id.0,
+            field_type: self.field_type,
+        })
+    }
+}
+
+#[derive(Debug, Default, ProtoBuf)]
+pub struct FieldTypeOptionContext {
+    #[pb(index = 1)]
+    pub grid_id: String,
+
+    #[pb(index = 2)]
+    pub grid_field: Field,
+
+    #[pb(index = 3)]
+    pub type_option_data: Vec<u8>,
+}
+
+#[derive(Debug, Default, ProtoBuf)]
+pub struct FieldTypeOptionData {
+    #[pb(index = 1)]
+    pub grid_id: String,
+
+    #[pb(index = 2)]
+    pub field: Field,
+
+    #[pb(index = 3)]
+    pub type_option_data: Vec<u8>,
+}
+
+#[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, Default, ProtoBuf)]
+pub struct RepeatedFieldOrder {
+    #[pb(index = 1)]
+    pub items: Vec<FieldOrder>,
+}
+
+impl std::ops::Deref for RepeatedFieldOrder {
+    type Target = Vec<FieldOrder>;
+    fn deref(&self) -> &Self::Target {
+        &self.items
+    }
+}
+
+impl std::convert::From<Vec<FieldOrder>> for RepeatedFieldOrder {
+    fn from(field_orders: Vec<FieldOrder>) -> Self {
+        RepeatedFieldOrder { items: field_orders }
+    }
+}
+
+impl std::convert::From<String> for RepeatedFieldOrder {
+    fn from(s: String) -> Self {
+        RepeatedFieldOrder {
+            items: vec![FieldOrder::from(s)],
+        }
+    }
+}
+
+#[derive(ProtoBuf, Default)]
+pub struct InsertFieldPayload {
+    #[pb(index = 1)]
+    pub grid_id: String,
+
+    #[pb(index = 2)]
+    pub field: Field,
+
+    #[pb(index = 3)]
+    pub type_option_data: Vec<u8>,
+
+    #[pb(index = 4, one_of)]
+    pub start_field_id: Option<String>,
+}
+
+#[derive(Clone)]
+pub struct InsertFieldParams {
+    pub grid_id: String,
+    pub field: Field,
+    pub type_option_data: Vec<u8>,
+    pub start_field_id: Option<String>,
+}
+
+impl TryInto<InsertFieldParams> for InsertFieldPayload {
+    type Error = ErrorCode;
+
+    fn try_into(self) -> Result<InsertFieldParams, Self::Error> {
+        let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
+        let _ = NotEmptyStr::parse(self.field.id.clone()).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
+
+        let start_field_id = match self.start_field_id {
+            None => None,
+            Some(id) => Some(NotEmptyStr::parse(id).map_err(|_| ErrorCode::FieldIdIsEmpty)?.0),
+        };
+
+        Ok(InsertFieldParams {
+            grid_id: grid_id.0,
+            field: self.field,
+            type_option_data: self.type_option_data,
+            start_field_id,
+        })
+    }
+}
+
+#[derive(ProtoBuf, Default)]
+pub struct UpdateFieldTypeOptionPayload {
+    #[pb(index = 1)]
+    pub grid_id: String,
+
+    #[pb(index = 2)]
+    pub field_id: String,
+
+    #[pb(index = 3)]
+    pub type_option_data: Vec<u8>,
+}
+
+#[derive(Clone)]
+pub struct UpdateFieldTypeOptionParams {
+    pub grid_id: String,
+    pub field_id: String,
+    pub type_option_data: Vec<u8>,
+}
+
+impl TryInto<UpdateFieldTypeOptionParams> for UpdateFieldTypeOptionPayload {
+    type Error = ErrorCode;
+
+    fn try_into(self) -> Result<UpdateFieldTypeOptionParams, Self::Error> {
+        let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
+        let _ = NotEmptyStr::parse(self.field_id.clone()).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
+
+        Ok(UpdateFieldTypeOptionParams {
+            grid_id: grid_id.0,
+            field_id: self.field_id,
+            type_option_data: self.type_option_data,
+        })
+    }
+}
+
+#[derive(ProtoBuf, Default)]
+pub struct QueryFieldPayload {
+    #[pb(index = 1)]
+    pub grid_id: String,
+
+    #[pb(index = 2)]
+    pub field_orders: RepeatedFieldOrder,
+}
+
+pub struct QueryFieldParams {
+    pub grid_id: String,
+    pub field_orders: RepeatedFieldOrder,
+}
+
+impl TryInto<QueryFieldParams> for QueryFieldPayload {
+    type Error = ErrorCode;
+
+    fn try_into(self) -> Result<QueryFieldParams, Self::Error> {
+        let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
+        Ok(QueryFieldParams {
+            grid_id: grid_id.0,
+            field_orders: self.field_orders,
+        })
+    }
+}
+
+#[derive(Debug, Clone, Default, ProtoBuf)]
+pub struct FieldChangesetPayload {
+    #[pb(index = 1)]
+    pub field_id: String,
+
+    #[pb(index = 2)]
+    pub grid_id: String,
+
+    #[pb(index = 3, one_of)]
+    pub name: Option<String>,
+
+    #[pb(index = 4, one_of)]
+    pub desc: Option<String>,
+
+    #[pb(index = 5, one_of)]
+    pub field_type: Option<FieldType>,
+
+    #[pb(index = 6, one_of)]
+    pub frozen: Option<bool>,
+
+    #[pb(index = 7, one_of)]
+    pub visibility: Option<bool>,
+
+    #[pb(index = 8, one_of)]
+    pub width: Option<i32>,
+
+    #[pb(index = 9, one_of)]
+    pub type_option_data: Option<Vec<u8>>,
+}
+
+#[derive(Debug, Clone, Default)]
+pub struct FieldChangesetParams {
+    pub field_id: String,
+
+    pub grid_id: String,
+
+    pub name: Option<String>,
+
+    pub desc: Option<String>,
+
+    pub field_type: Option<FieldType>,
+
+    pub frozen: Option<bool>,
+
+    pub visibility: Option<bool>,
+
+    pub width: Option<i32>,
+
+    pub type_option_data: Option<Vec<u8>>,
+}
+
+impl TryInto<FieldChangesetParams> for FieldChangesetPayload {
+    type Error = ErrorCode;
+
+    fn try_into(self) -> Result<FieldChangesetParams, Self::Error> {
+        let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
+        let field_id = NotEmptyStr::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
+
+        if let Some(type_option_data) = self.type_option_data.as_ref() {
+            if type_option_data.is_empty() {
+                return Err(ErrorCode::TypeOptionDataIsEmpty);
+            }
+        }
+
+        Ok(FieldChangesetParams {
+            field_id: field_id.0,
+            grid_id: grid_id.0,
+            name: self.name,
+            desc: self.desc,
+            field_type: self.field_type,
+            frozen: self.frozen,
+            visibility: self.visibility,
+            width: self.width,
+            type_option_data: self.type_option_data,
+        })
+    }
+}
+
+#[derive(
+    Debug,
+    Clone,
+    PartialEq,
+    Eq,
+    ProtoBuf_Enum,
+    EnumCountMacro,
+    EnumString,
+    EnumIter,
+    Display,
+    Serialize_repr,
+    Deserialize_repr,
+)]
+#[repr(u8)]
+pub enum FieldType {
+    RichText = 0,
+    Number = 1,
+    DateTime = 2,
+    SingleSelect = 3,
+    MultiSelect = 4,
+    Checkbox = 5,
+    URL = 6,
+}
+
+impl std::default::Default for FieldType {
+    fn default() -> Self {
+        FieldType::RichText
+    }
+}
+
+impl AsRef<FieldType> for FieldType {
+    fn as_ref(&self) -> &FieldType {
+        self
+    }
+}
+
+impl From<&FieldType> for FieldType {
+    fn from(field_type: &FieldType) -> Self {
+        field_type.clone()
+    }
+}
+
+impl FieldType {
+    pub fn type_id(&self) -> String {
+        let ty = self.clone() as u8;
+        ty.to_string()
+    }
+
+    pub fn default_cell_width(&self) -> i32 {
+        match self {
+            FieldType::DateTime => 180,
+            _ => 150,
+        }
+    }
+
+    pub fn is_number(&self) -> bool {
+        self == &FieldType::Number
+    }
+
+    pub fn is_text(&self) -> bool {
+        self == &FieldType::RichText
+    }
+
+    pub fn is_checkbox(&self) -> bool {
+        self == &FieldType::Checkbox
+    }
+
+    pub fn is_date(&self) -> bool {
+        self == &FieldType::DateTime
+    }
+
+    pub fn is_single_select(&self) -> bool {
+        self == &FieldType::SingleSelect
+    }
+
+    pub fn is_multi_select(&self) -> bool {
+        self == &FieldType::MultiSelect
+    }
+
+    pub fn is_url(&self) -> bool {
+        self == &FieldType::URL
+    }
+
+    pub fn is_select_option(&self) -> bool {
+        self == &FieldType::MultiSelect || self == &FieldType::SingleSelect
+    }
+}

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

@@ -1,12 +1,10 @@
-use crate::entities::{CellMeta, FieldMeta, RowMeta, RowMetaChangeset};
+use crate::entities::FieldOrder;
 use crate::parser::NotEmptyStr;
+use crate::revision::{CellRevision, FieldRevision, RowMetaChangeset, RowRevision};
 use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
 use flowy_error_code::ErrorCode;
 
-use serde_repr::*;
 use std::collections::HashMap;
-use std::sync::Arc;
-use strum_macros::{Display, EnumCount as EnumCountMacro, EnumIter, EnumString};
 
 #[derive(Debug, Clone, Default, ProtoBuf)]
 pub struct Grid {
@@ -20,276 +18,6 @@ pub struct Grid {
     pub block_orders: Vec<GridBlockOrder>,
 }
 
-#[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 visibility: bool,
-
-    #[pb(index = 7)]
-    pub width: i32,
-
-    #[pb(index = 8)]
-    pub is_primary: bool,
-}
-
-impl std::convert::From<FieldMeta> for Field {
-    fn from(field_meta: FieldMeta) -> Self {
-        Self {
-            id: field_meta.id,
-            name: field_meta.name,
-            desc: field_meta.desc,
-            field_type: field_meta.field_type,
-            frozen: field_meta.frozen,
-            visibility: field_meta.visibility,
-            width: field_meta.width,
-            is_primary: field_meta.is_primary,
-        }
-    }
-}
-
-#[derive(Debug, Clone, Default, ProtoBuf)]
-pub struct FieldOrder {
-    #[pb(index = 1)]
-    pub field_id: String,
-}
-
-impl std::convert::From<&FieldMeta> for FieldOrder {
-    fn from(field_meta: &FieldMeta) -> Self {
-        Self {
-            field_id: field_meta.id.clone(),
-        }
-    }
-}
-
-impl std::convert::From<&str> for FieldOrder {
-    fn from(s: &str) -> Self {
-        FieldOrder { field_id: s.to_owned() }
-    }
-}
-
-impl std::convert::From<String> for FieldOrder {
-    fn from(s: String) -> Self {
-        FieldOrder { field_id: s }
-    }
-}
-
-#[derive(Debug, Clone, Default, ProtoBuf)]
-pub struct GridFieldChangeset {
-    #[pb(index = 1)]
-    pub grid_id: String,
-
-    #[pb(index = 2)]
-    pub inserted_fields: Vec<IndexField>,
-
-    #[pb(index = 3)]
-    pub deleted_fields: Vec<FieldOrder>,
-
-    #[pb(index = 4)]
-    pub updated_fields: Vec<Field>,
-}
-
-impl GridFieldChangeset {
-    pub fn insert(grid_id: &str, inserted_fields: Vec<IndexField>) -> Self {
-        Self {
-            grid_id: grid_id.to_owned(),
-            inserted_fields,
-            deleted_fields: vec![],
-            updated_fields: vec![],
-        }
-    }
-
-    pub fn delete(grid_id: &str, deleted_fields: Vec<FieldOrder>) -> Self {
-        Self {
-            grid_id: grid_id.to_string(),
-            inserted_fields: vec![],
-            deleted_fields,
-            updated_fields: vec![],
-        }
-    }
-
-    pub fn update(grid_id: &str, updated_fields: Vec<Field>) -> Self {
-        Self {
-            grid_id: grid_id.to_string(),
-            inserted_fields: vec![],
-            deleted_fields: vec![],
-            updated_fields,
-        }
-    }
-}
-
-#[derive(Debug, Clone, Default, ProtoBuf)]
-pub struct IndexField {
-    #[pb(index = 1)]
-    pub field: Field,
-
-    #[pb(index = 2)]
-    pub index: i32,
-}
-
-impl IndexField {
-    pub fn from_field_meta(field_meta: &FieldMeta, index: usize) -> Self {
-        Self {
-            field: Field::from(field_meta.clone()),
-            index: index as i32,
-        }
-    }
-}
-
-#[derive(Debug, Default, ProtoBuf)]
-pub struct GetEditFieldContextPayload {
-    #[pb(index = 1)]
-    pub grid_id: String,
-
-    #[pb(index = 2, one_of)]
-    pub field_id: Option<String>,
-
-    #[pb(index = 3)]
-    pub field_type: FieldType,
-}
-
-#[derive(Debug, Default, ProtoBuf)]
-pub struct EditFieldPayload {
-    #[pb(index = 1)]
-    pub grid_id: String,
-
-    #[pb(index = 2)]
-    pub field_id: String,
-
-    #[pb(index = 3)]
-    pub field_type: FieldType,
-
-    #[pb(index = 4)]
-    pub create_if_not_exist: bool,
-}
-
-pub struct EditFieldParams {
-    pub grid_id: String,
-    pub field_id: String,
-    pub field_type: FieldType,
-}
-
-impl TryInto<EditFieldParams> for EditFieldPayload {
-    type Error = ErrorCode;
-
-    fn try_into(self) -> Result<EditFieldParams, Self::Error> {
-        let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
-        let field_id = NotEmptyStr::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
-        Ok(EditFieldParams {
-            grid_id: grid_id.0,
-            field_id: field_id.0,
-            field_type: self.field_type,
-        })
-    }
-}
-
-pub struct CreateFieldParams {
-    pub grid_id: String,
-    pub field_type: FieldType,
-}
-
-impl TryInto<CreateFieldParams> for EditFieldPayload {
-    type Error = ErrorCode;
-
-    fn try_into(self) -> Result<CreateFieldParams, Self::Error> {
-        let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
-
-        Ok(CreateFieldParams {
-            grid_id: grid_id.0,
-            field_type: self.field_type,
-        })
-    }
-}
-
-#[derive(Debug, Default, ProtoBuf)]
-pub struct FieldTypeOptionContext {
-    #[pb(index = 1)]
-    pub grid_id: String,
-
-    #[pb(index = 2)]
-    pub grid_field: Field,
-
-    #[pb(index = 3)]
-    pub type_option_data: Vec<u8>,
-}
-
-#[derive(Debug, Default, ProtoBuf)]
-pub struct FieldTypeOptionData {
-    #[pb(index = 1)]
-    pub grid_id: String,
-
-    #[pb(index = 2)]
-    pub field: Field,
-
-    #[pb(index = 3)]
-    pub type_option_data: Vec<u8>,
-}
-
-#[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, Default, ProtoBuf)]
-pub struct RepeatedFieldOrder {
-    #[pb(index = 1)]
-    pub items: Vec<FieldOrder>,
-}
-
-impl std::ops::Deref for RepeatedFieldOrder {
-    type Target = Vec<FieldOrder>;
-    fn deref(&self) -> &Self::Target {
-        &self.items
-    }
-}
-
-impl std::convert::From<Vec<FieldOrder>> for RepeatedFieldOrder {
-    fn from(field_orders: Vec<FieldOrder>) -> Self {
-        RepeatedFieldOrder { items: field_orders }
-    }
-}
-
-impl std::convert::From<String> for RepeatedFieldOrder {
-    fn from(s: String) -> Self {
-        RepeatedFieldOrder {
-            items: vec![FieldOrder::from(s)],
-        }
-    }
-}
-
 #[derive(Debug, Default, Clone, ProtoBuf)]
 pub struct RowOrder {
     #[pb(index = 1)]
@@ -302,26 +30,6 @@ pub struct RowOrder {
     pub height: i32,
 }
 
-impl std::convert::From<&RowMeta> for RowOrder {
-    fn from(row: &RowMeta) -> Self {
-        Self {
-            row_id: row.id.clone(),
-            block_id: row.block_id.clone(),
-            height: row.height,
-        }
-    }
-}
-
-impl std::convert::From<&Arc<RowMeta>> for RowOrder {
-    fn from(row: &Arc<RowMeta>) -> Self {
-        Self {
-            row_id: row.id.clone(),
-            block_id: row.block_id.clone(),
-            height: row.height,
-        }
-    }
-}
-
 #[derive(Debug, Default, ProtoBuf)]
 pub struct Row {
     #[pb(index = 1)]
@@ -395,9 +103,9 @@ pub struct UpdatedRowOrder {
 }
 
 impl UpdatedRowOrder {
-    pub fn new(row_meta: &RowMeta, row: Row) -> Self {
+    pub fn new(row_rev: &RowRevision, row: Row) -> Self {
         Self {
-            row_order: RowOrder::from(row_meta),
+            row_order: RowOrder::from(row_rev),
             row,
         }
     }
@@ -424,8 +132,8 @@ impl std::convert::From<RowOrder> for IndexRowOrder {
     }
 }
 
-impl std::convert::From<&RowMeta> for IndexRowOrder {
-    fn from(row: &RowMeta) -> Self {
+impl std::convert::From<&RowRevision> for IndexRowOrder {
+    fn from(row: &RowRevision) -> Self {
         let row_order = RowOrder::from(row);
         Self::from(row_order)
     }
@@ -591,110 +299,6 @@ impl TryInto<CreateRowParams> for CreateRowPayload {
     }
 }
 
-#[derive(ProtoBuf, Default)]
-pub struct InsertFieldPayload {
-    #[pb(index = 1)]
-    pub grid_id: String,
-
-    #[pb(index = 2)]
-    pub field: Field,
-
-    #[pb(index = 3)]
-    pub type_option_data: Vec<u8>,
-
-    #[pb(index = 4, one_of)]
-    pub start_field_id: Option<String>,
-}
-
-#[derive(Clone)]
-pub struct InsertFieldParams {
-    pub grid_id: String,
-    pub field: Field,
-    pub type_option_data: Vec<u8>,
-    pub start_field_id: Option<String>,
-}
-
-impl TryInto<InsertFieldParams> for InsertFieldPayload {
-    type Error = ErrorCode;
-
-    fn try_into(self) -> Result<InsertFieldParams, Self::Error> {
-        let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
-        let _ = NotEmptyStr::parse(self.field.id.clone()).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
-
-        let start_field_id = match self.start_field_id {
-            None => None,
-            Some(id) => Some(NotEmptyStr::parse(id).map_err(|_| ErrorCode::FieldIdIsEmpty)?.0),
-        };
-
-        Ok(InsertFieldParams {
-            grid_id: grid_id.0,
-            field: self.field,
-            type_option_data: self.type_option_data,
-            start_field_id,
-        })
-    }
-}
-
-#[derive(ProtoBuf, Default)]
-pub struct UpdateFieldTypeOptionPayload {
-    #[pb(index = 1)]
-    pub grid_id: String,
-
-    #[pb(index = 2)]
-    pub field_id: String,
-
-    #[pb(index = 3)]
-    pub type_option_data: Vec<u8>,
-}
-
-#[derive(Clone)]
-pub struct UpdateFieldTypeOptionParams {
-    pub grid_id: String,
-    pub field_id: String,
-    pub type_option_data: Vec<u8>,
-}
-
-impl TryInto<UpdateFieldTypeOptionParams> for UpdateFieldTypeOptionPayload {
-    type Error = ErrorCode;
-
-    fn try_into(self) -> Result<UpdateFieldTypeOptionParams, Self::Error> {
-        let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
-        let _ = NotEmptyStr::parse(self.field_id.clone()).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
-
-        Ok(UpdateFieldTypeOptionParams {
-            grid_id: grid_id.0,
-            field_id: self.field_id,
-            type_option_data: self.type_option_data,
-        })
-    }
-}
-
-#[derive(ProtoBuf, Default)]
-pub struct QueryFieldPayload {
-    #[pb(index = 1)]
-    pub grid_id: String,
-
-    #[pb(index = 2)]
-    pub field_orders: RepeatedFieldOrder,
-}
-
-pub struct QueryFieldParams {
-    pub grid_id: String,
-    pub field_orders: RepeatedFieldOrder,
-}
-
-impl TryInto<QueryFieldParams> for QueryFieldPayload {
-    type Error = ErrorCode;
-
-    fn try_into(self) -> Result<QueryFieldParams, Self::Error> {
-        let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
-        Ok(QueryFieldParams {
-            grid_id: grid_id.0,
-            field_orders: self.field_orders,
-        })
-    }
-}
-
 #[derive(ProtoBuf, Default)]
 pub struct QueryGridBlocksPayload {
     #[pb(index = 1)]
@@ -721,84 +325,6 @@ impl TryInto<QueryGridBlocksParams> for QueryGridBlocksPayload {
     }
 }
 
-#[derive(Debug, Clone, Default, ProtoBuf)]
-pub struct FieldChangesetPayload {
-    #[pb(index = 1)]
-    pub field_id: String,
-
-    #[pb(index = 2)]
-    pub grid_id: String,
-
-    #[pb(index = 3, one_of)]
-    pub name: Option<String>,
-
-    #[pb(index = 4, one_of)]
-    pub desc: Option<String>,
-
-    #[pb(index = 5, one_of)]
-    pub field_type: Option<FieldType>,
-
-    #[pb(index = 6, one_of)]
-    pub frozen: Option<bool>,
-
-    #[pb(index = 7, one_of)]
-    pub visibility: Option<bool>,
-
-    #[pb(index = 8, one_of)]
-    pub width: Option<i32>,
-
-    #[pb(index = 9, one_of)]
-    pub type_option_data: Option<Vec<u8>>,
-}
-
-#[derive(Debug, Clone, Default)]
-pub struct FieldChangesetParams {
-    pub field_id: String,
-
-    pub grid_id: String,
-
-    pub name: Option<String>,
-
-    pub desc: Option<String>,
-
-    pub field_type: Option<FieldType>,
-
-    pub frozen: Option<bool>,
-
-    pub visibility: Option<bool>,
-
-    pub width: Option<i32>,
-
-    pub type_option_data: Option<Vec<u8>>,
-}
-
-impl TryInto<FieldChangesetParams> for FieldChangesetPayload {
-    type Error = ErrorCode;
-
-    fn try_into(self) -> Result<FieldChangesetParams, Self::Error> {
-        let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
-        let field_id = NotEmptyStr::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
-
-        if let Some(type_option_data) = self.type_option_data.as_ref() {
-            if type_option_data.is_empty() {
-                return Err(ErrorCode::TypeOptionDataIsEmpty);
-            }
-        }
-
-        Ok(FieldChangesetParams {
-            field_id: field_id.0,
-            grid_id: grid_id.0,
-            name: self.name,
-            desc: self.desc,
-            field_type: self.field_type,
-            frozen: self.frozen,
-            visibility: self.visibility,
-            width: self.width,
-            type_option_data: self.type_option_data,
-        })
-    }
-}
-
 #[derive(Debug, Clone, ProtoBuf_Enum)]
 pub enum MoveItemType {
     MoveField = 0,
@@ -854,94 +380,6 @@ impl TryInto<MoveItemParams> for MoveItemPayload {
     }
 }
 
-#[derive(
-    Debug,
-    Clone,
-    PartialEq,
-    Eq,
-    ProtoBuf_Enum,
-    EnumCountMacro,
-    EnumString,
-    EnumIter,
-    Display,
-    Serialize_repr,
-    Deserialize_repr,
-)]
-#[repr(u8)]
-pub enum FieldType {
-    RichText = 0,
-    Number = 1,
-    DateTime = 2,
-    SingleSelect = 3,
-    MultiSelect = 4,
-    Checkbox = 5,
-    URL = 6,
-}
-
-impl std::default::Default for FieldType {
-    fn default() -> Self {
-        FieldType::RichText
-    }
-}
-
-impl AsRef<FieldType> for FieldType {
-    fn as_ref(&self) -> &FieldType {
-        self
-    }
-}
-
-impl From<&FieldType> for FieldType {
-    fn from(field_type: &FieldType) -> Self {
-        field_type.clone()
-    }
-}
-
-impl FieldType {
-    pub fn type_id(&self) -> String {
-        let ty = self.clone();
-        format!("{}", ty as u8)
-    }
-
-    pub fn default_cell_width(&self) -> i32 {
-        match self {
-            FieldType::DateTime => 180,
-            _ => 150,
-        }
-    }
-
-    pub fn is_number(&self) -> bool {
-        self == &FieldType::Number
-    }
-
-    pub fn is_text(&self) -> bool {
-        self == &FieldType::RichText
-    }
-
-    pub fn is_checkbox(&self) -> bool {
-        self == &FieldType::Checkbox
-    }
-
-    pub fn is_date(&self) -> bool {
-        self == &FieldType::DateTime
-    }
-
-    pub fn is_single_select(&self) -> bool {
-        self == &FieldType::SingleSelect
-    }
-
-    pub fn is_multi_select(&self) -> bool {
-        self == &FieldType::MultiSelect
-    }
-
-    pub fn is_url(&self) -> bool {
-        self == &FieldType::URL
-    }
-
-    pub fn is_select_option(&self) -> bool {
-        self == &FieldType::MultiSelect || self == &FieldType::SingleSelect
-    }
-}
-
 #[derive(Debug, Clone, Default, ProtoBuf)]
 pub struct CellChangeset {
     #[pb(index = 1)]
@@ -956,21 +394,3 @@ pub struct CellChangeset {
     #[pb(index = 4, one_of)]
     pub cell_content_changeset: Option<String>,
 }
-
-impl std::convert::From<CellChangeset> for RowMetaChangeset {
-    fn from(changeset: CellChangeset) -> Self {
-        let mut cell_by_field_id = HashMap::with_capacity(1);
-        let field_id = changeset.field_id;
-        let cell_meta = CellMeta {
-            data: changeset.cell_content_changeset.unwrap_or_else(|| "".to_owned()),
-        };
-        cell_by_field_id.insert(field_id, cell_meta);
-
-        RowMetaChangeset {
-            row_id: changeset.row_id,
-            height: None,
-            visibility: None,
-            cell_by_field_id,
-        }
-    }
-}

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

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

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

@@ -1,3 +1,4 @@
 pub mod entities;
 pub mod parser;
 pub mod protobuf;
+pub mod revision;

+ 4104 - 0
shared-lib/flowy-grid-data-model/src/protobuf/model/field.rs

@@ -0,0 +1,4104 @@
+// 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 `field.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 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 is_primary: bool,
+    // 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;
+    }
+
+    // bool is_primary = 8;
+
+
+    pub fn get_is_primary(&self) -> bool {
+        self.is_primary
+    }
+    pub fn clear_is_primary(&mut self) {
+        self.is_primary = false;
+    }
+
+    // Param is passed by value, moved
+    pub fn set_is_primary(&mut self, v: bool) {
+        self.is_primary = v;
+    }
+}
+
+impl ::protobuf::Message for Field {
+    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.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 => {
+                    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.is_primary = 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.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 self.is_primary != 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.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 self.is_primary != false {
+            os.write_bool(8, self.is_primary)?;
+        }
+        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_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>(
+                "is_primary",
+                |m: &Field| { &m.is_primary },
+                |m: &mut Field| { &mut m.is_primary },
+            ));
+            ::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.is_primary = false;
+        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 FieldOrder {
+    // message fields
+    pub field_id: ::std::string::String,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a FieldOrder {
+    fn default() -> &'a FieldOrder {
+        <FieldOrder as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl FieldOrder {
+    pub fn new() -> FieldOrder {
+        ::std::default::Default::default()
+    }
+
+    // string field_id = 1;
+
+
+    pub fn get_field_id(&self) -> &str {
+        &self.field_id
+    }
+    pub fn clear_field_id(&mut self) {
+        self.field_id.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_field_id(&mut self, v: ::std::string::String) {
+        self.field_id = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_field_id(&mut self) -> &mut ::std::string::String {
+        &mut self.field_id
+    }
+
+    // Take field
+    pub fn take_field_id(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.field_id, ::std::string::String::new())
+    }
+}
+
+impl ::protobuf::Message for FieldOrder {
+    fn is_initialized(&self) -> bool {
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?;
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if !self.field_id.is_empty() {
+            my_size += ::protobuf::rt::string_size(1, &self.field_id);
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+        if !self.field_id.is_empty() {
+            os.write_string(1, &self.field_id)?;
+        }
+        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() -> FieldOrder {
+        FieldOrder::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT;
+        descriptor.get(|| {
+            let mut fields = ::std::vec::Vec::new();
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "field_id",
+                |m: &FieldOrder| { &m.field_id },
+                |m: &mut FieldOrder| { &mut m.field_id },
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<FieldOrder>(
+                "FieldOrder",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static FieldOrder {
+        static instance: ::protobuf::rt::LazyV2<FieldOrder> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(FieldOrder::new)
+    }
+}
+
+impl ::protobuf::Clear for FieldOrder {
+    fn clear(&mut self) {
+        self.field_id.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for FieldOrder {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for FieldOrder {
+    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+        ::protobuf::reflect::ReflectValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct GridFieldChangeset {
+    // message fields
+    pub grid_id: ::std::string::String,
+    pub inserted_fields: ::protobuf::RepeatedField<IndexField>,
+    pub deleted_fields: ::protobuf::RepeatedField<FieldOrder>,
+    pub updated_fields: ::protobuf::RepeatedField<Field>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a GridFieldChangeset {
+    fn default() -> &'a GridFieldChangeset {
+        <GridFieldChangeset as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl GridFieldChangeset {
+    pub fn new() -> GridFieldChangeset {
+        ::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 .IndexField inserted_fields = 2;
+
+
+    pub fn get_inserted_fields(&self) -> &[IndexField] {
+        &self.inserted_fields
+    }
+    pub fn clear_inserted_fields(&mut self) {
+        self.inserted_fields.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_inserted_fields(&mut self, v: ::protobuf::RepeatedField<IndexField>) {
+        self.inserted_fields = v;
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_inserted_fields(&mut self) -> &mut ::protobuf::RepeatedField<IndexField> {
+        &mut self.inserted_fields
+    }
+
+    // Take field
+    pub fn take_inserted_fields(&mut self) -> ::protobuf::RepeatedField<IndexField> {
+        ::std::mem::replace(&mut self.inserted_fields, ::protobuf::RepeatedField::new())
+    }
+
+    // repeated .FieldOrder deleted_fields = 3;
+
+
+    pub fn get_deleted_fields(&self) -> &[FieldOrder] {
+        &self.deleted_fields
+    }
+    pub fn clear_deleted_fields(&mut self) {
+        self.deleted_fields.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_deleted_fields(&mut self, v: ::protobuf::RepeatedField<FieldOrder>) {
+        self.deleted_fields = v;
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_deleted_fields(&mut self) -> &mut ::protobuf::RepeatedField<FieldOrder> {
+        &mut self.deleted_fields
+    }
+
+    // Take field
+    pub fn take_deleted_fields(&mut self) -> ::protobuf::RepeatedField<FieldOrder> {
+        ::std::mem::replace(&mut self.deleted_fields, ::protobuf::RepeatedField::new())
+    }
+
+    // repeated .Field updated_fields = 4;
+
+
+    pub fn get_updated_fields(&self) -> &[Field] {
+        &self.updated_fields
+    }
+    pub fn clear_updated_fields(&mut self) {
+        self.updated_fields.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_updated_fields(&mut self, v: ::protobuf::RepeatedField<Field>) {
+        self.updated_fields = v;
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_updated_fields(&mut self) -> &mut ::protobuf::RepeatedField<Field> {
+        &mut self.updated_fields
+    }
+
+    // Take field
+    pub fn take_updated_fields(&mut self) -> ::protobuf::RepeatedField<Field> {
+        ::std::mem::replace(&mut self.updated_fields, ::protobuf::RepeatedField::new())
+    }
+}
+
+impl ::protobuf::Message for GridFieldChangeset {
+    fn is_initialized(&self) -> bool {
+        for v in &self.inserted_fields {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        for v in &self.deleted_fields {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        for v in &self.updated_fields {
+            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.inserted_fields)?;
+                },
+                3 => {
+                    ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.deleted_fields)?;
+                },
+                4 => {
+                    ::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.updated_fields)?;
+                },
+                _ => {
+                    ::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.inserted_fields {
+            let len = value.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        };
+        for value in &self.deleted_fields {
+            let len = value.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        };
+        for value in &self.updated_fields {
+            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.inserted_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.deleted_fields {
+            os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        };
+        for v in &self.updated_fields {
+            os.write_tag(4, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        };
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &dyn (::std::any::Any) {
+        self as &dyn (::std::any::Any)
+    }
+    fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
+        self as &mut dyn (::std::any::Any)
+    }
+    fn into_any(self: ::std::boxed::Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> GridFieldChangeset {
+        GridFieldChangeset::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: &GridFieldChangeset| { &m.grid_id },
+                |m: &mut GridFieldChangeset| { &mut m.grid_id },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<IndexField>>(
+                "inserted_fields",
+                |m: &GridFieldChangeset| { &m.inserted_fields },
+                |m: &mut GridFieldChangeset| { &mut m.inserted_fields },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<FieldOrder>>(
+                "deleted_fields",
+                |m: &GridFieldChangeset| { &m.deleted_fields },
+                |m: &mut GridFieldChangeset| { &mut m.deleted_fields },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<Field>>(
+                "updated_fields",
+                |m: &GridFieldChangeset| { &m.updated_fields },
+                |m: &mut GridFieldChangeset| { &mut m.updated_fields },
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<GridFieldChangeset>(
+                "GridFieldChangeset",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static GridFieldChangeset {
+        static instance: ::protobuf::rt::LazyV2<GridFieldChangeset> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(GridFieldChangeset::new)
+    }
+}
+
+impl ::protobuf::Clear for GridFieldChangeset {
+    fn clear(&mut self) {
+        self.grid_id.clear();
+        self.inserted_fields.clear();
+        self.deleted_fields.clear();
+        self.updated_fields.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for GridFieldChangeset {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for GridFieldChangeset {
+    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+        ::protobuf::reflect::ReflectValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct IndexField {
+    // message fields
+    pub field: ::protobuf::SingularPtrField<Field>,
+    pub index: i32,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a IndexField {
+    fn default() -> &'a IndexField {
+        <IndexField as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl IndexField {
+    pub fn new() -> IndexField {
+        ::std::default::Default::default()
+    }
+
+    // .Field field = 1;
+
+
+    pub fn get_field(&self) -> &Field {
+        self.field.as_ref().unwrap_or_else(|| <Field as ::protobuf::Message>::default_instance())
+    }
+    pub fn clear_field(&mut self) {
+        self.field.clear();
+    }
+
+    pub fn has_field(&self) -> bool {
+        self.field.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_field(&mut self, v: Field) {
+        self.field = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_field(&mut self) -> &mut Field {
+        if self.field.is_none() {
+            self.field.set_default();
+        }
+        self.field.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_field(&mut self) -> Field {
+        self.field.take().unwrap_or_else(|| Field::new())
+    }
+
+    // int32 index = 2;
+
+
+    pub fn get_index(&self) -> i32 {
+        self.index
+    }
+    pub fn clear_index(&mut self) {
+        self.index = 0;
+    }
+
+    // Param is passed by value, moved
+    pub fn set_index(&mut self, v: i32) {
+        self.index = v;
+    }
+}
+
+impl ::protobuf::Message for IndexField {
+    fn is_initialized(&self) -> bool {
+        for v in &self.field {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.field)?;
+                },
+                2 => {
+                    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.index = 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 let Some(ref v) = self.field.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        if self.index != 0 {
+            my_size += ::protobuf::rt::value_size(2, self.index, ::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 let Some(ref v) = self.field.as_ref() {
+            os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        if self.index != 0 {
+            os.write_int32(2, self.index)?;
+        }
+        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() -> IndexField {
+        IndexField::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT;
+        descriptor.get(|| {
+            let mut fields = ::std::vec::Vec::new();
+            fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<Field>>(
+                "field",
+                |m: &IndexField| { &m.field },
+                |m: &mut IndexField| { &mut m.field },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>(
+                "index",
+                |m: &IndexField| { &m.index },
+                |m: &mut IndexField| { &mut m.index },
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<IndexField>(
+                "IndexField",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static IndexField {
+        static instance: ::protobuf::rt::LazyV2<IndexField> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(IndexField::new)
+    }
+}
+
+impl ::protobuf::Clear for IndexField {
+    fn clear(&mut self) {
+        self.field.clear();
+        self.index = 0;
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for IndexField {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for IndexField {
+    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+        ::protobuf::reflect::ReflectValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct GetEditFieldContextPayload {
+    // message fields
+    pub grid_id: ::std::string::String,
+    pub field_type: FieldType,
+    // message oneof groups
+    pub one_of_field_id: ::std::option::Option<GetEditFieldContextPayload_oneof_one_of_field_id>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a GetEditFieldContextPayload {
+    fn default() -> &'a GetEditFieldContextPayload {
+        <GetEditFieldContextPayload as ::protobuf::Message>::default_instance()
+    }
+}
+
+#[derive(Clone,PartialEq,Debug)]
+pub enum GetEditFieldContextPayload_oneof_one_of_field_id {
+    field_id(::std::string::String),
+}
+
+impl GetEditFieldContextPayload {
+    pub fn new() -> GetEditFieldContextPayload {
+        ::std::default::Default::default()
+    }
+
+    // string grid_id = 1;
+
+
+    pub fn get_grid_id(&self) -> &str {
+        &self.grid_id
+    }
+    pub fn clear_grid_id(&mut self) {
+        self.grid_id.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_grid_id(&mut self, v: ::std::string::String) {
+        self.grid_id = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_grid_id(&mut self) -> &mut ::std::string::String {
+        &mut self.grid_id
+    }
+
+    // Take field
+    pub fn take_grid_id(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.grid_id, ::std::string::String::new())
+    }
+
+    // string field_id = 2;
+
+
+    pub fn get_field_id(&self) -> &str {
+        match self.one_of_field_id {
+            ::std::option::Option::Some(GetEditFieldContextPayload_oneof_one_of_field_id::field_id(ref v)) => v,
+            _ => "",
+        }
+    }
+    pub fn clear_field_id(&mut self) {
+        self.one_of_field_id = ::std::option::Option::None;
+    }
+
+    pub fn has_field_id(&self) -> bool {
+        match self.one_of_field_id {
+            ::std::option::Option::Some(GetEditFieldContextPayload_oneof_one_of_field_id::field_id(..)) => true,
+            _ => false,
+        }
+    }
+
+    // Param is passed by value, moved
+    pub fn set_field_id(&mut self, v: ::std::string::String) {
+        self.one_of_field_id = ::std::option::Option::Some(GetEditFieldContextPayload_oneof_one_of_field_id::field_id(v))
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_field_id(&mut self) -> &mut ::std::string::String {
+        if let ::std::option::Option::Some(GetEditFieldContextPayload_oneof_one_of_field_id::field_id(_)) = self.one_of_field_id {
+        } else {
+            self.one_of_field_id = ::std::option::Option::Some(GetEditFieldContextPayload_oneof_one_of_field_id::field_id(::std::string::String::new()));
+        }
+        match self.one_of_field_id {
+            ::std::option::Option::Some(GetEditFieldContextPayload_oneof_one_of_field_id::field_id(ref mut v)) => v,
+            _ => panic!(),
+        }
+    }
+
+    // Take field
+    pub fn take_field_id(&mut self) -> ::std::string::String {
+        if self.has_field_id() {
+            match self.one_of_field_id.take() {
+                ::std::option::Option::Some(GetEditFieldContextPayload_oneof_one_of_field_id::field_id(v)) => v,
+                _ => panic!(),
+            }
+        } else {
+            ::std::string::String::new()
+        }
+    }
+
+    // .FieldType field_type = 3;
+
+
+    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;
+    }
+}
+
+impl ::protobuf::Message for GetEditFieldContextPayload {
+    fn is_initialized(&self) -> bool {
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?;
+                },
+                2 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    self.one_of_field_id = ::std::option::Option::Some(GetEditFieldContextPayload_oneof_one_of_field_id::field_id(is.read_string()?));
+                },
+                3 => {
+                    ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.field_type, 3, &mut self.unknown_fields)?
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if !self.grid_id.is_empty() {
+            my_size += ::protobuf::rt::string_size(1, &self.grid_id);
+        }
+        if self.field_type != FieldType::RichText {
+            my_size += ::protobuf::rt::enum_size(3, self.field_type);
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_field_id {
+            match v {
+                &GetEditFieldContextPayload_oneof_one_of_field_id::field_id(ref v) => {
+                    my_size += ::protobuf::rt::string_size(2, &v);
+                },
+            };
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+        if !self.grid_id.is_empty() {
+            os.write_string(1, &self.grid_id)?;
+        }
+        if self.field_type != FieldType::RichText {
+            os.write_enum(3, ::protobuf::ProtobufEnum::value(&self.field_type))?;
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_field_id {
+            match v {
+                &GetEditFieldContextPayload_oneof_one_of_field_id::field_id(ref v) => {
+                    os.write_string(2, v)?;
+                },
+            };
+        }
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &dyn (::std::any::Any) {
+        self as &dyn (::std::any::Any)
+    }
+    fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
+        self as &mut dyn (::std::any::Any)
+    }
+    fn into_any(self: ::std::boxed::Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> GetEditFieldContextPayload {
+        GetEditFieldContextPayload::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: &GetEditFieldContextPayload| { &m.grid_id },
+                |m: &mut GetEditFieldContextPayload| { &mut m.grid_id },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>(
+                "field_id",
+                GetEditFieldContextPayload::has_field_id,
+                GetEditFieldContextPayload::get_field_id,
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum<FieldType>>(
+                "field_type",
+                |m: &GetEditFieldContextPayload| { &m.field_type },
+                |m: &mut GetEditFieldContextPayload| { &mut m.field_type },
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<GetEditFieldContextPayload>(
+                "GetEditFieldContextPayload",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static GetEditFieldContextPayload {
+        static instance: ::protobuf::rt::LazyV2<GetEditFieldContextPayload> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(GetEditFieldContextPayload::new)
+    }
+}
+
+impl ::protobuf::Clear for GetEditFieldContextPayload {
+    fn clear(&mut self) {
+        self.grid_id.clear();
+        self.one_of_field_id = ::std::option::Option::None;
+        self.field_type = FieldType::RichText;
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for GetEditFieldContextPayload {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for GetEditFieldContextPayload {
+    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+        ::protobuf::reflect::ReflectValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct EditFieldPayload {
+    // message fields
+    pub grid_id: ::std::string::String,
+    pub field_id: ::std::string::String,
+    pub field_type: FieldType,
+    pub create_if_not_exist: bool,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a EditFieldPayload {
+    fn default() -> &'a EditFieldPayload {
+        <EditFieldPayload as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl EditFieldPayload {
+    pub fn new() -> EditFieldPayload {
+        ::std::default::Default::default()
+    }
+
+    // string grid_id = 1;
+
+
+    pub fn get_grid_id(&self) -> &str {
+        &self.grid_id
+    }
+    pub fn clear_grid_id(&mut self) {
+        self.grid_id.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_grid_id(&mut self, v: ::std::string::String) {
+        self.grid_id = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_grid_id(&mut self) -> &mut ::std::string::String {
+        &mut self.grid_id
+    }
+
+    // Take field
+    pub fn take_grid_id(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.grid_id, ::std::string::String::new())
+    }
+
+    // string field_id = 2;
+
+
+    pub fn get_field_id(&self) -> &str {
+        &self.field_id
+    }
+    pub fn clear_field_id(&mut self) {
+        self.field_id.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_field_id(&mut self, v: ::std::string::String) {
+        self.field_id = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_field_id(&mut self) -> &mut ::std::string::String {
+        &mut self.field_id
+    }
+
+    // Take field
+    pub fn take_field_id(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.field_id, ::std::string::String::new())
+    }
+
+    // .FieldType field_type = 3;
+
+
+    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 create_if_not_exist = 4;
+
+
+    pub fn get_create_if_not_exist(&self) -> bool {
+        self.create_if_not_exist
+    }
+    pub fn clear_create_if_not_exist(&mut self) {
+        self.create_if_not_exist = false;
+    }
+
+    // Param is passed by value, moved
+    pub fn set_create_if_not_exist(&mut self, v: bool) {
+        self.create_if_not_exist = v;
+    }
+}
+
+impl ::protobuf::Message for EditFieldPayload {
+    fn is_initialized(&self) -> bool {
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?;
+                },
+                2 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?;
+                },
+                3 => {
+                    ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.field_type, 3, &mut self.unknown_fields)?
+                },
+                4 => {
+                    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.create_if_not_exist = 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.grid_id.is_empty() {
+            my_size += ::protobuf::rt::string_size(1, &self.grid_id);
+        }
+        if !self.field_id.is_empty() {
+            my_size += ::protobuf::rt::string_size(2, &self.field_id);
+        }
+        if self.field_type != FieldType::RichText {
+            my_size += ::protobuf::rt::enum_size(3, self.field_type);
+        }
+        if self.create_if_not_exist != 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.grid_id.is_empty() {
+            os.write_string(1, &self.grid_id)?;
+        }
+        if !self.field_id.is_empty() {
+            os.write_string(2, &self.field_id)?;
+        }
+        if self.field_type != FieldType::RichText {
+            os.write_enum(3, ::protobuf::ProtobufEnum::value(&self.field_type))?;
+        }
+        if self.create_if_not_exist != false {
+            os.write_bool(4, self.create_if_not_exist)?;
+        }
+        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() -> EditFieldPayload {
+        EditFieldPayload::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: &EditFieldPayload| { &m.grid_id },
+                |m: &mut EditFieldPayload| { &mut m.grid_id },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "field_id",
+                |m: &EditFieldPayload| { &m.field_id },
+                |m: &mut EditFieldPayload| { &mut m.field_id },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum<FieldType>>(
+                "field_type",
+                |m: &EditFieldPayload| { &m.field_type },
+                |m: &mut EditFieldPayload| { &mut m.field_type },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>(
+                "create_if_not_exist",
+                |m: &EditFieldPayload| { &m.create_if_not_exist },
+                |m: &mut EditFieldPayload| { &mut m.create_if_not_exist },
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<EditFieldPayload>(
+                "EditFieldPayload",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static EditFieldPayload {
+        static instance: ::protobuf::rt::LazyV2<EditFieldPayload> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(EditFieldPayload::new)
+    }
+}
+
+impl ::protobuf::Clear for EditFieldPayload {
+    fn clear(&mut self) {
+        self.grid_id.clear();
+        self.field_id.clear();
+        self.field_type = FieldType::RichText;
+        self.create_if_not_exist = false;
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for EditFieldPayload {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for EditFieldPayload {
+    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+        ::protobuf::reflect::ReflectValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct FieldTypeOptionContext {
+    // message fields
+    pub grid_id: ::std::string::String,
+    pub grid_field: ::protobuf::SingularPtrField<Field>,
+    pub type_option_data: ::std::vec::Vec<u8>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a FieldTypeOptionContext {
+    fn default() -> &'a FieldTypeOptionContext {
+        <FieldTypeOptionContext as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl FieldTypeOptionContext {
+    pub fn new() -> FieldTypeOptionContext {
+        ::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())
+    }
+
+    // .Field grid_field = 2;
+
+
+    pub fn get_grid_field(&self) -> &Field {
+        self.grid_field.as_ref().unwrap_or_else(|| <Field as ::protobuf::Message>::default_instance())
+    }
+    pub fn clear_grid_field(&mut self) {
+        self.grid_field.clear();
+    }
+
+    pub fn has_grid_field(&self) -> bool {
+        self.grid_field.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_grid_field(&mut self, v: Field) {
+        self.grid_field = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_grid_field(&mut self) -> &mut Field {
+        if self.grid_field.is_none() {
+            self.grid_field.set_default();
+        }
+        self.grid_field.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_grid_field(&mut self) -> Field {
+        self.grid_field.take().unwrap_or_else(|| Field::new())
+    }
+
+    // bytes type_option_data = 3;
+
+
+    pub fn get_type_option_data(&self) -> &[u8] {
+        &self.type_option_data
+    }
+    pub fn clear_type_option_data(&mut self) {
+        self.type_option_data.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_type_option_data(&mut self, v: ::std::vec::Vec<u8>) {
+        self.type_option_data = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_type_option_data(&mut self) -> &mut ::std::vec::Vec<u8> {
+        &mut self.type_option_data
+    }
+
+    // Take field
+    pub fn take_type_option_data(&mut self) -> ::std::vec::Vec<u8> {
+        ::std::mem::replace(&mut self.type_option_data, ::std::vec::Vec::new())
+    }
+}
+
+impl ::protobuf::Message for FieldTypeOptionContext {
+    fn is_initialized(&self) -> bool {
+        for v in &self.grid_field {
+            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_singular_message_into(wire_type, is, &mut self.grid_field)?;
+                },
+                3 => {
+                    ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.type_option_data)?;
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if !self.grid_id.is_empty() {
+            my_size += ::protobuf::rt::string_size(1, &self.grid_id);
+        }
+        if let Some(ref v) = self.grid_field.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        if !self.type_option_data.is_empty() {
+            my_size += ::protobuf::rt::bytes_size(3, &self.type_option_data);
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+        if !self.grid_id.is_empty() {
+            os.write_string(1, &self.grid_id)?;
+        }
+        if let Some(ref v) = self.grid_field.as_ref() {
+            os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        if !self.type_option_data.is_empty() {
+            os.write_bytes(3, &self.type_option_data)?;
+        }
+        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() -> FieldTypeOptionContext {
+        FieldTypeOptionContext::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: &FieldTypeOptionContext| { &m.grid_id },
+                |m: &mut FieldTypeOptionContext| { &mut m.grid_id },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<Field>>(
+                "grid_field",
+                |m: &FieldTypeOptionContext| { &m.grid_field },
+                |m: &mut FieldTypeOptionContext| { &mut m.grid_field },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
+                "type_option_data",
+                |m: &FieldTypeOptionContext| { &m.type_option_data },
+                |m: &mut FieldTypeOptionContext| { &mut m.type_option_data },
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<FieldTypeOptionContext>(
+                "FieldTypeOptionContext",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static FieldTypeOptionContext {
+        static instance: ::protobuf::rt::LazyV2<FieldTypeOptionContext> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(FieldTypeOptionContext::new)
+    }
+}
+
+impl ::protobuf::Clear for FieldTypeOptionContext {
+    fn clear(&mut self) {
+        self.grid_id.clear();
+        self.grid_field.clear();
+        self.type_option_data.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for FieldTypeOptionContext {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for FieldTypeOptionContext {
+    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+        ::protobuf::reflect::ReflectValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct FieldTypeOptionData {
+    // message fields
+    pub grid_id: ::std::string::String,
+    pub field: ::protobuf::SingularPtrField<Field>,
+    pub type_option_data: ::std::vec::Vec<u8>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a FieldTypeOptionData {
+    fn default() -> &'a FieldTypeOptionData {
+        <FieldTypeOptionData as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl FieldTypeOptionData {
+    pub fn new() -> FieldTypeOptionData {
+        ::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())
+    }
+
+    // .Field field = 2;
+
+
+    pub fn get_field(&self) -> &Field {
+        self.field.as_ref().unwrap_or_else(|| <Field as ::protobuf::Message>::default_instance())
+    }
+    pub fn clear_field(&mut self) {
+        self.field.clear();
+    }
+
+    pub fn has_field(&self) -> bool {
+        self.field.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_field(&mut self, v: Field) {
+        self.field = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_field(&mut self) -> &mut Field {
+        if self.field.is_none() {
+            self.field.set_default();
+        }
+        self.field.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_field(&mut self) -> Field {
+        self.field.take().unwrap_or_else(|| Field::new())
+    }
+
+    // bytes type_option_data = 3;
+
+
+    pub fn get_type_option_data(&self) -> &[u8] {
+        &self.type_option_data
+    }
+    pub fn clear_type_option_data(&mut self) {
+        self.type_option_data.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_type_option_data(&mut self, v: ::std::vec::Vec<u8>) {
+        self.type_option_data = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_type_option_data(&mut self) -> &mut ::std::vec::Vec<u8> {
+        &mut self.type_option_data
+    }
+
+    // Take field
+    pub fn take_type_option_data(&mut self) -> ::std::vec::Vec<u8> {
+        ::std::mem::replace(&mut self.type_option_data, ::std::vec::Vec::new())
+    }
+}
+
+impl ::protobuf::Message for FieldTypeOptionData {
+    fn is_initialized(&self) -> bool {
+        for v in &self.field {
+            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_singular_message_into(wire_type, is, &mut self.field)?;
+                },
+                3 => {
+                    ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.type_option_data)?;
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if !self.grid_id.is_empty() {
+            my_size += ::protobuf::rt::string_size(1, &self.grid_id);
+        }
+        if let Some(ref v) = self.field.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        if !self.type_option_data.is_empty() {
+            my_size += ::protobuf::rt::bytes_size(3, &self.type_option_data);
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+        if !self.grid_id.is_empty() {
+            os.write_string(1, &self.grid_id)?;
+        }
+        if let Some(ref v) = self.field.as_ref() {
+            os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        if !self.type_option_data.is_empty() {
+            os.write_bytes(3, &self.type_option_data)?;
+        }
+        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() -> FieldTypeOptionData {
+        FieldTypeOptionData::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: &FieldTypeOptionData| { &m.grid_id },
+                |m: &mut FieldTypeOptionData| { &mut m.grid_id },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<Field>>(
+                "field",
+                |m: &FieldTypeOptionData| { &m.field },
+                |m: &mut FieldTypeOptionData| { &mut m.field },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
+                "type_option_data",
+                |m: &FieldTypeOptionData| { &m.type_option_data },
+                |m: &mut FieldTypeOptionData| { &mut m.type_option_data },
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<FieldTypeOptionData>(
+                "FieldTypeOptionData",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static FieldTypeOptionData {
+        static instance: ::protobuf::rt::LazyV2<FieldTypeOptionData> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(FieldTypeOptionData::new)
+    }
+}
+
+impl ::protobuf::Clear for FieldTypeOptionData {
+    fn clear(&mut self) {
+        self.grid_id.clear();
+        self.field.clear();
+        self.type_option_data.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for FieldTypeOptionData {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for FieldTypeOptionData {
+    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 RepeatedFieldOrder {
+    // message fields
+    pub items: ::protobuf::RepeatedField<FieldOrder>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a RepeatedFieldOrder {
+    fn default() -> &'a RepeatedFieldOrder {
+        <RepeatedFieldOrder as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl RepeatedFieldOrder {
+    pub fn new() -> RepeatedFieldOrder {
+        ::std::default::Default::default()
+    }
+
+    // repeated .FieldOrder items = 1;
+
+
+    pub fn get_items(&self) -> &[FieldOrder] {
+        &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<FieldOrder>) {
+        self.items = v;
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_items(&mut self) -> &mut ::protobuf::RepeatedField<FieldOrder> {
+        &mut self.items
+    }
+
+    // Take field
+    pub fn take_items(&mut self) -> ::protobuf::RepeatedField<FieldOrder> {
+        ::std::mem::replace(&mut self.items, ::protobuf::RepeatedField::new())
+    }
+}
+
+impl ::protobuf::Message for RepeatedFieldOrder {
+    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() -> RepeatedFieldOrder {
+        RepeatedFieldOrder::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<FieldOrder>>(
+                "items",
+                |m: &RepeatedFieldOrder| { &m.items },
+                |m: &mut RepeatedFieldOrder| { &mut m.items },
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<RepeatedFieldOrder>(
+                "RepeatedFieldOrder",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static RepeatedFieldOrder {
+        static instance: ::protobuf::rt::LazyV2<RepeatedFieldOrder> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(RepeatedFieldOrder::new)
+    }
+}
+
+impl ::protobuf::Clear for RepeatedFieldOrder {
+    fn clear(&mut self) {
+        self.items.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for RepeatedFieldOrder {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for RepeatedFieldOrder {
+    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+        ::protobuf::reflect::ReflectValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct InsertFieldPayload {
+    // message fields
+    pub grid_id: ::std::string::String,
+    pub field: ::protobuf::SingularPtrField<Field>,
+    pub type_option_data: ::std::vec::Vec<u8>,
+    // message oneof groups
+    pub one_of_start_field_id: ::std::option::Option<InsertFieldPayload_oneof_one_of_start_field_id>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a InsertFieldPayload {
+    fn default() -> &'a InsertFieldPayload {
+        <InsertFieldPayload as ::protobuf::Message>::default_instance()
+    }
+}
+
+#[derive(Clone,PartialEq,Debug)]
+pub enum InsertFieldPayload_oneof_one_of_start_field_id {
+    start_field_id(::std::string::String),
+}
+
+impl InsertFieldPayload {
+    pub fn new() -> InsertFieldPayload {
+        ::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())
+    }
+
+    // .Field field = 2;
+
+
+    pub fn get_field(&self) -> &Field {
+        self.field.as_ref().unwrap_or_else(|| <Field as ::protobuf::Message>::default_instance())
+    }
+    pub fn clear_field(&mut self) {
+        self.field.clear();
+    }
+
+    pub fn has_field(&self) -> bool {
+        self.field.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_field(&mut self, v: Field) {
+        self.field = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_field(&mut self) -> &mut Field {
+        if self.field.is_none() {
+            self.field.set_default();
+        }
+        self.field.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_field(&mut self) -> Field {
+        self.field.take().unwrap_or_else(|| Field::new())
+    }
+
+    // bytes type_option_data = 3;
+
+
+    pub fn get_type_option_data(&self) -> &[u8] {
+        &self.type_option_data
+    }
+    pub fn clear_type_option_data(&mut self) {
+        self.type_option_data.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_type_option_data(&mut self, v: ::std::vec::Vec<u8>) {
+        self.type_option_data = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_type_option_data(&mut self) -> &mut ::std::vec::Vec<u8> {
+        &mut self.type_option_data
+    }
+
+    // Take field
+    pub fn take_type_option_data(&mut self) -> ::std::vec::Vec<u8> {
+        ::std::mem::replace(&mut self.type_option_data, ::std::vec::Vec::new())
+    }
+
+    // string start_field_id = 4;
+
+
+    pub fn get_start_field_id(&self) -> &str {
+        match self.one_of_start_field_id {
+            ::std::option::Option::Some(InsertFieldPayload_oneof_one_of_start_field_id::start_field_id(ref v)) => v,
+            _ => "",
+        }
+    }
+    pub fn clear_start_field_id(&mut self) {
+        self.one_of_start_field_id = ::std::option::Option::None;
+    }
+
+    pub fn has_start_field_id(&self) -> bool {
+        match self.one_of_start_field_id {
+            ::std::option::Option::Some(InsertFieldPayload_oneof_one_of_start_field_id::start_field_id(..)) => true,
+            _ => false,
+        }
+    }
+
+    // Param is passed by value, moved
+    pub fn set_start_field_id(&mut self, v: ::std::string::String) {
+        self.one_of_start_field_id = ::std::option::Option::Some(InsertFieldPayload_oneof_one_of_start_field_id::start_field_id(v))
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_start_field_id(&mut self) -> &mut ::std::string::String {
+        if let ::std::option::Option::Some(InsertFieldPayload_oneof_one_of_start_field_id::start_field_id(_)) = self.one_of_start_field_id {
+        } else {
+            self.one_of_start_field_id = ::std::option::Option::Some(InsertFieldPayload_oneof_one_of_start_field_id::start_field_id(::std::string::String::new()));
+        }
+        match self.one_of_start_field_id {
+            ::std::option::Option::Some(InsertFieldPayload_oneof_one_of_start_field_id::start_field_id(ref mut v)) => v,
+            _ => panic!(),
+        }
+    }
+
+    // Take field
+    pub fn take_start_field_id(&mut self) -> ::std::string::String {
+        if self.has_start_field_id() {
+            match self.one_of_start_field_id.take() {
+                ::std::option::Option::Some(InsertFieldPayload_oneof_one_of_start_field_id::start_field_id(v)) => v,
+                _ => panic!(),
+            }
+        } else {
+            ::std::string::String::new()
+        }
+    }
+}
+
+impl ::protobuf::Message for InsertFieldPayload {
+    fn is_initialized(&self) -> bool {
+        for v in &self.field {
+            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_singular_message_into(wire_type, is, &mut self.field)?;
+                },
+                3 => {
+                    ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.type_option_data)?;
+                },
+                4 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    self.one_of_start_field_id = ::std::option::Option::Some(InsertFieldPayload_oneof_one_of_start_field_id::start_field_id(is.read_string()?));
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if !self.grid_id.is_empty() {
+            my_size += ::protobuf::rt::string_size(1, &self.grid_id);
+        }
+        if let Some(ref v) = self.field.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
+        }
+        if !self.type_option_data.is_empty() {
+            my_size += ::protobuf::rt::bytes_size(3, &self.type_option_data);
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_start_field_id {
+            match v {
+                &InsertFieldPayload_oneof_one_of_start_field_id::start_field_id(ref v) => {
+                    my_size += ::protobuf::rt::string_size(4, &v);
+                },
+            };
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+        if !self.grid_id.is_empty() {
+            os.write_string(1, &self.grid_id)?;
+        }
+        if let Some(ref v) = self.field.as_ref() {
+            os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        if !self.type_option_data.is_empty() {
+            os.write_bytes(3, &self.type_option_data)?;
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_start_field_id {
+            match v {
+                &InsertFieldPayload_oneof_one_of_start_field_id::start_field_id(ref v) => {
+                    os.write_string(4, v)?;
+                },
+            };
+        }
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &dyn (::std::any::Any) {
+        self as &dyn (::std::any::Any)
+    }
+    fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
+        self as &mut dyn (::std::any::Any)
+    }
+    fn into_any(self: ::std::boxed::Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> InsertFieldPayload {
+        InsertFieldPayload::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: &InsertFieldPayload| { &m.grid_id },
+                |m: &mut InsertFieldPayload| { &mut m.grid_id },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<Field>>(
+                "field",
+                |m: &InsertFieldPayload| { &m.field },
+                |m: &mut InsertFieldPayload| { &mut m.field },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
+                "type_option_data",
+                |m: &InsertFieldPayload| { &m.type_option_data },
+                |m: &mut InsertFieldPayload| { &mut m.type_option_data },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>(
+                "start_field_id",
+                InsertFieldPayload::has_start_field_id,
+                InsertFieldPayload::get_start_field_id,
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<InsertFieldPayload>(
+                "InsertFieldPayload",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static InsertFieldPayload {
+        static instance: ::protobuf::rt::LazyV2<InsertFieldPayload> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(InsertFieldPayload::new)
+    }
+}
+
+impl ::protobuf::Clear for InsertFieldPayload {
+    fn clear(&mut self) {
+        self.grid_id.clear();
+        self.field.clear();
+        self.type_option_data.clear();
+        self.one_of_start_field_id = ::std::option::Option::None;
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for InsertFieldPayload {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for InsertFieldPayload {
+    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+        ::protobuf::reflect::ReflectValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct UpdateFieldTypeOptionPayload {
+    // message fields
+    pub grid_id: ::std::string::String,
+    pub field_id: ::std::string::String,
+    pub type_option_data: ::std::vec::Vec<u8>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a UpdateFieldTypeOptionPayload {
+    fn default() -> &'a UpdateFieldTypeOptionPayload {
+        <UpdateFieldTypeOptionPayload as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl UpdateFieldTypeOptionPayload {
+    pub fn new() -> UpdateFieldTypeOptionPayload {
+        ::std::default::Default::default()
+    }
+
+    // string grid_id = 1;
+
+
+    pub fn get_grid_id(&self) -> &str {
+        &self.grid_id
+    }
+    pub fn clear_grid_id(&mut self) {
+        self.grid_id.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_grid_id(&mut self, v: ::std::string::String) {
+        self.grid_id = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_grid_id(&mut self) -> &mut ::std::string::String {
+        &mut self.grid_id
+    }
+
+    // Take field
+    pub fn take_grid_id(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.grid_id, ::std::string::String::new())
+    }
+
+    // string field_id = 2;
+
+
+    pub fn get_field_id(&self) -> &str {
+        &self.field_id
+    }
+    pub fn clear_field_id(&mut self) {
+        self.field_id.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_field_id(&mut self, v: ::std::string::String) {
+        self.field_id = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_field_id(&mut self) -> &mut ::std::string::String {
+        &mut self.field_id
+    }
+
+    // Take field
+    pub fn take_field_id(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.field_id, ::std::string::String::new())
+    }
+
+    // bytes type_option_data = 3;
+
+
+    pub fn get_type_option_data(&self) -> &[u8] {
+        &self.type_option_data
+    }
+    pub fn clear_type_option_data(&mut self) {
+        self.type_option_data.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_type_option_data(&mut self, v: ::std::vec::Vec<u8>) {
+        self.type_option_data = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_type_option_data(&mut self) -> &mut ::std::vec::Vec<u8> {
+        &mut self.type_option_data
+    }
+
+    // Take field
+    pub fn take_type_option_data(&mut self) -> ::std::vec::Vec<u8> {
+        ::std::mem::replace(&mut self.type_option_data, ::std::vec::Vec::new())
+    }
+}
+
+impl ::protobuf::Message for UpdateFieldTypeOptionPayload {
+    fn is_initialized(&self) -> bool {
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?;
+                },
+                2 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?;
+                },
+                3 => {
+                    ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.type_option_data)?;
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if !self.grid_id.is_empty() {
+            my_size += ::protobuf::rt::string_size(1, &self.grid_id);
+        }
+        if !self.field_id.is_empty() {
+            my_size += ::protobuf::rt::string_size(2, &self.field_id);
+        }
+        if !self.type_option_data.is_empty() {
+            my_size += ::protobuf::rt::bytes_size(3, &self.type_option_data);
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+        if !self.grid_id.is_empty() {
+            os.write_string(1, &self.grid_id)?;
+        }
+        if !self.field_id.is_empty() {
+            os.write_string(2, &self.field_id)?;
+        }
+        if !self.type_option_data.is_empty() {
+            os.write_bytes(3, &self.type_option_data)?;
+        }
+        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() -> UpdateFieldTypeOptionPayload {
+        UpdateFieldTypeOptionPayload::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: &UpdateFieldTypeOptionPayload| { &m.grid_id },
+                |m: &mut UpdateFieldTypeOptionPayload| { &mut m.grid_id },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "field_id",
+                |m: &UpdateFieldTypeOptionPayload| { &m.field_id },
+                |m: &mut UpdateFieldTypeOptionPayload| { &mut m.field_id },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
+                "type_option_data",
+                |m: &UpdateFieldTypeOptionPayload| { &m.type_option_data },
+                |m: &mut UpdateFieldTypeOptionPayload| { &mut m.type_option_data },
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<UpdateFieldTypeOptionPayload>(
+                "UpdateFieldTypeOptionPayload",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static UpdateFieldTypeOptionPayload {
+        static instance: ::protobuf::rt::LazyV2<UpdateFieldTypeOptionPayload> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(UpdateFieldTypeOptionPayload::new)
+    }
+}
+
+impl ::protobuf::Clear for UpdateFieldTypeOptionPayload {
+    fn clear(&mut self) {
+        self.grid_id.clear();
+        self.field_id.clear();
+        self.type_option_data.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for UpdateFieldTypeOptionPayload {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for UpdateFieldTypeOptionPayload {
+    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+        ::protobuf::reflect::ReflectValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct QueryFieldPayload {
+    // message fields
+    pub grid_id: ::std::string::String,
+    pub field_orders: ::protobuf::SingularPtrField<RepeatedFieldOrder>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a QueryFieldPayload {
+    fn default() -> &'a QueryFieldPayload {
+        <QueryFieldPayload as ::protobuf::Message>::default_instance()
+    }
+}
+
+impl QueryFieldPayload {
+    pub fn new() -> QueryFieldPayload {
+        ::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())
+    }
+
+    // .RepeatedFieldOrder field_orders = 2;
+
+
+    pub fn get_field_orders(&self) -> &RepeatedFieldOrder {
+        self.field_orders.as_ref().unwrap_or_else(|| <RepeatedFieldOrder as ::protobuf::Message>::default_instance())
+    }
+    pub fn clear_field_orders(&mut self) {
+        self.field_orders.clear();
+    }
+
+    pub fn has_field_orders(&self) -> bool {
+        self.field_orders.is_some()
+    }
+
+    // Param is passed by value, moved
+    pub fn set_field_orders(&mut self, v: RepeatedFieldOrder) {
+        self.field_orders = ::protobuf::SingularPtrField::some(v);
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_field_orders(&mut self) -> &mut RepeatedFieldOrder {
+        if self.field_orders.is_none() {
+            self.field_orders.set_default();
+        }
+        self.field_orders.as_mut().unwrap()
+    }
+
+    // Take field
+    pub fn take_field_orders(&mut self) -> RepeatedFieldOrder {
+        self.field_orders.take().unwrap_or_else(|| RepeatedFieldOrder::new())
+    }
+}
+
+impl ::protobuf::Message for QueryFieldPayload {
+    fn is_initialized(&self) -> bool {
+        for v in &self.field_orders {
+            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_singular_message_into(wire_type, is, &mut self.field_orders)?;
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if !self.grid_id.is_empty() {
+            my_size += ::protobuf::rt::string_size(1, &self.grid_id);
+        }
+        if let Some(ref v) = self.field_orders.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.grid_id.is_empty() {
+            os.write_string(1, &self.grid_id)?;
+        }
+        if let Some(ref v) = self.field_orders.as_ref() {
+            os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
+        }
+        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() -> QueryFieldPayload {
+        QueryFieldPayload::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: &QueryFieldPayload| { &m.grid_id },
+                |m: &mut QueryFieldPayload| { &mut m.grid_id },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<RepeatedFieldOrder>>(
+                "field_orders",
+                |m: &QueryFieldPayload| { &m.field_orders },
+                |m: &mut QueryFieldPayload| { &mut m.field_orders },
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<QueryFieldPayload>(
+                "QueryFieldPayload",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static QueryFieldPayload {
+        static instance: ::protobuf::rt::LazyV2<QueryFieldPayload> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(QueryFieldPayload::new)
+    }
+}
+
+impl ::protobuf::Clear for QueryFieldPayload {
+    fn clear(&mut self) {
+        self.grid_id.clear();
+        self.field_orders.clear();
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for QueryFieldPayload {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for QueryFieldPayload {
+    fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
+        ::protobuf::reflect::ReflectValueRef::Message(self)
+    }
+}
+
+#[derive(PartialEq,Clone,Default)]
+pub struct FieldChangesetPayload {
+    // message fields
+    pub field_id: ::std::string::String,
+    pub grid_id: ::std::string::String,
+    // message oneof groups
+    pub one_of_name: ::std::option::Option<FieldChangesetPayload_oneof_one_of_name>,
+    pub one_of_desc: ::std::option::Option<FieldChangesetPayload_oneof_one_of_desc>,
+    pub one_of_field_type: ::std::option::Option<FieldChangesetPayload_oneof_one_of_field_type>,
+    pub one_of_frozen: ::std::option::Option<FieldChangesetPayload_oneof_one_of_frozen>,
+    pub one_of_visibility: ::std::option::Option<FieldChangesetPayload_oneof_one_of_visibility>,
+    pub one_of_width: ::std::option::Option<FieldChangesetPayload_oneof_one_of_width>,
+    pub one_of_type_option_data: ::std::option::Option<FieldChangesetPayload_oneof_one_of_type_option_data>,
+    // special fields
+    pub unknown_fields: ::protobuf::UnknownFields,
+    pub cached_size: ::protobuf::CachedSize,
+}
+
+impl<'a> ::std::default::Default for &'a FieldChangesetPayload {
+    fn default() -> &'a FieldChangesetPayload {
+        <FieldChangesetPayload as ::protobuf::Message>::default_instance()
+    }
+}
+
+#[derive(Clone,PartialEq,Debug)]
+pub enum FieldChangesetPayload_oneof_one_of_name {
+    name(::std::string::String),
+}
+
+#[derive(Clone,PartialEq,Debug)]
+pub enum FieldChangesetPayload_oneof_one_of_desc {
+    desc(::std::string::String),
+}
+
+#[derive(Clone,PartialEq,Debug)]
+pub enum FieldChangesetPayload_oneof_one_of_field_type {
+    field_type(FieldType),
+}
+
+#[derive(Clone,PartialEq,Debug)]
+pub enum FieldChangesetPayload_oneof_one_of_frozen {
+    frozen(bool),
+}
+
+#[derive(Clone,PartialEq,Debug)]
+pub enum FieldChangesetPayload_oneof_one_of_visibility {
+    visibility(bool),
+}
+
+#[derive(Clone,PartialEq,Debug)]
+pub enum FieldChangesetPayload_oneof_one_of_width {
+    width(i32),
+}
+
+#[derive(Clone,PartialEq,Debug)]
+pub enum FieldChangesetPayload_oneof_one_of_type_option_data {
+    type_option_data(::std::vec::Vec<u8>),
+}
+
+impl FieldChangesetPayload {
+    pub fn new() -> FieldChangesetPayload {
+        ::std::default::Default::default()
+    }
+
+    // string field_id = 1;
+
+
+    pub fn get_field_id(&self) -> &str {
+        &self.field_id
+    }
+    pub fn clear_field_id(&mut self) {
+        self.field_id.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_field_id(&mut self, v: ::std::string::String) {
+        self.field_id = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_field_id(&mut self) -> &mut ::std::string::String {
+        &mut self.field_id
+    }
+
+    // Take field
+    pub fn take_field_id(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.field_id, ::std::string::String::new())
+    }
+
+    // string grid_id = 2;
+
+
+    pub fn get_grid_id(&self) -> &str {
+        &self.grid_id
+    }
+    pub fn clear_grid_id(&mut self) {
+        self.grid_id.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_grid_id(&mut self, v: ::std::string::String) {
+        self.grid_id = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_grid_id(&mut self) -> &mut ::std::string::String {
+        &mut self.grid_id
+    }
+
+    // Take field
+    pub fn take_grid_id(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.grid_id, ::std::string::String::new())
+    }
+
+    // string name = 3;
+
+
+    pub fn get_name(&self) -> &str {
+        match self.one_of_name {
+            ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_name::name(ref v)) => v,
+            _ => "",
+        }
+    }
+    pub fn clear_name(&mut self) {
+        self.one_of_name = ::std::option::Option::None;
+    }
+
+    pub fn has_name(&self) -> bool {
+        match self.one_of_name {
+            ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_name::name(..)) => true,
+            _ => false,
+        }
+    }
+
+    // Param is passed by value, moved
+    pub fn set_name(&mut self, v: ::std::string::String) {
+        self.one_of_name = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_name::name(v))
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_name(&mut self) -> &mut ::std::string::String {
+        if let ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_name::name(_)) = self.one_of_name {
+        } else {
+            self.one_of_name = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_name::name(::std::string::String::new()));
+        }
+        match self.one_of_name {
+            ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_name::name(ref mut v)) => v,
+            _ => panic!(),
+        }
+    }
+
+    // Take field
+    pub fn take_name(&mut self) -> ::std::string::String {
+        if self.has_name() {
+            match self.one_of_name.take() {
+                ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_name::name(v)) => v,
+                _ => panic!(),
+            }
+        } else {
+            ::std::string::String::new()
+        }
+    }
+
+    // string desc = 4;
+
+
+    pub fn get_desc(&self) -> &str {
+        match self.one_of_desc {
+            ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_desc::desc(ref v)) => v,
+            _ => "",
+        }
+    }
+    pub fn clear_desc(&mut self) {
+        self.one_of_desc = ::std::option::Option::None;
+    }
+
+    pub fn has_desc(&self) -> bool {
+        match self.one_of_desc {
+            ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_desc::desc(..)) => true,
+            _ => false,
+        }
+    }
+
+    // Param is passed by value, moved
+    pub fn set_desc(&mut self, v: ::std::string::String) {
+        self.one_of_desc = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_desc::desc(v))
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_desc(&mut self) -> &mut ::std::string::String {
+        if let ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_desc::desc(_)) = self.one_of_desc {
+        } else {
+            self.one_of_desc = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_desc::desc(::std::string::String::new()));
+        }
+        match self.one_of_desc {
+            ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_desc::desc(ref mut v)) => v,
+            _ => panic!(),
+        }
+    }
+
+    // Take field
+    pub fn take_desc(&mut self) -> ::std::string::String {
+        if self.has_desc() {
+            match self.one_of_desc.take() {
+                ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_desc::desc(v)) => v,
+                _ => panic!(),
+            }
+        } else {
+            ::std::string::String::new()
+        }
+    }
+
+    // .FieldType field_type = 5;
+
+
+    pub fn get_field_type(&self) -> FieldType {
+        match self.one_of_field_type {
+            ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_field_type::field_type(v)) => v,
+            _ => FieldType::RichText,
+        }
+    }
+    pub fn clear_field_type(&mut self) {
+        self.one_of_field_type = ::std::option::Option::None;
+    }
+
+    pub fn has_field_type(&self) -> bool {
+        match self.one_of_field_type {
+            ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_field_type::field_type(..)) => true,
+            _ => false,
+        }
+    }
+
+    // Param is passed by value, moved
+    pub fn set_field_type(&mut self, v: FieldType) {
+        self.one_of_field_type = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_field_type::field_type(v))
+    }
+
+    // bool frozen = 6;
+
+
+    pub fn get_frozen(&self) -> bool {
+        match self.one_of_frozen {
+            ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_frozen::frozen(v)) => v,
+            _ => false,
+        }
+    }
+    pub fn clear_frozen(&mut self) {
+        self.one_of_frozen = ::std::option::Option::None;
+    }
+
+    pub fn has_frozen(&self) -> bool {
+        match self.one_of_frozen {
+            ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_frozen::frozen(..)) => true,
+            _ => false,
+        }
+    }
+
+    // Param is passed by value, moved
+    pub fn set_frozen(&mut self, v: bool) {
+        self.one_of_frozen = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_frozen::frozen(v))
+    }
+
+    // bool visibility = 7;
+
+
+    pub fn get_visibility(&self) -> bool {
+        match self.one_of_visibility {
+            ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_visibility::visibility(v)) => v,
+            _ => false,
+        }
+    }
+    pub fn clear_visibility(&mut self) {
+        self.one_of_visibility = ::std::option::Option::None;
+    }
+
+    pub fn has_visibility(&self) -> bool {
+        match self.one_of_visibility {
+            ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_visibility::visibility(..)) => true,
+            _ => false,
+        }
+    }
+
+    // Param is passed by value, moved
+    pub fn set_visibility(&mut self, v: bool) {
+        self.one_of_visibility = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_visibility::visibility(v))
+    }
+
+    // int32 width = 8;
+
+
+    pub fn get_width(&self) -> i32 {
+        match self.one_of_width {
+            ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_width::width(v)) => v,
+            _ => 0,
+        }
+    }
+    pub fn clear_width(&mut self) {
+        self.one_of_width = ::std::option::Option::None;
+    }
+
+    pub fn has_width(&self) -> bool {
+        match self.one_of_width {
+            ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_width::width(..)) => true,
+            _ => false,
+        }
+    }
+
+    // Param is passed by value, moved
+    pub fn set_width(&mut self, v: i32) {
+        self.one_of_width = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_width::width(v))
+    }
+
+    // bytes type_option_data = 9;
+
+
+    pub fn get_type_option_data(&self) -> &[u8] {
+        match self.one_of_type_option_data {
+            ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(ref v)) => v,
+            _ => &[],
+        }
+    }
+    pub fn clear_type_option_data(&mut self) {
+        self.one_of_type_option_data = ::std::option::Option::None;
+    }
+
+    pub fn has_type_option_data(&self) -> bool {
+        match self.one_of_type_option_data {
+            ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(..)) => true,
+            _ => false,
+        }
+    }
+
+    // Param is passed by value, moved
+    pub fn set_type_option_data(&mut self, v: ::std::vec::Vec<u8>) {
+        self.one_of_type_option_data = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(v))
+    }
+
+    // Mutable pointer to the field.
+    pub fn mut_type_option_data(&mut self) -> &mut ::std::vec::Vec<u8> {
+        if let ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(_)) = self.one_of_type_option_data {
+        } else {
+            self.one_of_type_option_data = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(::std::vec::Vec::new()));
+        }
+        match self.one_of_type_option_data {
+            ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(ref mut v)) => v,
+            _ => panic!(),
+        }
+    }
+
+    // Take field
+    pub fn take_type_option_data(&mut self) -> ::std::vec::Vec<u8> {
+        if self.has_type_option_data() {
+            match self.one_of_type_option_data.take() {
+                ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(v)) => v,
+                _ => panic!(),
+            }
+        } else {
+            ::std::vec::Vec::new()
+        }
+    }
+}
+
+impl ::protobuf::Message for FieldChangesetPayload {
+    fn is_initialized(&self) -> bool {
+        true
+    }
+
+    fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+        while !is.eof()? {
+            let (field_number, wire_type) = is.read_tag_unpack()?;
+            match field_number {
+                1 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.field_id)?;
+                },
+                2 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.grid_id)?;
+                },
+                3 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    self.one_of_name = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_name::name(is.read_string()?));
+                },
+                4 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    self.one_of_desc = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_desc::desc(is.read_string()?));
+                },
+                5 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    self.one_of_field_type = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_field_type::field_type(is.read_enum()?));
+                },
+                6 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    self.one_of_frozen = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_frozen::frozen(is.read_bool()?));
+                },
+                7 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    self.one_of_visibility = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_visibility::visibility(is.read_bool()?));
+                },
+                8 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeVarint {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    self.one_of_width = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_width::width(is.read_int32()?));
+                },
+                9 => {
+                    if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
+                        return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
+                    }
+                    self.one_of_type_option_data = ::std::option::Option::Some(FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(is.read_bytes()?));
+                },
+                _ => {
+                    ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
+                },
+            };
+        }
+        ::std::result::Result::Ok(())
+    }
+
+    // Compute sizes of nested messages
+    #[allow(unused_variables)]
+    fn compute_size(&self) -> u32 {
+        let mut my_size = 0;
+        if !self.field_id.is_empty() {
+            my_size += ::protobuf::rt::string_size(1, &self.field_id);
+        }
+        if !self.grid_id.is_empty() {
+            my_size += ::protobuf::rt::string_size(2, &self.grid_id);
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_name {
+            match v {
+                &FieldChangesetPayload_oneof_one_of_name::name(ref v) => {
+                    my_size += ::protobuf::rt::string_size(3, &v);
+                },
+            };
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_desc {
+            match v {
+                &FieldChangesetPayload_oneof_one_of_desc::desc(ref v) => {
+                    my_size += ::protobuf::rt::string_size(4, &v);
+                },
+            };
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_field_type {
+            match v {
+                &FieldChangesetPayload_oneof_one_of_field_type::field_type(v) => {
+                    my_size += ::protobuf::rt::enum_size(5, v);
+                },
+            };
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_frozen {
+            match v {
+                &FieldChangesetPayload_oneof_one_of_frozen::frozen(v) => {
+                    my_size += 2;
+                },
+            };
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_visibility {
+            match v {
+                &FieldChangesetPayload_oneof_one_of_visibility::visibility(v) => {
+                    my_size += 2;
+                },
+            };
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_width {
+            match v {
+                &FieldChangesetPayload_oneof_one_of_width::width(v) => {
+                    my_size += ::protobuf::rt::value_size(8, v, ::protobuf::wire_format::WireTypeVarint);
+                },
+            };
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_type_option_data {
+            match v {
+                &FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(ref v) => {
+                    my_size += ::protobuf::rt::bytes_size(9, &v);
+                },
+            };
+        }
+        my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
+        self.cached_size.set(my_size);
+        my_size
+    }
+
+    fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
+        if !self.field_id.is_empty() {
+            os.write_string(1, &self.field_id)?;
+        }
+        if !self.grid_id.is_empty() {
+            os.write_string(2, &self.grid_id)?;
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_name {
+            match v {
+                &FieldChangesetPayload_oneof_one_of_name::name(ref v) => {
+                    os.write_string(3, v)?;
+                },
+            };
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_desc {
+            match v {
+                &FieldChangesetPayload_oneof_one_of_desc::desc(ref v) => {
+                    os.write_string(4, v)?;
+                },
+            };
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_field_type {
+            match v {
+                &FieldChangesetPayload_oneof_one_of_field_type::field_type(v) => {
+                    os.write_enum(5, ::protobuf::ProtobufEnum::value(&v))?;
+                },
+            };
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_frozen {
+            match v {
+                &FieldChangesetPayload_oneof_one_of_frozen::frozen(v) => {
+                    os.write_bool(6, v)?;
+                },
+            };
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_visibility {
+            match v {
+                &FieldChangesetPayload_oneof_one_of_visibility::visibility(v) => {
+                    os.write_bool(7, v)?;
+                },
+            };
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_width {
+            match v {
+                &FieldChangesetPayload_oneof_one_of_width::width(v) => {
+                    os.write_int32(8, v)?;
+                },
+            };
+        }
+        if let ::std::option::Option::Some(ref v) = self.one_of_type_option_data {
+            match v {
+                &FieldChangesetPayload_oneof_one_of_type_option_data::type_option_data(ref v) => {
+                    os.write_bytes(9, v)?;
+                },
+            };
+        }
+        os.write_unknown_fields(self.get_unknown_fields())?;
+        ::std::result::Result::Ok(())
+    }
+
+    fn get_cached_size(&self) -> u32 {
+        self.cached_size.get()
+    }
+
+    fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
+        &self.unknown_fields
+    }
+
+    fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
+        &mut self.unknown_fields
+    }
+
+    fn as_any(&self) -> &dyn (::std::any::Any) {
+        self as &dyn (::std::any::Any)
+    }
+    fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
+        self as &mut dyn (::std::any::Any)
+    }
+    fn into_any(self: ::std::boxed::Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
+        self
+    }
+
+    fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
+        Self::descriptor_static()
+    }
+
+    fn new() -> FieldChangesetPayload {
+        FieldChangesetPayload::new()
+    }
+
+    fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
+        static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT;
+        descriptor.get(|| {
+            let mut fields = ::std::vec::Vec::new();
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "field_id",
+                |m: &FieldChangesetPayload| { &m.field_id },
+                |m: &mut FieldChangesetPayload| { &mut m.field_id },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "grid_id",
+                |m: &FieldChangesetPayload| { &m.grid_id },
+                |m: &mut FieldChangesetPayload| { &mut m.grid_id },
+            ));
+            fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>(
+                "name",
+                FieldChangesetPayload::has_name,
+                FieldChangesetPayload::get_name,
+            ));
+            fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>(
+                "desc",
+                FieldChangesetPayload::has_desc,
+                FieldChangesetPayload::get_desc,
+            ));
+            fields.push(::protobuf::reflect::accessor::make_singular_enum_accessor::<_, FieldType>(
+                "field_type",
+                FieldChangesetPayload::has_field_type,
+                FieldChangesetPayload::get_field_type,
+            ));
+            fields.push(::protobuf::reflect::accessor::make_singular_bool_accessor::<_>(
+                "frozen",
+                FieldChangesetPayload::has_frozen,
+                FieldChangesetPayload::get_frozen,
+            ));
+            fields.push(::protobuf::reflect::accessor::make_singular_bool_accessor::<_>(
+                "visibility",
+                FieldChangesetPayload::has_visibility,
+                FieldChangesetPayload::get_visibility,
+            ));
+            fields.push(::protobuf::reflect::accessor::make_singular_i32_accessor::<_>(
+                "width",
+                FieldChangesetPayload::has_width,
+                FieldChangesetPayload::get_width,
+            ));
+            fields.push(::protobuf::reflect::accessor::make_singular_bytes_accessor::<_>(
+                "type_option_data",
+                FieldChangesetPayload::has_type_option_data,
+                FieldChangesetPayload::get_type_option_data,
+            ));
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<FieldChangesetPayload>(
+                "FieldChangesetPayload",
+                fields,
+                file_descriptor_proto()
+            )
+        })
+    }
+
+    fn default_instance() -> &'static FieldChangesetPayload {
+        static instance: ::protobuf::rt::LazyV2<FieldChangesetPayload> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(FieldChangesetPayload::new)
+    }
+}
+
+impl ::protobuf::Clear for FieldChangesetPayload {
+    fn clear(&mut self) {
+        self.field_id.clear();
+        self.grid_id.clear();
+        self.one_of_name = ::std::option::Option::None;
+        self.one_of_desc = ::std::option::Option::None;
+        self.one_of_field_type = ::std::option::Option::None;
+        self.one_of_frozen = ::std::option::Option::None;
+        self.one_of_visibility = ::std::option::Option::None;
+        self.one_of_width = ::std::option::Option::None;
+        self.one_of_type_option_data = ::std::option::Option::None;
+        self.unknown_fields.clear();
+    }
+}
+
+impl ::std::fmt::Debug for FieldChangesetPayload {
+    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        ::protobuf::text_format::fmt(self, f)
+    }
+}
+
+impl ::protobuf::reflect::ProtobufValue for FieldChangesetPayload {
+    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,
+    URL = 6,
+}
+
+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),
+            6 => ::std::option::Option::Some(FieldType::URL),
+            _ => ::std::option::Option::None
+        }
+    }
+
+    fn values() -> &'static [Self] {
+        static values: &'static [FieldType] = &[
+            FieldType::RichText,
+            FieldType::Number,
+            FieldType::DateTime,
+            FieldType::SingleSelect,
+            FieldType::MultiSelect,
+            FieldType::Checkbox,
+            FieldType::URL,
+        ];
+        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\x0bfield.proto\"\xd7\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\x04des\
+    c\x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_type\x18\x04\x20\x01(\x0e2\n\
+    .FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\x08R\x06froz\
+    en\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\x12\x14\n\x05\
+    width\x18\x07\x20\x01(\x05R\x05width\x12\x1d\n\nis_primary\x18\x08\x20\
+    \x01(\x08R\tisPrimary\"'\n\nFieldOrder\x12\x19\n\x08field_id\x18\x01\x20\
+    \x01(\tR\x07fieldId\"\xc6\x01\n\x12GridFieldChangeset\x12\x17\n\x07grid_\
+    id\x18\x01\x20\x01(\tR\x06gridId\x124\n\x0finserted_fields\x18\x02\x20\
+    \x03(\x0b2\x0b.IndexFieldR\x0einsertedFields\x122\n\x0edeleted_fields\
+    \x18\x03\x20\x03(\x0b2\x0b.FieldOrderR\rdeletedFields\x12-\n\x0eupdated_\
+    fields\x18\x04\x20\x03(\x0b2\x06.FieldR\rupdatedFields\"@\n\nIndexField\
+    \x12\x1c\n\x05field\x18\x01\x20\x01(\x0b2\x06.FieldR\x05field\x12\x14\n\
+    \x05index\x18\x02\x20\x01(\x05R\x05index\"\x90\x01\n\x1aGetEditFieldCont\
+    extPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x1b\n\
+    \x08field_id\x18\x02\x20\x01(\tH\0R\x07fieldId\x12)\n\nfield_type\x18\
+    \x03\x20\x01(\x0e2\n.FieldTypeR\tfieldTypeB\x11\n\x0fone_of_field_id\"\
+    \xa0\x01\n\x10EditFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\
+    \x06gridId\x12\x19\n\x08field_id\x18\x02\x20\x01(\tR\x07fieldId\x12)\n\n\
+    field_type\x18\x03\x20\x01(\x0e2\n.FieldTypeR\tfieldType\x12-\n\x13creat\
+    e_if_not_exist\x18\x04\x20\x01(\x08R\x10createIfNotExist\"\x82\x01\n\x16\
+    FieldTypeOptionContext\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridI\
+    d\x12%\n\ngrid_field\x18\x02\x20\x01(\x0b2\x06.FieldR\tgridField\x12(\n\
+    \x10type_option_data\x18\x03\x20\x01(\x0cR\x0etypeOptionData\"v\n\x13Fie\
+    ldTypeOptionData\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\
+    \x1c\n\x05field\x18\x02\x20\x01(\x0b2\x06.FieldR\x05field\x12(\n\x10type\
+    _option_data\x18\x03\x20\x01(\x0cR\x0etypeOptionData\"-\n\rRepeatedField\
+    \x12\x1c\n\x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"7\n\x12Re\
+    peatedFieldOrder\x12!\n\x05items\x18\x01\x20\x03(\x0b2\x0b.FieldOrderR\
+    \x05items\"\xb6\x01\n\x12InsertFieldPayload\x12\x17\n\x07grid_id\x18\x01\
+    \x20\x01(\tR\x06gridId\x12\x1c\n\x05field\x18\x02\x20\x01(\x0b2\x06.Fiel\
+    dR\x05field\x12(\n\x10type_option_data\x18\x03\x20\x01(\x0cR\x0etypeOpti\
+    onData\x12&\n\x0estart_field_id\x18\x04\x20\x01(\tH\0R\x0cstartFieldIdB\
+    \x17\n\x15one_of_start_field_id\"|\n\x1cUpdateFieldTypeOptionPayload\x12\
+    \x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x19\n\x08field_id\
+    \x18\x02\x20\x01(\tR\x07fieldId\x12(\n\x10type_option_data\x18\x03\x20\
+    \x01(\x0cR\x0etypeOptionData\"d\n\x11QueryFieldPayload\x12\x17\n\x07grid\
+    _id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_orders\x18\x02\x20\x01\
+    (\x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"\xa8\x03\n\x15FieldChange\
+    setPayload\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x17\
+    \n\x07grid_id\x18\x02\x20\x01(\tR\x06gridId\x12\x14\n\x04name\x18\x03\
+    \x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x04\x20\x01(\tH\x01R\x04de\
+    sc\x12+\n\nfield_type\x18\x05\x20\x01(\x0e2\n.FieldTypeH\x02R\tfieldType\
+    \x12\x18\n\x06frozen\x18\x06\x20\x01(\x08H\x03R\x06frozen\x12\x20\n\nvis\
+    ibility\x18\x07\x20\x01(\x08H\x04R\nvisibility\x12\x16\n\x05width\x18\
+    \x08\x20\x01(\x05H\x05R\x05width\x12*\n\x10type_option_data\x18\t\x20\
+    \x01(\x0cH\x06R\x0etypeOptionDataB\r\n\x0bone_of_nameB\r\n\x0bone_of_des\
+    cB\x13\n\x11one_of_field_typeB\x0f\n\rone_of_frozenB\x13\n\x11one_of_vis\
+    ibilityB\x0e\n\x0cone_of_widthB\x19\n\x17one_of_type_option_data*m\n\tFi\
+    eldType\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\x0bMult\
+    iSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\x05\x12\x07\n\x03URL\x10\x06b\
+    \x06proto3\
+";
+
+static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
+
+fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto {
+    ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap()
+}
+
+pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto {
+    file_descriptor_proto_lazy.get(|| {
+        parse_descriptor_proto()
+    })
+}

File diff suppressed because it is too large
+ 241 - 469
shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs


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

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

+ 87 - 0
shared-lib/flowy-grid-data-model/src/protobuf/proto/field.proto

@@ -0,0 +1,87 @@
+syntax = "proto3";
+
+message Field {
+    string id = 1;
+    string name = 2;
+    string desc = 3;
+    FieldType field_type = 4;
+    bool frozen = 5;
+    bool visibility = 6;
+    int32 width = 7;
+    bool is_primary = 8;
+}
+message FieldOrder {
+    string field_id = 1;
+}
+message GridFieldChangeset {
+    string grid_id = 1;
+    repeated IndexField inserted_fields = 2;
+    repeated FieldOrder deleted_fields = 3;
+    repeated Field updated_fields = 4;
+}
+message IndexField {
+    Field field = 1;
+    int32 index = 2;
+}
+message GetEditFieldContextPayload {
+    string grid_id = 1;
+    oneof one_of_field_id { string field_id = 2; };
+    FieldType field_type = 3;
+}
+message EditFieldPayload {
+    string grid_id = 1;
+    string field_id = 2;
+    FieldType field_type = 3;
+    bool create_if_not_exist = 4;
+}
+message FieldTypeOptionContext {
+    string grid_id = 1;
+    Field grid_field = 2;
+    bytes type_option_data = 3;
+}
+message FieldTypeOptionData {
+    string grid_id = 1;
+    Field field = 2;
+    bytes type_option_data = 3;
+}
+message RepeatedField {
+    repeated Field items = 1;
+}
+message RepeatedFieldOrder {
+    repeated FieldOrder items = 1;
+}
+message InsertFieldPayload {
+    string grid_id = 1;
+    Field field = 2;
+    bytes type_option_data = 3;
+    oneof one_of_start_field_id { string start_field_id = 4; };
+}
+message UpdateFieldTypeOptionPayload {
+    string grid_id = 1;
+    string field_id = 2;
+    bytes type_option_data = 3;
+}
+message QueryFieldPayload {
+    string grid_id = 1;
+    RepeatedFieldOrder field_orders = 2;
+}
+message FieldChangesetPayload {
+    string field_id = 1;
+    string grid_id = 2;
+    oneof one_of_name { string name = 3; };
+    oneof one_of_desc { string desc = 4; };
+    oneof one_of_field_type { FieldType field_type = 5; };
+    oneof one_of_frozen { bool frozen = 6; };
+    oneof one_of_visibility { bool visibility = 7; };
+    oneof one_of_width { int32 width = 8; };
+    oneof one_of_type_option_data { bytes type_option_data = 9; };
+}
+enum FieldType {
+    RichText = 0;
+    Number = 1;
+    DateTime = 2;
+    SingleSelect = 3;
+    MultiSelect = 4;
+    Checkbox = 5;
+    URL = 6;
+}

+ 1 - 85
shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto

@@ -1,60 +1,11 @@
 syntax = "proto3";
+import "field.proto";
 
 message Grid {
     string id = 1;
     repeated FieldOrder field_orders = 2;
     repeated GridBlockOrder block_orders = 3;
 }
-message Field {
-    string id = 1;
-    string name = 2;
-    string desc = 3;
-    FieldType field_type = 4;
-    bool frozen = 5;
-    bool visibility = 6;
-    int32 width = 7;
-    bool is_primary = 8;
-}
-message FieldOrder {
-    string field_id = 1;
-}
-message GridFieldChangeset {
-    string grid_id = 1;
-    repeated IndexField inserted_fields = 2;
-    repeated FieldOrder deleted_fields = 3;
-    repeated Field updated_fields = 4;
-}
-message IndexField {
-    Field field = 1;
-    int32 index = 2;
-}
-message GetEditFieldContextPayload {
-    string grid_id = 1;
-    oneof one_of_field_id { string field_id = 2; };
-    FieldType field_type = 3;
-}
-message EditFieldPayload {
-    string grid_id = 1;
-    string field_id = 2;
-    FieldType field_type = 3;
-    bool create_if_not_exist = 4;
-}
-message FieldTypeOptionContext {
-    string grid_id = 1;
-    Field grid_field = 2;
-    bytes type_option_data = 3;
-}
-message FieldTypeOptionData {
-    string grid_id = 1;
-    Field field = 2;
-    bytes type_option_data = 3;
-}
-message RepeatedField {
-    repeated Field items = 1;
-}
-message RepeatedFieldOrder {
-    repeated FieldOrder items = 1;
-}
 message RowOrder {
     string row_id = 1;
     string block_id = 2;
@@ -113,36 +64,10 @@ message CreateRowPayload {
     string grid_id = 1;
     oneof one_of_start_row_id { string start_row_id = 2; };
 }
-message InsertFieldPayload {
-    string grid_id = 1;
-    Field field = 2;
-    bytes type_option_data = 3;
-    oneof one_of_start_field_id { string start_field_id = 4; };
-}
-message UpdateFieldTypeOptionPayload {
-    string grid_id = 1;
-    string field_id = 2;
-    bytes type_option_data = 3;
-}
-message QueryFieldPayload {
-    string grid_id = 1;
-    RepeatedFieldOrder field_orders = 2;
-}
 message QueryGridBlocksPayload {
     string grid_id = 1;
     repeated GridBlockOrder block_orders = 2;
 }
-message FieldChangesetPayload {
-    string field_id = 1;
-    string grid_id = 2;
-    oneof one_of_name { string name = 3; };
-    oneof one_of_desc { string desc = 4; };
-    oneof one_of_field_type { FieldType field_type = 5; };
-    oneof one_of_frozen { bool frozen = 6; };
-    oneof one_of_visibility { bool visibility = 7; };
-    oneof one_of_width { int32 width = 8; };
-    oneof one_of_type_option_data { bytes type_option_data = 9; };
-}
 message MoveItemPayload {
     string grid_id = 1;
     string item_id = 2;
@@ -160,12 +85,3 @@ enum MoveItemType {
     MoveField = 0;
     MoveRow = 1;
 }
-enum FieldType {
-    RichText = 0;
-    Number = 1;
-    DateTime = 2;
-    SingleSelect = 3;
-    MultiSelect = 4;
-    Checkbox = 5;
-    URL = 6;
-}

+ 86 - 23
shared-lib/flowy-grid-data-model/src/entities/meta.rs → shared-lib/flowy-grid-data-model/src/revision/mod.rs

@@ -1,9 +1,11 @@
-use crate::entities::FieldType;
+use crate::entities::{CellChangeset, Field, FieldOrder, FieldType, RowOrder};
 use bytes::Bytes;
 use indexmap::IndexMap;
 use nanoid::nanoid;
 use serde::{Deserialize, Serialize};
+use std::any::Any;
 use std::collections::HashMap;
+use std::sync::Arc;
 
 pub const DEFAULT_ROW_HEIGHT: i32 = 42;
 
@@ -25,20 +27,20 @@ pub fn gen_field_id() -> String {
 }
 
 #[derive(Debug, Clone, Default, Serialize, Deserialize)]
-pub struct GridMeta {
+pub struct GridRevision {
     pub grid_id: String,
-    pub fields: Vec<FieldMeta>,
-    pub blocks: Vec<GridBlockMeta>,
+    pub fields: Vec<FieldRevision>,
+    pub blocks: Vec<GridBlockRevision>,
 }
 
 #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
-pub struct GridBlockMeta {
+pub struct GridBlockRevision {
     pub block_id: String,
     pub start_row_index: i32,
     pub row_count: i32,
 }
 
-impl GridBlockMeta {
+impl GridBlockRevision {
     pub fn len(&self) -> i32 {
         self.row_count
     }
@@ -48,22 +50,22 @@ impl GridBlockMeta {
     }
 }
 
-impl GridBlockMeta {
+impl GridBlockRevision {
     pub fn new() -> Self {
-        GridBlockMeta {
+        GridBlockRevision {
             block_id: gen_block_id(),
             ..Default::default()
         }
     }
 }
 
-pub struct GridBlockMetaChangeset {
+pub struct GridBlockRevisionChangeset {
     pub block_id: String,
     pub start_row_index: Option<i32>,
     pub row_count: Option<i32>,
 }
 
-impl GridBlockMetaChangeset {
+impl GridBlockRevisionChangeset {
     pub fn from_row_count(block_id: &str, row_count: i32) -> Self {
         Self {
             block_id: block_id.to_string(),
@@ -74,13 +76,13 @@ impl GridBlockMetaChangeset {
 }
 
 #[derive(Debug, Clone, Default, Serialize, Deserialize)]
-pub struct GridBlockMetaData {
+pub struct GridBlockRevisionData {
     pub block_id: String,
-    pub rows: Vec<RowMeta>,
+    pub rows: Vec<RowRevision>,
 }
 
 #[derive(Debug, Clone, Default, Serialize, Deserialize, Eq, PartialEq)]
-pub struct FieldMeta {
+pub struct FieldRevision {
     pub id: String,
 
     pub name: String,
@@ -110,7 +112,7 @@ fn default_is_primary() -> bool {
     false
 }
 
-impl FieldMeta {
+impl FieldRevision {
     pub fn new(name: &str, desc: &str, field_type: FieldType, is_primary: bool) -> Self {
         let width = field_type.default_cell_width();
         Self {
@@ -148,6 +150,29 @@ impl FieldMeta {
     }
 }
 
+impl std::convert::From<FieldRevision> for Field {
+    fn from(field_rev: FieldRevision) -> Self {
+        Self {
+            id: field_rev.id,
+            name: field_rev.name,
+            desc: field_rev.desc,
+            field_type: field_rev.field_type,
+            frozen: field_rev.frozen,
+            visibility: field_rev.visibility,
+            width: field_rev.width,
+            is_primary: field_rev.is_primary,
+        }
+    }
+}
+
+impl std::convert::From<&FieldRevision> for FieldOrder {
+    fn from(field_rev: &FieldRevision) -> Self {
+        Self {
+            field_id: field_rev.id.clone(),
+        }
+    }
+}
+
 pub trait TypeOptionDataEntry {
     fn field_type(&self) -> FieldType;
     fn json_str(&self) -> String;
@@ -160,19 +185,19 @@ pub trait TypeOptionDataDeserializer {
 }
 
 #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
-pub struct RowMeta {
+pub struct RowRevision {
     pub id: String,
     pub block_id: String,
     /// cells contains key/value pairs.
     /// key: field id,
     /// value: CellMeta
     #[serde(with = "indexmap::serde_seq")]
-    pub cells: IndexMap<String, CellMeta>,
+    pub cells: IndexMap<String, CellRevision>,
     pub height: i32,
     pub visibility: bool,
 }
 
-impl RowMeta {
+impl RowRevision {
     pub fn new(block_id: &str) -> Self {
         Self {
             id: gen_row_id(),
@@ -184,20 +209,58 @@ impl RowMeta {
     }
 }
 
+impl std::convert::From<&RowRevision> for RowOrder {
+    fn from(row: &RowRevision) -> Self {
+        Self {
+            row_id: row.id.clone(),
+            block_id: row.block_id.clone(),
+            height: row.height,
+        }
+    }
+}
+
+impl std::convert::From<&Arc<RowRevision>> for RowOrder {
+    fn from(row: &Arc<RowRevision>) -> Self {
+        Self {
+            row_id: row.id.clone(),
+            block_id: row.block_id.clone(),
+            height: row.height,
+        }
+    }
+}
+
 #[derive(Debug, Clone, Default)]
 pub struct RowMetaChangeset {
     pub row_id: String,
     pub height: Option<i32>,
     pub visibility: Option<bool>,
-    pub cell_by_field_id: HashMap<String, CellMeta>,
+    pub cell_by_field_id: HashMap<String, CellRevision>,
+}
+
+impl std::convert::From<CellChangeset> for RowMetaChangeset {
+    fn from(changeset: CellChangeset) -> Self {
+        let mut cell_by_field_id = HashMap::with_capacity(1);
+        let field_id = changeset.field_id;
+        let cell_rev = CellRevision {
+            data: changeset.cell_content_changeset.unwrap_or_else(|| "".to_owned()),
+        };
+        cell_by_field_id.insert(field_id, cell_rev);
+
+        RowMetaChangeset {
+            row_id: changeset.row_id,
+            height: None,
+            visibility: None,
+            cell_by_field_id,
+        }
+    }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
-pub struct CellMeta {
+pub struct CellRevision {
     pub data: String,
 }
 
-impl CellMeta {
+impl CellRevision {
     pub fn new(data: String) -> Self {
         Self { data }
     }
@@ -205,9 +268,9 @@ impl CellMeta {
 
 #[derive(Clone, Default, Deserialize, Serialize)]
 pub struct BuildGridContext {
-    pub field_metas: Vec<FieldMeta>,
-    pub blocks: Vec<GridBlockMeta>,
-    pub blocks_meta_data: Vec<GridBlockMetaData>,
+    pub field_revs: Vec<FieldRevision>,
+    pub blocks: Vec<GridBlockRevision>,
+    pub blocks_meta_data: Vec<GridBlockRevisionData>,
 }
 
 impl BuildGridContext {

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

@@ -1,9 +1,9 @@
-use flowy_grid_data_model::entities::*;
+use flowy_grid_data_model::revision::*;
 
 #[test]
 fn grid_default_serde_test() {
     let grid_id = "1".to_owned();
-    let grid = GridMeta {
+    let grid = GridRevision {
         grid_id,
         fields: vec![],
         blocks: vec![],

+ 77 - 72
shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs → shared-lib/flowy-sync/src/client_grid/grid_block_revsion_pad.rs

@@ -1,8 +1,8 @@
 use crate::entities::revision::{md5, RepeatedRevision, Revision};
 use crate::errors::{CollaborateError, CollaborateResult};
 use crate::util::{cal_diff, make_delta_from_revisions};
-use flowy_grid_data_model::entities::{
-    gen_block_id, gen_row_id, CellMeta, GridBlockMetaData, RowMeta, RowMetaChangeset,
+use flowy_grid_data_model::revision::{
+    gen_block_id, gen_row_id, CellRevision, GridBlockRevisionData, RowMetaChangeset, RowRevision,
 };
 use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder};
 use serde::{Deserialize, Serialize};
@@ -11,20 +11,20 @@ use std::borrow::Cow;
 use std::collections::HashMap;
 use std::sync::Arc;
 
-pub type GridBlockMetaDelta = PlainTextDelta;
-pub type GridBlockMetaDeltaBuilder = PlainTextDeltaBuilder;
+pub type GridBlockRevisionDelta = PlainTextDelta;
+pub type GridBlockRevisionDeltaBuilder = PlainTextDeltaBuilder;
 
 #[derive(Debug, Deserialize, Serialize, Clone)]
-pub struct GridBlockMetaPad {
+pub struct GridBlockRevisionPad {
     block_id: String,
-    rows: Vec<Arc<RowMeta>>,
+    rows: Vec<Arc<RowRevision>>,
 
     #[serde(skip)]
-    pub(crate) delta: GridBlockMetaDelta,
+    pub(crate) delta: GridBlockRevisionDelta,
 }
 
-impl GridBlockMetaPad {
-    pub async fn duplicate_data(&self, duplicated_block_id: &str) -> GridBlockMetaData {
+impl GridBlockRevisionPad {
+    pub async fn duplicate_data(&self, duplicated_block_id: &str) -> GridBlockRevisionData {
         let duplicated_rows = self
             .rows
             .iter()
@@ -34,34 +34,38 @@ impl GridBlockMetaPad {
                 duplicated_row.block_id = duplicated_block_id.to_string();
                 duplicated_row
             })
-            .collect::<Vec<RowMeta>>();
-        GridBlockMetaData {
+            .collect::<Vec<RowRevision>>();
+        GridBlockRevisionData {
             block_id: duplicated_block_id.to_string(),
             rows: duplicated_rows,
         }
     }
 
-    pub fn from_delta(delta: GridBlockMetaDelta) -> CollaborateResult<Self> {
+    pub fn from_delta(delta: GridBlockRevisionDelta) -> CollaborateResult<Self> {
         let s = delta.to_str()?;
-        let meta_data: GridBlockMetaData = serde_json::from_str(&s).map_err(|e| {
+        let meta_data: GridBlockRevisionData = serde_json::from_str(&s).map_err(|e| {
             let msg = format!("Deserialize delta to block meta failed: {}", e);
             tracing::error!("{}", s);
             CollaborateError::internal().context(msg)
         })?;
         let block_id = meta_data.block_id;
-        let rows = meta_data.rows.into_iter().map(Arc::new).collect::<Vec<Arc<RowMeta>>>();
+        let rows = meta_data
+            .rows
+            .into_iter()
+            .map(Arc::new)
+            .collect::<Vec<Arc<RowRevision>>>();
         Ok(Self { block_id, rows, delta })
     }
 
     pub fn from_revisions(_grid_id: &str, revisions: Vec<Revision>) -> CollaborateResult<Self> {
-        let block_delta: GridBlockMetaDelta = make_delta_from_revisions::<PlainTextAttributes>(revisions)?;
+        let block_delta: GridBlockRevisionDelta = make_delta_from_revisions::<PlainTextAttributes>(revisions)?;
         Self::from_delta(block_delta)
     }
 
     #[tracing::instrument(level = "trace", skip(self, row), err)]
-    pub fn add_row_meta(
+    pub fn add_row_rev(
         &mut self,
-        row: RowMeta,
+        row: RowRevision,
         start_row_id: Option<String>,
     ) -> CollaborateResult<Option<GridBlockMetaChange>> {
         self.modify(|rows| {
@@ -86,7 +90,7 @@ impl GridBlockMetaPad {
         })
     }
 
-    pub fn get_row_metas<T>(&self, row_ids: Option<Vec<Cow<'_, T>>>) -> CollaborateResult<Vec<Arc<RowMeta>>>
+    pub fn get_row_revs<T>(&self, row_ids: Option<Vec<Cow<'_, T>>>) -> CollaborateResult<Vec<Arc<RowRevision>>>
     where
         T: AsRef<str> + ToOwned + ?Sized,
     {
@@ -97,7 +101,7 @@ impl GridBlockMetaPad {
                     .rows
                     .iter()
                     .map(|row| (row.id.as_str(), row.clone()))
-                    .collect::<HashMap<&str, Arc<RowMeta>>>();
+                    .collect::<HashMap<&str, Arc<RowRevision>>>();
 
                 Ok(row_ids
                     .iter()
@@ -116,20 +120,20 @@ impl GridBlockMetaPad {
         }
     }
 
-    pub fn get_cell_metas(
+    pub fn get_cell_revs(
         &self,
         field_id: &str,
         row_ids: Option<Vec<Cow<'_, String>>>,
-    ) -> CollaborateResult<Vec<CellMeta>> {
-        let rows = self.get_row_metas(row_ids)?;
-        let cell_metas = rows
+    ) -> CollaborateResult<Vec<CellRevision>> {
+        let rows = self.get_row_revs(row_ids)?;
+        let cell_revs = rows
             .iter()
             .flat_map(|row| {
-                let cell_meta = row.cells.get(field_id)?;
-                Some(cell_meta.clone())
+                let cell_rev = row.cells.get(field_id)?;
+                Some(cell_rev.clone())
             })
-            .collect::<Vec<CellMeta>>();
-        Ok(cell_metas)
+            .collect::<Vec<CellRevision>>();
+        Ok(cell_revs)
     }
 
     pub fn number_of_rows(&self) -> i32 {
@@ -169,11 +173,11 @@ impl GridBlockMetaPad {
     }
 
     pub fn move_row(&mut self, row_id: &str, from: usize, to: usize) -> CollaborateResult<Option<GridBlockMetaChange>> {
-        self.modify(|row_metas| {
-            if let Some(position) = row_metas.iter().position(|row_meta| row_meta.id == row_id) {
+        self.modify(|row_revs| {
+            if let Some(position) = row_revs.iter().position(|row_rev| row_rev.id == row_id) {
                 debug_assert_eq!(from, position);
-                let row_meta = row_metas.remove(position);
-                row_metas.insert(to, row_meta);
+                let row_rev = row_revs.remove(position);
+                row_revs.insert(to, row_rev);
                 Ok(Some(()))
             } else {
                 Ok(None)
@@ -183,7 +187,7 @@ impl GridBlockMetaPad {
 
     pub fn modify<F>(&mut self, f: F) -> CollaborateResult<Option<GridBlockMetaChange>>
     where
-        F: for<'a> FnOnce(&'a mut Vec<Arc<RowMeta>>) -> CollaborateResult<Option<()>>,
+        F: for<'a> FnOnce(&'a mut Vec<Arc<RowRevision>>) -> CollaborateResult<Option<()>>,
     {
         let cloned_self = self.clone();
         match f(&mut self.rows)? {
@@ -209,11 +213,11 @@ impl GridBlockMetaPad {
 
     fn modify_row<F>(&mut self, row_id: &str, f: F) -> CollaborateResult<Option<GridBlockMetaChange>>
     where
-        F: FnOnce(&mut RowMeta) -> CollaborateResult<Option<()>>,
+        F: FnOnce(&mut RowRevision) -> CollaborateResult<Option<()>>,
     {
         self.modify(|rows| {
-            if let Some(row_meta) = rows.iter_mut().find(|row_meta| row_id == row_meta.id) {
-                f(Arc::make_mut(row_meta))
+            if let Some(row_rev) = rows.iter_mut().find(|row_rev| row_id == row_rev.id) {
+                f(Arc::make_mut(row_rev))
             } else {
                 tracing::warn!("[BlockMetaPad]: Can't find any row with id: {}", row_id);
                 Ok(None)
@@ -236,32 +240,32 @@ impl GridBlockMetaPad {
 }
 
 pub struct GridBlockMetaChange {
-    pub delta: GridBlockMetaDelta,
+    pub delta: GridBlockRevisionDelta,
     /// md5: the md5 of the grid after applying the change.
     pub md5: String,
 }
 
-pub fn make_block_meta_delta(grid_block_meta_data: &GridBlockMetaData) -> GridBlockMetaDelta {
+pub fn make_block_meta_delta(grid_block_meta_data: &GridBlockRevisionData) -> GridBlockRevisionDelta {
     let json = serde_json::to_string(&grid_block_meta_data).unwrap();
     PlainTextDeltaBuilder::new().insert(&json).build()
 }
 
-pub fn make_block_meta_revisions(user_id: &str, grid_block_meta_data: &GridBlockMetaData) -> RepeatedRevision {
+pub fn make_block_meta_revisions(user_id: &str, grid_block_meta_data: &GridBlockRevisionData) -> RepeatedRevision {
     let delta = make_block_meta_delta(grid_block_meta_data);
     let bytes = delta.to_delta_bytes();
     let revision = Revision::initial_revision(user_id, &grid_block_meta_data.block_id, bytes);
     revision.into()
 }
 
-impl std::default::Default for GridBlockMetaPad {
+impl std::default::Default for GridBlockRevisionPad {
     fn default() -> Self {
-        let block_meta_data = GridBlockMetaData {
+        let block_meta_data = GridBlockRevisionData {
             block_id: gen_block_id(),
             rows: vec![],
         };
 
         let delta = make_block_meta_delta(&block_meta_data);
-        GridBlockMetaPad {
+        GridBlockRevisionPad {
             block_id: block_meta_data.block_id,
             rows: block_meta_data.rows.into_iter().map(Arc::new).collect::<Vec<_>>(),
             delta,
@@ -271,14 +275,14 @@ impl std::default::Default for GridBlockMetaPad {
 
 #[cfg(test)]
 mod tests {
-    use crate::client_grid::{GridBlockMetaDelta, GridBlockMetaPad};
-    use flowy_grid_data_model::entities::{RowMeta, RowMetaChangeset};
+    use crate::client_grid::{GridBlockRevisionDelta, GridBlockRevisionPad};
+    use flowy_grid_data_model::revision::{RowMetaChangeset, RowRevision};
     use std::borrow::Cow;
 
     #[test]
     fn block_meta_add_row() {
         let mut pad = test_pad();
-        let row = RowMeta {
+        let row = RowRevision {
             id: "1".to_string(),
             block_id: pad.block_id.clone(),
             cells: Default::default(),
@@ -286,7 +290,7 @@ mod tests {
             visibility: false,
         };
 
-        let change = pad.add_row_meta(row.clone(), None).unwrap().unwrap();
+        let change = pad.add_row_rev(row.clone(), None).unwrap().unwrap();
         assert_eq!(pad.rows.first().unwrap().as_ref(), &row);
         assert_eq!(
             change.delta.to_delta_str(),
@@ -297,23 +301,23 @@ mod tests {
     #[test]
     fn block_meta_insert_row() {
         let mut pad = test_pad();
-        let row_1 = test_row_meta("1", &pad);
-        let row_2 = test_row_meta("2", &pad);
-        let row_3 = test_row_meta("3", &pad);
+        let row_1 = test_row_rev("1", &pad);
+        let row_2 = test_row_rev("2", &pad);
+        let row_3 = test_row_rev("3", &pad);
 
-        let change = pad.add_row_meta(row_1.clone(), None).unwrap().unwrap();
+        let change = pad.add_row_rev(row_1.clone(), None).unwrap().unwrap();
         assert_eq!(
             change.delta.to_delta_str(),
             r#"[{"retain":24},{"insert":"{\"id\":\"1\",\"block_id\":\"1\",\"cells\":[],\"height\":0,\"visibility\":false}"},{"retain":2}]"#
         );
 
-        let change = pad.add_row_meta(row_2.clone(), None).unwrap().unwrap();
+        let change = pad.add_row_rev(row_2.clone(), None).unwrap().unwrap();
         assert_eq!(
             change.delta.to_delta_str(),
             r#"[{"retain":90},{"insert":",{\"id\":\"2\",\"block_id\":\"1\",\"cells\":[],\"height\":0,\"visibility\":false}"},{"retain":2}]"#
         );
 
-        let change = pad.add_row_meta(row_3.clone(), Some("2".to_string())).unwrap().unwrap();
+        let change = pad.add_row_rev(row_3.clone(), Some("2".to_string())).unwrap().unwrap();
         assert_eq!(
             change.delta.to_delta_str(),
             r#"[{"retain":157},{"insert":",{\"id\":\"3\",\"block_id\":\"1\",\"cells\":[],\"height\":0,\"visibility\":false}"},{"retain":2}]"#
@@ -324,8 +328,8 @@ mod tests {
         assert_eq!(*pad.rows[2], row_3);
     }
 
-    fn test_row_meta(id: &str, pad: &GridBlockMetaPad) -> RowMeta {
-        RowMeta {
+    fn test_row_rev(id: &str, pad: &GridBlockRevisionPad) -> RowRevision {
+        RowRevision {
             id: id.to_string(),
             block_id: pad.block_id.clone(),
             cells: Default::default(),
@@ -337,13 +341,13 @@ mod tests {
     #[test]
     fn block_meta_insert_row2() {
         let mut pad = test_pad();
-        let row_1 = test_row_meta("1", &pad);
-        let row_2 = test_row_meta("2", &pad);
-        let row_3 = test_row_meta("3", &pad);
+        let row_1 = test_row_rev("1", &pad);
+        let row_2 = test_row_rev("2", &pad);
+        let row_3 = test_row_rev("3", &pad);
 
-        let _ = pad.add_row_meta(row_1.clone(), None).unwrap().unwrap();
-        let _ = pad.add_row_meta(row_2.clone(), None).unwrap().unwrap();
-        let _ = pad.add_row_meta(row_3.clone(), Some("1".to_string())).unwrap().unwrap();
+        let _ = pad.add_row_rev(row_1.clone(), None).unwrap().unwrap();
+        let _ = pad.add_row_rev(row_2.clone(), None).unwrap().unwrap();
+        let _ = pad.add_row_rev(row_3.clone(), Some("1".to_string())).unwrap().unwrap();
 
         assert_eq!(*pad.rows[0], row_1);
         assert_eq!(*pad.rows[1], row_3);
@@ -353,13 +357,13 @@ mod tests {
     #[test]
     fn block_meta_insert_row3() {
         let mut pad = test_pad();
-        let row_1 = test_row_meta("1", &pad);
-        let row_2 = test_row_meta("2", &pad);
-        let row_3 = test_row_meta("3", &pad);
+        let row_1 = test_row_rev("1", &pad);
+        let row_2 = test_row_rev("2", &pad);
+        let row_3 = test_row_rev("3", &pad);
 
-        let _ = pad.add_row_meta(row_1.clone(), None).unwrap().unwrap();
-        let _ = pad.add_row_meta(row_2.clone(), None).unwrap().unwrap();
-        let _ = pad.add_row_meta(row_3.clone(), Some("".to_string())).unwrap().unwrap();
+        let _ = pad.add_row_rev(row_1.clone(), None).unwrap().unwrap();
+        let _ = pad.add_row_rev(row_2.clone(), None).unwrap().unwrap();
+        let _ = pad.add_row_rev(row_3.clone(), Some("".to_string())).unwrap().unwrap();
 
         assert_eq!(*pad.rows[0], row_1);
         assert_eq!(*pad.rows[1], row_2);
@@ -370,7 +374,7 @@ mod tests {
     fn block_meta_delete_row() {
         let mut pad = test_pad();
         let pre_delta_str = pad.delta_str();
-        let row = RowMeta {
+        let row = RowRevision {
             id: "1".to_string(),
             block_id: pad.block_id.clone(),
             cells: Default::default(),
@@ -378,7 +382,7 @@ mod tests {
             visibility: false,
         };
 
-        let _ = pad.add_row_meta(row.clone(), None).unwrap().unwrap();
+        let _ = pad.add_row_rev(row.clone(), None).unwrap().unwrap();
         let change = pad.delete_rows(vec![Cow::Borrowed(&row.id)]).unwrap().unwrap();
         assert_eq!(
             change.delta.to_delta_str(),
@@ -391,7 +395,7 @@ mod tests {
     #[test]
     fn block_meta_update_row() {
         let mut pad = test_pad();
-        let row = RowMeta {
+        let row = RowRevision {
             id: "1".to_string(),
             block_id: pad.block_id.clone(),
             cells: Default::default(),
@@ -406,7 +410,7 @@ mod tests {
             cell_by_field_id: Default::default(),
         };
 
-        let _ = pad.add_row_meta(row, None).unwrap().unwrap();
+        let _ = pad.add_row_rev(row, None).unwrap().unwrap();
         let change = pad.update_row(changeset).unwrap().unwrap();
 
         assert_eq!(
@@ -420,8 +424,9 @@ mod tests {
         );
     }
 
-    fn test_pad() -> GridBlockMetaPad {
-        let delta = GridBlockMetaDelta::from_delta_str(r#"[{"insert":"{\"block_id\":\"1\",\"rows\":[]}"}]"#).unwrap();
-        GridBlockMetaPad::from_delta(delta).unwrap()
+    fn test_pad() -> GridBlockRevisionPad {
+        let delta =
+            GridBlockRevisionDelta::from_delta_str(r#"[{"insert":"{\"block_id\":\"1\",\"rows\":[]}"}]"#).unwrap();
+        GridBlockRevisionPad::from_delta(delta).unwrap()
     }
 }

+ 18 - 15
shared-lib/flowy-sync/src/client_grid/grid_builder.rs

@@ -1,5 +1,7 @@
 use crate::errors::{CollaborateError, CollaborateResult};
-use flowy_grid_data_model::entities::{BuildGridContext, FieldMeta, GridBlockMeta, GridBlockMetaData, RowMeta};
+use flowy_grid_data_model::revision::{
+    BuildGridContext, FieldRevision, GridBlockRevision, GridBlockRevisionData, RowRevision,
+};
 
 pub struct GridBuilder {
     build_context: BuildGridContext,
@@ -9,8 +11,8 @@ impl std::default::Default for GridBuilder {
     fn default() -> Self {
         let mut build_context = BuildGridContext::new();
 
-        let block_meta = GridBlockMeta::new();
-        let block_meta_data = GridBlockMetaData {
+        let block_meta = GridBlockRevision::new();
+        let block_meta_data = GridBlockRevisionData {
             block_id: block_meta.block_id.clone(),
             rows: vec![],
         };
@@ -23,13 +25,13 @@ impl std::default::Default for GridBuilder {
 }
 
 impl GridBuilder {
-    pub fn add_field(mut self, field: FieldMeta) -> Self {
-        self.build_context.field_metas.push(field);
+    pub fn add_field(mut self, field: FieldRevision) -> Self {
+        self.build_context.field_revs.push(field);
         self
     }
 
     pub fn add_empty_row(mut self) -> Self {
-        let row = RowMeta::new(&self.build_context.blocks.first().unwrap().block_id);
+        let row = RowRevision::new(&self.build_context.blocks.first().unwrap().block_id);
         let block_meta = self.build_context.blocks.first_mut().unwrap();
         let block_meta_data = self.build_context.blocks_meta_data.first_mut().unwrap();
         block_meta_data.rows.push(row);
@@ -43,7 +45,7 @@ impl GridBuilder {
 }
 
 #[allow(dead_code)]
-fn check_rows(fields: &[FieldMeta], rows: &[RowMeta]) -> CollaborateResult<()> {
+fn check_rows(fields: &[FieldRevision], rows: &[RowRevision]) -> CollaborateResult<()> {
     let field_ids = fields.iter().map(|field| &field.id).collect::<Vec<&String>>();
     for row in rows {
         let cell_field_ids = row.cells.keys().into_iter().collect::<Vec<&String>>();
@@ -59,29 +61,30 @@ fn check_rows(fields: &[FieldMeta], rows: &[RowMeta]) -> CollaborateResult<()> {
 mod tests {
 
     use crate::client_grid::{make_block_meta_delta, make_grid_delta, GridBuilder};
-    use flowy_grid_data_model::entities::{FieldMeta, FieldType, GridBlockMetaData, GridMeta};
+    use flowy_grid_data_model::entities::FieldType;
+    use flowy_grid_data_model::revision::{FieldRevision, GridBlockRevisionData, GridRevision};
 
     #[test]
     fn create_default_grid_test() {
         let grid_id = "1".to_owned();
         let build_context = GridBuilder::default()
-            .add_field(FieldMeta::new("Name", "", FieldType::RichText, true))
-            .add_field(FieldMeta::new("Tags", "", FieldType::SingleSelect, false))
+            .add_field(FieldRevision::new("Name", "", FieldType::RichText, true))
+            .add_field(FieldRevision::new("Tags", "", FieldType::SingleSelect, false))
             .add_empty_row()
             .add_empty_row()
             .add_empty_row()
             .build();
 
-        let grid_meta = GridMeta {
+        let grid_rev = GridRevision {
             grid_id,
-            fields: build_context.field_metas,
+            fields: build_context.field_revs,
             blocks: build_context.blocks,
         };
 
-        let grid_meta_delta = make_grid_delta(&grid_meta);
-        let _: GridMeta = serde_json::from_str(&grid_meta_delta.to_str().unwrap()).unwrap();
+        let grid_meta_delta = make_grid_delta(&grid_rev);
+        let _: GridRevision = serde_json::from_str(&grid_meta_delta.to_str().unwrap()).unwrap();
 
         let grid_block_meta_delta = make_block_meta_delta(build_context.blocks_meta_data.first().unwrap());
-        let _: GridBlockMetaData = serde_json::from_str(&grid_block_meta_delta.to_str().unwrap()).unwrap();
+        let _: GridBlockRevisionData = serde_json::from_str(&grid_block_meta_delta.to_str().unwrap()).unwrap();
     }
 }

+ 74 - 69
shared-lib/flowy-sync/src/client_grid/grid_meta_pad.rs → shared-lib/flowy-sync/src/client_grid/grid_revision_pad.rs

@@ -2,33 +2,35 @@ use crate::entities::revision::{md5, RepeatedRevision, Revision};
 use crate::errors::{internal_error, CollaborateError, CollaborateResult};
 use crate::util::{cal_diff, make_delta_from_revisions};
 use bytes::Bytes;
-use flowy_grid_data_model::entities::{
-    gen_block_id, gen_grid_id, FieldChangesetParams, FieldMeta, FieldOrder, FieldType, GridBlockMeta,
-    GridBlockMetaChangeset, GridMeta,
+use flowy_grid_data_model::entities::FieldType;
+use flowy_grid_data_model::entities::{FieldChangesetParams, FieldOrder};
+use flowy_grid_data_model::revision::{
+    gen_block_id, gen_grid_id, FieldRevision, GridBlockRevision, GridBlockRevisionChangeset, GridRevision,
 };
+use futures::StreamExt;
 use lib_infra::util::move_vec_element;
 use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder};
 use std::collections::HashMap;
 use std::sync::Arc;
 
-pub type GridMetaDelta = PlainTextDelta;
-pub type GridDeltaBuilder = PlainTextDeltaBuilder;
+pub type GridRevisionDelta = PlainTextDelta;
+pub type GridRevisionDeltaBuilder = PlainTextDeltaBuilder;
 
-pub struct GridMetaPad {
-    pub(crate) grid_meta: Arc<GridMeta>,
-    pub(crate) delta: GridMetaDelta,
+pub struct GridRevisionPad {
+    pub(crate) grid_rev: Arc<GridRevision>,
+    pub(crate) delta: GridRevisionDelta,
 }
 
 pub trait JsonDeserializer {
     fn deserialize(&self, type_option_data: Vec<u8>) -> CollaborateResult<String>;
 }
 
-impl GridMetaPad {
-    pub async fn duplicate_grid_meta(&self) -> (Vec<FieldMeta>, Vec<GridBlockMeta>) {
-        let fields = self.grid_meta.fields.to_vec();
+impl GridRevisionPad {
+    pub async fn duplicate_grid_meta(&self) -> (Vec<FieldRevision>, Vec<GridBlockRevision>) {
+        let fields = self.grid_rev.fields.to_vec();
 
         let blocks = self
-            .grid_meta
+            .grid_rev
             .blocks
             .iter()
             .map(|block| {
@@ -36,31 +38,31 @@ impl GridMetaPad {
                 duplicated_block.block_id = gen_block_id();
                 duplicated_block
             })
-            .collect::<Vec<GridBlockMeta>>();
+            .collect::<Vec<GridBlockRevision>>();
 
         (fields, blocks)
     }
 
-    pub fn from_delta(delta: GridMetaDelta) -> CollaborateResult<Self> {
+    pub fn from_delta(delta: GridRevisionDelta) -> CollaborateResult<Self> {
         let s = delta.to_str()?;
-        let grid: GridMeta = serde_json::from_str(&s)
+        let grid: GridRevision = serde_json::from_str(&s)
             .map_err(|e| CollaborateError::internal().context(format!("Deserialize delta to grid failed: {}", e)))?;
 
         Ok(Self {
-            grid_meta: Arc::new(grid),
+            grid_rev: Arc::new(grid),
             delta,
         })
     }
 
     pub fn from_revisions(_grid_id: &str, revisions: Vec<Revision>) -> CollaborateResult<Self> {
-        let grid_delta: GridMetaDelta = make_delta_from_revisions::<PlainTextAttributes>(revisions)?;
+        let grid_delta: GridRevisionDelta = make_delta_from_revisions::<PlainTextAttributes>(revisions)?;
         Self::from_delta(grid_delta)
     }
 
     #[tracing::instrument(level = "debug", skip_all, err)]
-    pub fn create_field_meta(
+    pub fn create_field_rev(
         &mut self,
-        new_field_meta: FieldMeta,
+        new_field_rev: FieldRevision,
         start_field_id: Option<String>,
     ) -> CollaborateResult<Option<GridChangeset>> {
         self.modify_grid(|grid_meta| {
@@ -68,7 +70,7 @@ impl GridMetaPad {
             if grid_meta
                 .fields
                 .iter()
-                .any(|field_meta| field_meta.id == new_field_meta.id)
+                .any(|field_rev| field_rev.id == new_field_rev.id)
             {
                 tracing::error!("Duplicate grid field");
                 return Ok(None);
@@ -80,14 +82,14 @@ impl GridMetaPad {
             };
 
             match insert_index {
-                None => grid_meta.fields.push(new_field_meta),
-                Some(index) => grid_meta.fields.insert(index, new_field_meta),
+                None => grid_meta.fields.push(new_field_rev),
+                Some(index) => grid_meta.fields.insert(index, new_field_rev),
             }
             Ok(Some(()))
         })
     }
 
-    pub fn delete_field_meta(&mut self, field_id: &str) -> CollaborateResult<Option<GridChangeset>> {
+    pub fn delete_field_rev(&mut self, field_id: &str) -> CollaborateResult<Option<GridChangeset>> {
         self.modify_grid(
             |grid_meta| match grid_meta.fields.iter().position(|field| field.id == field_id) {
                 None => Ok(None),
@@ -99,7 +101,7 @@ impl GridMetaPad {
         )
     }
 
-    pub fn duplicate_field_meta(
+    pub fn duplicate_field_rev(
         &mut self,
         field_id: &str,
         duplicated_field_id: &str,
@@ -108,10 +110,10 @@ impl GridMetaPad {
             |grid_meta| match grid_meta.fields.iter().position(|field| field.id == field_id) {
                 None => Ok(None),
                 Some(index) => {
-                    let mut duplicate_field_meta = grid_meta.fields[index].clone();
-                    duplicate_field_meta.id = duplicated_field_id.to_string();
-                    duplicate_field_meta.name = format!("{} (copy)", duplicate_field_meta.name);
-                    grid_meta.fields.insert(index + 1, duplicate_field_meta);
+                    let mut duplicate_field_rev = grid_meta.fields[index].clone();
+                    duplicate_field_rev.id = duplicated_field_id.to_string();
+                    duplicate_field_rev.name = format!("{} (copy)", duplicate_field_rev.name);
+                    grid_meta.fields.insert(index + 1, duplicate_field_rev);
                     Ok(Some(()))
                 }
             },
@@ -129,25 +131,25 @@ impl GridMetaPad {
     {
         self.modify_grid(|grid_meta| {
             //
-            match grid_meta.fields.iter_mut().find(|field_meta| field_meta.id == field_id) {
+            match grid_meta.fields.iter_mut().find(|field_rev| field_rev.id == field_id) {
                 None => {
                     tracing::warn!("Can not find the field with id: {}", field_id);
                     Ok(None)
                 }
-                Some(field_meta) => {
-                    if field_meta.get_type_option_str(&field_type).is_none() {
+                Some(field_rev) => {
+                    if field_rev.get_type_option_str(&field_type).is_none() {
                         let type_option_json = type_option_json_builder(&field_type);
-                        field_meta.insert_type_option_str(&field_type, type_option_json);
+                        field_rev.insert_type_option_str(&field_type, type_option_json);
                     }
 
-                    field_meta.field_type = field_type;
+                    field_rev.field_type = field_type;
                     Ok(Some(()))
                 }
             }
         })
     }
 
-    pub fn update_field_meta<T: JsonDeserializer>(
+    pub fn update_field_rev<T: JsonDeserializer>(
         &mut self,
         changeset: FieldChangesetParams,
         deserializer: T,
@@ -202,21 +204,21 @@ impl GridMetaPad {
         })
     }
 
-    pub fn get_field_meta(&self, field_id: &str) -> Option<(usize, &FieldMeta)> {
-        self.grid_meta
+    pub fn get_field_rev(&self, field_id: &str) -> Option<(usize, &FieldRevision)> {
+        self.grid_rev
             .fields
             .iter()
             .enumerate()
             .find(|(_, field)| field.id == field_id)
     }
 
-    pub fn replace_field_meta(&mut self, field_meta: FieldMeta) -> CollaborateResult<Option<GridChangeset>> {
+    pub fn replace_field_rev(&mut self, field_rev: FieldRevision) -> CollaborateResult<Option<GridChangeset>> {
         self.modify_grid(
-            |grid_meta| match grid_meta.fields.iter().position(|field| field.id == field_meta.id) {
+            |grid_meta| match grid_meta.fields.iter().position(|field| field.id == field_rev.id) {
                 None => Ok(None),
                 Some(index) => {
                     grid_meta.fields.remove(index);
-                    grid_meta.fields.insert(index, field_meta);
+                    grid_meta.fields.insert(index, field_rev);
                     Ok(Some(()))
                 }
             },
@@ -245,23 +247,23 @@ impl GridMetaPad {
     }
 
     pub fn contain_field(&self, field_id: &str) -> bool {
-        self.grid_meta.fields.iter().any(|field| field.id == field_id)
+        self.grid_rev.fields.iter().any(|field| field.id == field_id)
     }
 
     pub fn get_field_orders(&self) -> Vec<FieldOrder> {
-        self.grid_meta.fields.iter().map(FieldOrder::from).collect()
+        self.grid_rev.fields.iter().map(FieldOrder::from).collect()
     }
 
-    pub fn get_field_metas(&self, field_orders: Option<Vec<FieldOrder>>) -> CollaborateResult<Vec<FieldMeta>> {
+    pub fn get_field_revs(&self, field_orders: Option<Vec<FieldOrder>>) -> CollaborateResult<Vec<FieldRevision>> {
         match field_orders {
-            None => Ok(self.grid_meta.fields.clone()),
+            None => Ok(self.grid_rev.fields.clone()),
             Some(field_orders) => {
                 let field_by_field_id = self
-                    .grid_meta
+                    .grid_rev
                     .fields
                     .iter()
                     .map(|field| (&field.id, field))
-                    .collect::<HashMap<&String, &FieldMeta>>();
+                    .collect::<HashMap<&String, &FieldRevision>>();
 
                 let fields = field_orders
                     .iter()
@@ -272,13 +274,13 @@ impl GridMetaPad {
                         }
                         Some(field) => Some((*field).clone()),
                     })
-                    .collect::<Vec<FieldMeta>>();
+                    .collect::<Vec<FieldRevision>>();
                 Ok(fields)
             }
         }
     }
 
-    pub fn create_block_meta(&mut self, block: GridBlockMeta) -> CollaborateResult<Option<GridChangeset>> {
+    pub fn create_block_meta(&mut self, block: GridBlockRevision) -> CollaborateResult<Option<GridChangeset>> {
         self.modify_grid(|grid_meta| {
             if grid_meta.blocks.iter().any(|b| b.block_id == block.block_id) {
                 tracing::warn!("Duplicate grid block");
@@ -301,11 +303,14 @@ impl GridMetaPad {
         })
     }
 
-    pub fn get_block_metas(&self) -> Vec<GridBlockMeta> {
-        self.grid_meta.blocks.clone()
+    pub fn get_block_metas(&self) -> Vec<GridBlockRevision> {
+        self.grid_rev.blocks.clone()
     }
 
-    pub fn update_block_meta(&mut self, changeset: GridBlockMetaChangeset) -> CollaborateResult<Option<GridChangeset>> {
+    pub fn update_block_meta(
+        &mut self,
+        changeset: GridBlockRevisionChangeset,
+    ) -> CollaborateResult<Option<GridChangeset>> {
         let block_id = changeset.block_id.clone();
         self.modify_block(&block_id, |block| {
             let mut is_changed = None;
@@ -336,20 +341,20 @@ impl GridMetaPad {
         self.delta.to_delta_bytes()
     }
 
-    pub fn fields(&self) -> &[FieldMeta] {
-        &self.grid_meta.fields
+    pub fn fields(&self) -> &[FieldRevision] {
+        &self.grid_rev.fields
     }
 
     fn modify_grid<F>(&mut self, f: F) -> CollaborateResult<Option<GridChangeset>>
     where
-        F: FnOnce(&mut GridMeta) -> CollaborateResult<Option<()>>,
+        F: FnOnce(&mut GridRevision) -> CollaborateResult<Option<()>>,
     {
-        let cloned_grid = self.grid_meta.clone();
-        match f(Arc::make_mut(&mut self.grid_meta))? {
+        let cloned_grid = self.grid_rev.clone();
+        match f(Arc::make_mut(&mut self.grid_rev))? {
             None => Ok(None),
             Some(_) => {
                 let old = json_from_grid(&cloned_grid)?;
-                let new = json_from_grid(&self.grid_meta)?;
+                let new = json_from_grid(&self.grid_rev)?;
                 match cal_diff::<PlainTextAttributes>(old, new) {
                     None => Ok(None),
                     Some(delta) => {
@@ -363,7 +368,7 @@ impl GridMetaPad {
 
     pub fn modify_block<F>(&mut self, block_id: &str, f: F) -> CollaborateResult<Option<GridChangeset>>
     where
-        F: FnOnce(&mut GridBlockMeta) -> CollaborateResult<Option<()>>,
+        F: FnOnce(&mut GridBlockRevision) -> CollaborateResult<Option<()>>,
     {
         self.modify_grid(
             |grid_meta| match grid_meta.blocks.iter().position(|block| block.block_id == block_id) {
@@ -378,7 +383,7 @@ impl GridMetaPad {
 
     pub fn modify_field<F>(&mut self, field_id: &str, f: F) -> CollaborateResult<Option<GridChangeset>>
     where
-        F: FnOnce(&mut FieldMeta) -> CollaborateResult<Option<()>>,
+        F: FnOnce(&mut FieldRevision) -> CollaborateResult<Option<()>>,
     {
         self.modify_grid(
             |grid_meta| match grid_meta.fields.iter().position(|field| field.id == field_id) {
@@ -392,40 +397,40 @@ impl GridMetaPad {
     }
 }
 
-fn json_from_grid(grid: &Arc<GridMeta>) -> CollaborateResult<String> {
+fn json_from_grid(grid: &Arc<GridRevision>) -> CollaborateResult<String> {
     let json = serde_json::to_string(grid)
         .map_err(|err| internal_error(format!("Serialize grid to json str failed. {:?}", err)))?;
     Ok(json)
 }
 
 pub struct GridChangeset {
-    pub delta: GridMetaDelta,
+    pub delta: GridRevisionDelta,
     /// md5: the md5 of the grid after applying the change.
     pub md5: String,
 }
 
-pub fn make_grid_delta(grid_meta: &GridMeta) -> GridMetaDelta {
-    let json = serde_json::to_string(&grid_meta).unwrap();
+pub fn make_grid_delta(grid_rev: &GridRevision) -> GridRevisionDelta {
+    let json = serde_json::to_string(&grid_rev).unwrap();
     PlainTextDeltaBuilder::new().insert(&json).build()
 }
 
-pub fn make_grid_revisions(user_id: &str, grid_meta: &GridMeta) -> RepeatedRevision {
-    let delta = make_grid_delta(grid_meta);
+pub fn make_grid_revisions(user_id: &str, grid_rev: &GridRevision) -> RepeatedRevision {
+    let delta = make_grid_delta(grid_rev);
     let bytes = delta.to_delta_bytes();
-    let revision = Revision::initial_revision(user_id, &grid_meta.grid_id, bytes);
+    let revision = Revision::initial_revision(user_id, &grid_rev.grid_id, bytes);
     revision.into()
 }
 
-impl std::default::Default for GridMetaPad {
+impl std::default::Default for GridRevisionPad {
     fn default() -> Self {
-        let grid = GridMeta {
+        let grid = GridRevision {
             grid_id: gen_grid_id(),
             fields: vec![],
             blocks: vec![],
         };
         let delta = make_grid_delta(&grid);
-        GridMetaPad {
-            grid_meta: Arc::new(grid),
+        GridRevisionPad {
+            grid_rev: Arc::new(grid),
             delta,
         }
     }

+ 4 - 4
shared-lib/flowy-sync/src/client_grid/mod.rs

@@ -1,7 +1,7 @@
-mod grid_block_meta_pad;
+mod grid_block_revsion_pad;
 mod grid_builder;
-mod grid_meta_pad;
+mod grid_revision_pad;
 
-pub use grid_block_meta_pad::*;
+pub use grid_block_revsion_pad::*;
 pub use grid_builder::*;
-pub use grid_meta_pad::*;
+pub use grid_revision_pad::*;

Some files were not shown because too many files changed in this diff