Просмотр исходного кода

chore: support including time on date type

appflowy 3 лет назад
Родитель
Сommit
a049034110
29 измененных файлов с 382 добавлено и 245 удалено
  1. 14 1
      frontend/Makefile.toml
  2. 1 0
      frontend/app_flowy/assets/translations/en.json
  3. 5 5
      frontend/app_flowy/lib/workspace/application/grid/cell_bloc/select_option_service.dart
  4. 2 2
      frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart
  5. 21 10
      frontend/app_flowy/lib/workspace/application/grid/field/type_option/date_bloc.dart
  6. 14 5
      frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart
  7. 32 0
      frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart
  8. 10 10
      frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart
  9. 2 2
      frontend/app_flowy/packages/flowy_sdk/lib/ffi.dart
  10. 18 18
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart
  11. 5 5
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart
  12. 14 0
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_type_option.pb.dart
  13. 2 1
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_type_option.pbjson.dart
  14. 6 6
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbenum.dart
  15. 4 4
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart
  16. 2 2
      frontend/app_flowy/packages/flowy_sdk/macos/flowy_sdk.podspec
  17. 18 6
      frontend/rust-lib/flowy-grid/src/event_handler.rs
  18. 8 10
      frontend/rust-lib/flowy-grid/src/event_map.rs
  19. 42 6
      frontend/rust-lib/flowy-grid/src/protobuf/model/date_type_option.rs
  20. 16 16
      frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs
  21. 1 0
      frontend/rust-lib/flowy-grid/src/protobuf/proto/date_type_option.proto
  22. 3 3
      frontend/rust-lib/flowy-grid/src/protobuf/proto/event_map.proto
  23. 84 77
      frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs
  24. 5 3
      frontend/rust-lib/flowy-grid/src/services/grid_editor.rs
  25. 1 1
      frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs
  26. 8 8
      frontend/rust-lib/flowy-grid/tests/grid/script.rs
  27. 5 5
      shared-lib/flowy-grid-data-model/src/entities/grid.rs
  28. 38 38
      shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs
  29. 1 1
      shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto

+ 14 - 1
frontend/Makefile.toml

@@ -24,7 +24,20 @@ LIB_NAME = "dart_ffi"
 CURRENT_APP_VERSION = "0.0.4"
 FEATURES = "flutter"
 PRODUCT_NAME = "AppFlowy"
-#CRATE_TYPE: https://doc.rust-lang.org/reference/linkage.html
+# CRATE_TYPE: https://doc.rust-lang.org/reference/linkage.html
+# If you update the macOS's CRATE_TYPE, don't forget to update the
+# flowy_sdk.podspec
+#   for staticlib:
+#        s.static_framework = true
+#        s.vendored_libraries = "libdart_ffi.a"
+#   for cdylib:
+#        s.vendored_libraries = "libdart_ffi.dylib"
+#
+# Remember to update the ffi.dart:
+#   for staticlib:
+#       if (Platform.isMacOS) return DynamicLibrary.open('${prefix}/libdart_ffi.a');
+#   for cdylib:
+#       if (Platform.isMacOS) return DynamicLibrary.open('${prefix}/libdart_ffi.dylib');
 CRATE_TYPE = "staticlib"
 SDK_EXT = "a"
 APP_ENVIRONMENT = "local"

+ 1 - 0
frontend/app_flowy/assets/translations/en.json

@@ -162,6 +162,7 @@
       "multiSelectFieldName": "Multiselect",
       "numberFormat": " Number format",
       "dateFormat": " Date format",
+      "includeTime": " Include time",
       "dateFormatFriendly": "Month Day,Year",
       "dateFormatISO": "Year-Month-Day",
       "dateFormatLocal": "Month/Month/Day",

+ 5 - 5
frontend/app_flowy/lib/workspace/application/grid/cell_bloc/select_option_service.dart

@@ -24,7 +24,7 @@ class SelectOptionService {
             final payload = SelectOptionChangesetPayload.create()
               ..insertOption = option
               ..cellIdentifier = cellIdentifier;
-            return GridEventApplySelectOptionChangeset(payload).send();
+            return GridEventUpdateSelectOption(payload).send();
           },
           (r) => right(r),
         );
@@ -45,7 +45,7 @@ class SelectOptionService {
     final payload = SelectOptionChangesetPayload.create()
       ..updateOption = option
       ..cellIdentifier = cellIdentifier;
-    return GridEventApplySelectOptionChangeset(payload).send();
+    return GridEventUpdateSelectOption(payload).send();
   }
 
   Future<Either<Unit, FlowyError>> delete({
@@ -63,7 +63,7 @@ class SelectOptionService {
       ..deleteOption = option
       ..cellIdentifier = cellIdentifier;
 
-    return GridEventApplySelectOptionChangeset(payload).send();
+    return GridEventUpdateSelectOption(payload).send();
   }
 
   Future<Either<SelectOptionContext, FlowyError>> getOpitonContext({
@@ -90,7 +90,7 @@ class SelectOptionService {
       ..fieldId = fieldId
       ..rowId = rowId
       ..insertOptionId = optionId;
-    return GridEventApplySelectOptionCellChangeset(payload).send();
+    return GridEventUpdateCellSelectOption(payload).send();
   }
 
   Future<Either<void, FlowyError>> remove({
@@ -104,6 +104,6 @@ class SelectOptionService {
       ..fieldId = fieldId
       ..rowId = rowId
       ..deleteOptionId = optionId;
-    return GridEventApplySelectOptionCellChangeset(payload).send();
+    return GridEventUpdateCellSelectOption(payload).send();
   }
 }

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

@@ -65,7 +65,7 @@ class FieldService {
     List<int>? typeOptionData,
     String? startFieldId,
   }) {
-    var payload = CreateFieldPayload.create()
+    var payload = InsertFieldPayload.create()
       ..gridId = gridId
       ..field_2 = field
       ..typeOptionData = typeOptionData ?? [];
@@ -74,7 +74,7 @@ class FieldService {
       payload.startFieldId = startFieldId;
     }
 
-    return GridEventCreateField(payload).send();
+    return GridEventInsertField(payload).send();
   }
 
   Future<Either<Unit, FlowyError>> deleteField({

+ 21 - 10
frontend/app_flowy/lib/workspace/application/grid/field/type_option/date_bloc.dart

@@ -11,27 +11,37 @@ class DateTypeOptionBloc extends Bloc<DateTypeOptionEvent, DateTypeOptionState>
       (event, emit) async {
         event.map(
           didSelectDateFormat: (_DidSelectDateFormat value) {
-            emit(state.copyWith(typeOption: _updateDateFormat(value.format)));
+            emit(state.copyWith(typeOption: _updateTypeOption(dateFormat: value.format)));
           },
           didSelectTimeFormat: (_DidSelectTimeFormat value) {
-            emit(state.copyWith(typeOption: _updateTimeFormat(value.format)));
+            emit(state.copyWith(typeOption: _updateTypeOption(timeFormat: value.format)));
+          },
+          includeTime: (_IncludeTime value) {
+            emit(state.copyWith(typeOption: _updateTypeOption(includeTime: value.includeTime)));
           },
         );
       },
     );
   }
 
-  DateTypeOption _updateTimeFormat(TimeFormat format) {
+  DateTypeOption _updateTypeOption({
+    DateFormat? dateFormat,
+    TimeFormat? timeFormat,
+    bool? includeTime,
+  }) {
     state.typeOption.freeze();
     return state.typeOption.rebuild((typeOption) {
-      typeOption.timeFormat = format;
-    });
-  }
+      if (dateFormat != null) {
+        typeOption.dateFormat = dateFormat;
+      }
 
-  DateTypeOption _updateDateFormat(DateFormat format) {
-    state.typeOption.freeze();
-    return state.typeOption.rebuild((typeOption) {
-      typeOption.dateFormat = format;
+      if (timeFormat != null) {
+        typeOption.timeFormat = timeFormat;
+      }
+
+      if (includeTime != null) {
+        typeOption.includeTime = includeTime;
+      }
     });
   }
 
@@ -45,6 +55,7 @@ class DateTypeOptionBloc extends Bloc<DateTypeOptionEvent, DateTypeOptionState>
 class DateTypeOptionEvent with _$DateTypeOptionEvent {
   const factory DateTypeOptionEvent.didSelectDateFormat(DateFormat format) = _DidSelectDateFormat;
   const factory DateTypeOptionEvent.didSelectTimeFormat(TimeFormat format) = _DidSelectTimeFormat;
+  const factory DateTypeOptionEvent.includeTime(bool includeTime) = _IncludeTime;
 }
 
 @freezed

+ 14 - 5
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell.dart

@@ -43,9 +43,9 @@ class _DateCellState extends State<DateCell> {
                 _CellCalendar.show(
                   context,
                   onSelected: (day) {
-                    widget.setFocus(context, false);
                     context.read<DateCellBloc>().add(DateCellEvent.selectDay(day));
                   },
+                  onDismissed: () => widget.setFocus(context, false),
                 );
               },
               child: MouseRegion(
@@ -71,17 +71,22 @@ final kToday = DateTime.now();
 final kFirstDay = DateTime(kToday.year, kToday.month - 3, kToday.day);
 final kLastDay = DateTime(kToday.year, kToday.month + 3, kToday.day);
 
-class _CellCalendar extends StatefulWidget {
+class _CellCalendar extends StatefulWidget with FlowyOverlayDelegate {
   final void Function(DateTime) onSelected;
-  const _CellCalendar({required this.onSelected, Key? key}) : super(key: key);
+  final VoidCallback onDismissed;
+  const _CellCalendar({required this.onSelected, required this.onDismissed, Key? key}) : super(key: key);
 
   @override
   State<_CellCalendar> createState() => _CellCalendarState();
 
-  static Future<void> show(BuildContext context, {required void Function(DateTime) onSelected}) async {
+  static Future<void> show(
+    BuildContext context, {
+    required void Function(DateTime) onSelected,
+    required VoidCallback onDismissed,
+  }) async {
     _CellCalendar.remove(context);
     final window = await getWindowInfo();
-    final calendar = _CellCalendar(onSelected: onSelected);
+    final calendar = _CellCalendar(onSelected: onSelected, onDismissed: onDismissed);
     const size = Size(460, 400);
     FlowyOverlay.of(context).insertWithRect(
       widget: OverlayContainer(
@@ -93,6 +98,7 @@ class _CellCalendar extends StatefulWidget {
       anchorSize: window.frame.size,
       anchorDirection: AnchorDirection.center,
       style: FlowyOverlayStyle(blur: false),
+      delegate: calendar,
     );
   }
 
@@ -103,6 +109,9 @@ class _CellCalendar extends StatefulWidget {
   static String identifier() {
     return (_CellCalendar).toString();
   }
+
+  @override
+  void didRemove() => onDismissed();
 }
 
 class _CellCalendarState extends State<_CellCalendar> {

+ 32 - 0
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart

@@ -52,6 +52,7 @@ class DateTypeOptionWidget extends TypeOptionWidget {
           return Column(children: [
             _dateFormatButton(context, state.typeOption.dateFormat),
             _timeFormatButton(context, state.typeOption.timeFormat),
+            const _IncludeTimeButton(),
           ]);
         },
       ),
@@ -102,6 +103,37 @@ class DateTypeOptionWidget extends TypeOptionWidget {
   }
 }
 
+class _IncludeTimeButton extends StatelessWidget {
+  const _IncludeTimeButton({Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return BlocSelector<DateTypeOptionBloc, DateTypeOptionState, bool>(
+      selector: (state) => state.typeOption.includeTime,
+      builder: (context, includeTime) {
+        return SizedBox(
+          height: GridSize.typeOptionItemHeight,
+          child: Padding(
+            padding: GridSize.typeOptionContentInsets,
+            child: Row(
+              children: [
+                FlowyText.medium(LocaleKeys.grid_field_includeTime.tr(), fontSize: 12),
+                const Spacer(),
+                Switch(
+                  value: includeTime,
+                  onChanged: (newValue) {
+                    context.read<DateTypeOptionBloc>().add(DateTypeOptionEvent.includeTime(newValue));
+                  },
+                ),
+              ],
+            ),
+          ),
+        );
+      },
+    );
+  }
+}
+
 class DateFormatList extends StatelessWidget {
   final DateFormat selectedFormat;
   final Function(DateFormat format) onSelected;

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

@@ -69,13 +69,13 @@ class GridEventUpdateField {
     }
 }
 
-class GridEventCreateField {
-     CreateFieldPayload request;
-     GridEventCreateField(this.request);
+class GridEventInsertField {
+     InsertFieldPayload request;
+     GridEventInsertField(this.request);
 
     Future<Either<Unit, FlowyError>> send() {
     final request = FFIRequest.create()
-          ..event = GridEvent.CreateField.toString()
+          ..event = GridEvent.InsertField.toString()
           ..payload = requestToBytes(this.request);
 
     return Dispatch.asyncRequest(request)
@@ -188,13 +188,13 @@ class GridEventGetSelectOptionContext {
     }
 }
 
-class GridEventApplySelectOptionChangeset {
+class GridEventUpdateSelectOption {
      SelectOptionChangesetPayload request;
-     GridEventApplySelectOptionChangeset(this.request);
+     GridEventUpdateSelectOption(this.request);
 
     Future<Either<Unit, FlowyError>> send() {
     final request = FFIRequest.create()
-          ..event = GridEvent.ApplySelectOptionChangeset.toString()
+          ..event = GridEvent.UpdateSelectOption.toString()
           ..payload = requestToBytes(this.request);
 
     return Dispatch.asyncRequest(request)
@@ -307,13 +307,13 @@ class GridEventUpdateCell {
     }
 }
 
-class GridEventApplySelectOptionCellChangeset {
+class GridEventUpdateCellSelectOption {
      SelectOptionCellChangesetPayload request;
-     GridEventApplySelectOptionCellChangeset(this.request);
+     GridEventUpdateCellSelectOption(this.request);
 
     Future<Either<Unit, FlowyError>> send() {
     final request = FFIRequest.create()
-          ..event = GridEvent.ApplySelectOptionCellChangeset.toString()
+          ..event = GridEvent.UpdateCellSelectOption.toString()
           ..payload = requestToBytes(this.request);
 
     return Dispatch.asyncRequest(request)

+ 2 - 2
frontend/app_flowy/packages/flowy_sdk/lib/ffi.dart

@@ -16,8 +16,8 @@ DynamicLibrary _open() {
     final prefix = "${Directory.current.path}/.sandbox";
     if (Platform.isLinux) return DynamicLibrary.open('${prefix}/libdart_ffi.so');
     if (Platform.isAndroid) return DynamicLibrary.open('${prefix}/libdart_ffi.so');
-    if (Platform.isMacOS) return DynamicLibrary.open('${prefix}/libdart_ffi.dylib');
-    if (Platform.isIOS) return DynamicLibrary.open('${prefix}/libdart_ffi.dylib');
+    if (Platform.isMacOS) return DynamicLibrary.open('${prefix}/libdart_ffi.a');
+    if (Platform.isIOS) return DynamicLibrary.open('${prefix}/libdart_ffi.a');
     if (Platform.isWindows) return DynamicLibrary.open('${prefix}/dart_ffi.dll');
   } else {
     if (Platform.isLinux) return DynamicLibrary.open('libdart_ffi.so');

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

@@ -1478,17 +1478,17 @@ class CreateRowPayload extends $pb.GeneratedMessage {
   void clearStartRowId() => clearField(2);
 }
 
-enum CreateFieldPayload_OneOfStartFieldId {
+enum InsertFieldPayload_OneOfStartFieldId {
   startFieldId, 
   notSet
 }
 
-class CreateFieldPayload extends $pb.GeneratedMessage {
-  static const $core.Map<$core.int, CreateFieldPayload_OneOfStartFieldId> _CreateFieldPayload_OneOfStartFieldIdByTag = {
-    4 : CreateFieldPayload_OneOfStartFieldId.startFieldId,
-    0 : CreateFieldPayload_OneOfStartFieldId.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') ? '' : 'CreateFieldPayload', createEmptyInstance: create)
+  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)
@@ -1497,8 +1497,8 @@ class CreateFieldPayload extends $pb.GeneratedMessage {
     ..hasRequiredFields = false
   ;
 
-  CreateFieldPayload._() : super();
-  factory CreateFieldPayload({
+  InsertFieldPayload._() : super();
+  factory InsertFieldPayload({
     $core.String? gridId,
     Field? field_2,
     $core.List<$core.int>? typeOptionData,
@@ -1519,28 +1519,28 @@ class CreateFieldPayload extends $pb.GeneratedMessage {
     }
     return _result;
   }
-  factory CreateFieldPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
-  factory CreateFieldPayload.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+  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')
-  CreateFieldPayload clone() => CreateFieldPayload()..mergeFromMessage(this);
+  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')
-  CreateFieldPayload copyWith(void Function(CreateFieldPayload) updates) => super.copyWith((message) => updates(message as CreateFieldPayload)) as CreateFieldPayload; // ignore: deprecated_member_use
+  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 CreateFieldPayload create() => CreateFieldPayload._();
-  CreateFieldPayload createEmptyInstance() => create();
-  static $pb.PbList<CreateFieldPayload> createRepeated() => $pb.PbList<CreateFieldPayload>();
+  static InsertFieldPayload create() => InsertFieldPayload._();
+  InsertFieldPayload createEmptyInstance() => create();
+  static $pb.PbList<InsertFieldPayload> createRepeated() => $pb.PbList<InsertFieldPayload>();
   @$core.pragma('dart2js:noInline')
-  static CreateFieldPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<CreateFieldPayload>(create);
-  static CreateFieldPayload? _defaultInstance;
+  static InsertFieldPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<InsertFieldPayload>(create);
+  static InsertFieldPayload? _defaultInstance;
 
-  CreateFieldPayload_OneOfStartFieldId whichOneOfStartFieldId() => _CreateFieldPayload_OneOfStartFieldIdByTag[$_whichOneof(0)]!;
+  InsertFieldPayload_OneOfStartFieldId whichOneOfStartFieldId() => _InsertFieldPayload_OneOfStartFieldIdByTag[$_whichOneof(0)]!;
   void clearOneOfStartFieldId() => clearField($_whichOneof(0));
 
   @$pb.TagNumber(1)

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

@@ -305,9 +305,9 @@ const CreateRowPayload$json = const {
 
 /// Descriptor for `CreateRowPayload`. Decode as a `google.protobuf.DescriptorProto`.
 final $typed_data.Uint8List createRowPayloadDescriptor = $convert.base64Decode('ChBDcmVhdGVSb3dQYXlsb2FkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIiCgxzdGFydF9yb3dfaWQYAiABKAlIAFIKc3RhcnRSb3dJZEIVChNvbmVfb2Zfc3RhcnRfcm93X2lk');
-@$core.Deprecated('Use createFieldPayloadDescriptor instead')
-const CreateFieldPayload$json = const {
-  '1': 'CreateFieldPayload',
+@$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'},
@@ -319,8 +319,8 @@ const CreateFieldPayload$json = const {
   ],
 };
 
-/// Descriptor for `CreateFieldPayload`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List createFieldPayloadDescriptor = $convert.base64Decode('ChJDcmVhdGVGaWVsZFBheWxvYWQSFwoHZ3JpZF9pZBgBIAEoCVIGZ3JpZElkEhwKBWZpZWxkGAIgASgLMgYuRmllbGRSBWZpZWxkEigKEHR5cGVfb3B0aW9uX2RhdGEYAyABKAxSDnR5cGVPcHRpb25EYXRhEiYKDnN0YXJ0X2ZpZWxkX2lkGAQgASgJSABSDHN0YXJ0RmllbGRJZEIXChVvbmVfb2Zfc3RhcnRfZmllbGRfaWQ=');
+/// Descriptor for `InsertFieldPayload`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List insertFieldPayloadDescriptor = $convert.base64Decode('ChJJbnNlcnRGaWVsZFBheWxvYWQSFwoHZ3JpZF9pZBgBIAEoCVIGZ3JpZElkEhwKBWZpZWxkGAIgASgLMgYuRmllbGRSBWZpZWxkEigKEHR5cGVfb3B0aW9uX2RhdGEYAyABKAxSDnR5cGVPcHRpb25EYXRhEiYKDnN0YXJ0X2ZpZWxkX2lkGAQgASgJSABSDHN0YXJ0RmllbGRJZEIXChVvbmVfb2Zfc3RhcnRfZmllbGRfaWQ=');
 @$core.Deprecated('Use queryFieldPayloadDescriptor instead')
 const QueryFieldPayload$json = const {
   '1': 'QueryFieldPayload',

+ 14 - 0
frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/date_type_option.pb.dart

@@ -17,6 +17,7 @@ class DateTypeOption extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'DateTypeOption', createEmptyInstance: create)
     ..e<DateFormat>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dateFormat', $pb.PbFieldType.OE, defaultOrMaker: DateFormat.Local, valueOf: DateFormat.valueOf, enumValues: DateFormat.values)
     ..e<TimeFormat>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'timeFormat', $pb.PbFieldType.OE, defaultOrMaker: TimeFormat.TwelveHour, valueOf: TimeFormat.valueOf, enumValues: TimeFormat.values)
+    ..aOB(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'includeTime')
     ..hasRequiredFields = false
   ;
 
@@ -24,6 +25,7 @@ class DateTypeOption extends $pb.GeneratedMessage {
   factory DateTypeOption({
     DateFormat? dateFormat,
     TimeFormat? timeFormat,
+    $core.bool? includeTime,
   }) {
     final _result = create();
     if (dateFormat != null) {
@@ -32,6 +34,9 @@ class DateTypeOption extends $pb.GeneratedMessage {
     if (timeFormat != null) {
       _result.timeFormat = timeFormat;
     }
+    if (includeTime != null) {
+      _result.includeTime = includeTime;
+    }
     return _result;
   }
   factory DateTypeOption.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
@@ -72,5 +77,14 @@ class DateTypeOption extends $pb.GeneratedMessage {
   $core.bool hasTimeFormat() => $_has(1);
   @$pb.TagNumber(2)
   void clearTimeFormat() => clearField(2);
+
+  @$pb.TagNumber(3)
+  $core.bool get includeTime => $_getBF(2);
+  @$pb.TagNumber(3)
+  set includeTime($core.bool v) { $_setBool(2, v); }
+  @$pb.TagNumber(3)
+  $core.bool hasIncludeTime() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearIncludeTime() => clearField(3);
 }
 

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

@@ -38,8 +38,9 @@ const DateTypeOption$json = const {
   '2': const [
     const {'1': 'date_format', '3': 1, '4': 1, '5': 14, '6': '.DateFormat', '10': 'dateFormat'},
     const {'1': 'time_format', '3': 2, '4': 1, '5': 14, '6': '.TimeFormat', '10': 'timeFormat'},
+    const {'1': 'include_time', '3': 3, '4': 1, '5': 8, '10': 'includeTime'},
   ],
 };
 
 /// Descriptor for `DateTypeOption`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List dateTypeOptionDescriptor = $convert.base64Decode('Cg5EYXRlVHlwZU9wdGlvbhIsCgtkYXRlX2Zvcm1hdBgBIAEoDjILLkRhdGVGb3JtYXRSCmRhdGVGb3JtYXQSLAoLdGltZV9mb3JtYXQYAiABKA4yCy5UaW1lRm9ybWF0Ugp0aW1lRm9ybWF0');
+final $typed_data.Uint8List dateTypeOptionDescriptor = $convert.base64Decode('Cg5EYXRlVHlwZU9wdGlvbhIsCgtkYXRlX2Zvcm1hdBgBIAEoDjILLkRhdGVGb3JtYXRSCmRhdGVGb3JtYXQSLAoLdGltZV9mb3JtYXQYAiABKA4yCy5UaW1lRm9ybWF0Ugp0aW1lRm9ybWF0EiEKDGluY2x1ZGVfdGltZRgDIAEoCFILaW5jbHVkZVRpbWU=');

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

@@ -14,42 +14,42 @@ class GridEvent extends $pb.ProtobufEnum {
   static const GridEvent GetGridBlocks = GridEvent._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetGridBlocks');
   static const GridEvent GetFields = GridEvent._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetFields');
   static const GridEvent UpdateField = GridEvent._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateField');
-  static const GridEvent CreateField = GridEvent._(12, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateField');
+  static const GridEvent InsertField = GridEvent._(12, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'InsertField');
   static const GridEvent DeleteField = GridEvent._(13, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DeleteField');
   static const GridEvent SwitchToField = GridEvent._(14, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'SwitchToField');
   static const GridEvent DuplicateField = GridEvent._(15, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DuplicateField');
   static const GridEvent GetEditFieldContext = GridEvent._(16, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetEditFieldContext');
   static const GridEvent NewSelectOption = GridEvent._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'NewSelectOption');
   static const GridEvent GetSelectOptionContext = GridEvent._(31, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetSelectOptionContext');
-  static const GridEvent ApplySelectOptionChangeset = GridEvent._(32, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ApplySelectOptionChangeset');
+  static const GridEvent UpdateSelectOption = GridEvent._(32, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateSelectOption');
   static const GridEvent CreateRow = GridEvent._(50, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateRow');
   static const GridEvent GetRow = GridEvent._(51, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetRow');
   static const GridEvent DeleteRow = GridEvent._(52, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DeleteRow');
   static const GridEvent DuplicateRow = GridEvent._(53, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DuplicateRow');
   static const GridEvent GetCell = GridEvent._(70, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetCell');
   static const GridEvent UpdateCell = GridEvent._(71, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateCell');
-  static const GridEvent ApplySelectOptionCellChangeset = GridEvent._(72, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ApplySelectOptionCellChangeset');
+  static const GridEvent UpdateCellSelectOption = GridEvent._(72, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateCellSelectOption');
 
   static const $core.List<GridEvent> values = <GridEvent> [
     GetGridData,
     GetGridBlocks,
     GetFields,
     UpdateField,
-    CreateField,
+    InsertField,
     DeleteField,
     SwitchToField,
     DuplicateField,
     GetEditFieldContext,
     NewSelectOption,
     GetSelectOptionContext,
-    ApplySelectOptionChangeset,
+    UpdateSelectOption,
     CreateRow,
     GetRow,
     DeleteRow,
     DuplicateRow,
     GetCell,
     UpdateCell,
-    ApplySelectOptionCellChangeset,
+    UpdateCellSelectOption,
   ];
 
   static final $core.Map<$core.int, GridEvent> _byValue = $pb.ProtobufEnum.initByValue(values);

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

@@ -16,23 +16,23 @@ const GridEvent$json = const {
     const {'1': 'GetGridBlocks', '2': 1},
     const {'1': 'GetFields', '2': 10},
     const {'1': 'UpdateField', '2': 11},
-    const {'1': 'CreateField', '2': 12},
+    const {'1': 'InsertField', '2': 12},
     const {'1': 'DeleteField', '2': 13},
     const {'1': 'SwitchToField', '2': 14},
     const {'1': 'DuplicateField', '2': 15},
     const {'1': 'GetEditFieldContext', '2': 16},
     const {'1': 'NewSelectOption', '2': 30},
     const {'1': 'GetSelectOptionContext', '2': 31},
-    const {'1': 'ApplySelectOptionChangeset', '2': 32},
+    const {'1': 'UpdateSelectOption', '2': 32},
     const {'1': 'CreateRow', '2': 50},
     const {'1': 'GetRow', '2': 51},
     const {'1': 'DeleteRow', '2': 52},
     const {'1': 'DuplicateRow', '2': 53},
     const {'1': 'GetCell', '2': 70},
     const {'1': 'UpdateCell', '2': 71},
-    const {'1': 'ApplySelectOptionCellChangeset', '2': 72},
+    const {'1': 'UpdateCellSelectOption', '2': 72},
   ],
 };
 
 /// Descriptor for `GridEvent`. Decode as a `google.protobuf.EnumDescriptorProto`.
-final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtDcmVhdGVGaWVsZBAMEg8KC0RlbGV0ZUZpZWxkEA0SEQoNU3dpdGNoVG9GaWVsZBAOEhIKDkR1cGxpY2F0ZUZpZWxkEA8SFwoTR2V0RWRpdEZpZWxkQ29udGV4dBAQEhMKD05ld1NlbGVjdE9wdGlvbhAeEhoKFkdldFNlbGVjdE9wdGlvbkNvbnRleHQQHxIeChpBcHBseVNlbGVjdE9wdGlvbkNoYW5nZXNldBAgEg0KCUNyZWF0ZVJvdxAyEgoKBkdldFJvdxAzEg0KCURlbGV0ZVJvdxA0EhAKDER1cGxpY2F0ZVJvdxA1EgsKB0dldENlbGwQRhIOCgpVcGRhdGVDZWxsEEcSIgoeQXBwbHlTZWxlY3RPcHRpb25DZWxsQ2hhbmdlc2V0EEg=');
+final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtJbnNlcnRGaWVsZBAMEg8KC0RlbGV0ZUZpZWxkEA0SEQoNU3dpdGNoVG9GaWVsZBAOEhIKDkR1cGxpY2F0ZUZpZWxkEA8SFwoTR2V0RWRpdEZpZWxkQ29udGV4dBAQEhMKD05ld1NlbGVjdE9wdGlvbhAeEhoKFkdldFNlbGVjdE9wdGlvbkNvbnRleHQQHxIWChJVcGRhdGVTZWxlY3RPcHRpb24QIBINCglDcmVhdGVSb3cQMhIKCgZHZXRSb3cQMxINCglEZWxldGVSb3cQNBIQCgxEdXBsaWNhdGVSb3cQNRILCgdHZXRDZWxsEEYSDgoKVXBkYXRlQ2VsbBBHEhoKFlVwZGF0ZUNlbGxTZWxlY3RPcHRpb24QSA==');

+ 2 - 2
frontend/app_flowy/packages/flowy_sdk/macos/flowy_sdk.podspec

@@ -20,6 +20,6 @@ A new flutter plugin project.
   s.platform = :osx, '10.11'
   s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' }
   s.swift_version = '5.0'
-  # s.static_framework = true
-  s.vendored_libraries = "libdart_ffi.dylib"
+  s.static_framework = true
+  s.vendored_libraries = "libdart_ffi.a"
 end

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

@@ -62,13 +62,13 @@ pub(crate) async fn update_field_handler(
 }
 
 #[tracing::instrument(level = "debug", skip(data, manager), err)]
-pub(crate) async fn create_field_handler(
-    data: Data<CreateFieldPayload>,
+pub(crate) async fn insert_field_handler(
+    data: Data<InsertFieldPayload>,
     manager: AppData<Arc<GridManager>>,
 ) -> Result<(), FlowyError> {
-    let params: CreateFieldParams = data.into_inner().try_into()?;
+    let params: InsertFieldParams = data.into_inner().try_into()?;
     let editor = manager.get_grid_editor(&params.grid_id)?;
-    let _ = editor.create_field(params).await?;
+    let _ = editor.insert_field(params).await?;
     Ok(())
 }
 
@@ -243,7 +243,7 @@ pub(crate) async fn new_select_option_handler(data: Data<SelectOptionName>) -> D
 }
 
 #[tracing::instrument(level = "debug", skip_all, err)]
-pub(crate) async fn select_option_changeset_handler(
+pub(crate) async fn update_select_option_handler(
     data: Data<SelectOptionChangesetPayload>,
     manager: AppData<Arc<GridManager>>,
 ) -> Result<(), FlowyError> {
@@ -281,6 +281,18 @@ pub(crate) async fn select_option_changeset_handler(
     }
     Ok(())
 }
+//
+// #[tracing::instrument(level = "debug", skip_all, err)]
+// pub(crate) async fn update_date_option_handler(
+//     data: Data<SelectOptionCellChangesetPayload>,
+//     manager: AppData<Arc<GridManager>>,
+// ) -> Result<(), FlowyError> {
+//     let params: SelectOptionCellChangesetParams = data.into_inner().try_into()?;
+//     let editor = manager.get_grid_editor(&params.grid_id)?;
+//     let changeset: CellChangeset = params.into();
+//     let _ = editor.update_cell(changeset).await?;
+//     Ok(())
+// }
 
 #[tracing::instrument(level = "debug", skip(data, manager), err)]
 pub(crate) async fn get_select_option_handler(
@@ -304,7 +316,7 @@ pub(crate) async fn get_select_option_handler(
 }
 
 #[tracing::instrument(level = "debug", skip_all, err)]
-pub(crate) async fn select_option_cell_changeset_handler(
+pub(crate) async fn update_cell_select_option_handler(
     data: Data<SelectOptionCellChangesetPayload>,
     manager: AppData<Arc<GridManager>>,
 ) -> Result<(), FlowyError> {

+ 8 - 10
frontend/rust-lib/flowy-grid/src/event_map.rs

@@ -13,7 +13,7 @@ pub fn create(grid_manager: Arc<GridManager>) -> Module {
         // Field
         .event(GridEvent::GetFields, get_fields_handler)
         .event(GridEvent::UpdateField, update_field_handler)
-        .event(GridEvent::CreateField, create_field_handler)
+        .event(GridEvent::InsertField, insert_field_handler)
         .event(GridEvent::DeleteField, delete_field_handler)
         .event(GridEvent::SwitchToField, switch_to_field_handler)
         .event(GridEvent::DuplicateField, duplicate_field_handler)
@@ -27,12 +27,10 @@ pub fn create(grid_manager: Arc<GridManager>) -> Module {
         .event(GridEvent::UpdateCell, update_cell_handler)
         // SelectOption
         .event(GridEvent::NewSelectOption, new_select_option_handler)
-        .event(GridEvent::ApplySelectOptionChangeset, select_option_changeset_handler)
+        .event(GridEvent::UpdateSelectOption, update_select_option_handler)
         .event(GridEvent::GetSelectOptionContext, get_select_option_handler)
-        .event(
-            GridEvent::ApplySelectOptionCellChangeset,
-            select_option_cell_changeset_handler,
-        )
+        .event(GridEvent::UpdateCellSelectOption, update_cell_select_option_handler)
+        //
         .event(GridEvent::GetEditFieldContext, get_field_context_handler);
 
     module
@@ -53,8 +51,8 @@ pub enum GridEvent {
     #[event(input = "FieldChangesetPayload")]
     UpdateField = 11,
 
-    #[event(input = "CreateFieldPayload")]
-    CreateField = 12,
+    #[event(input = "InsertFieldPayload")]
+    InsertField = 12,
 
     #[event(input = "FieldIdentifierPayload")]
     DeleteField = 13,
@@ -75,7 +73,7 @@ pub enum GridEvent {
     GetSelectOptionContext = 31,
 
     #[event(input = "SelectOptionChangesetPayload")]
-    ApplySelectOptionChangeset = 32,
+    UpdateSelectOption = 32,
 
     #[event(input = "CreateRowPayload", output = "Row")]
     CreateRow = 50,
@@ -96,5 +94,5 @@ pub enum GridEvent {
     UpdateCell = 71,
 
     #[event(input = "SelectOptionCellChangesetPayload")]
-    ApplySelectOptionCellChangeset = 72,
+    UpdateCellSelectOption = 72,
 }

+ 42 - 6
frontend/rust-lib/flowy-grid/src/protobuf/model/date_type_option.rs

@@ -28,6 +28,7 @@ pub struct DateTypeOption {
     // message fields
     pub date_format: DateFormat,
     pub time_format: TimeFormat,
+    pub include_time: bool,
     // special fields
     pub unknown_fields: ::protobuf::UnknownFields,
     pub cached_size: ::protobuf::CachedSize,
@@ -73,6 +74,21 @@ impl DateTypeOption {
     pub fn set_time_format(&mut self, v: TimeFormat) {
         self.time_format = v;
     }
+
+    // bool include_time = 3;
+
+
+    pub fn get_include_time(&self) -> bool {
+        self.include_time
+    }
+    pub fn clear_include_time(&mut self) {
+        self.include_time = false;
+    }
+
+    // Param is passed by value, moved
+    pub fn set_include_time(&mut self, v: bool) {
+        self.include_time = v;
+    }
 }
 
 impl ::protobuf::Message for DateTypeOption {
@@ -90,6 +106,13 @@ impl ::protobuf::Message for DateTypeOption {
                 2 => {
                     ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.time_format, 2, &mut self.unknown_fields)?
                 },
+                3 => {
+                    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.include_time = tmp;
+                },
                 _ => {
                     ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
                 },
@@ -108,6 +131,9 @@ impl ::protobuf::Message for DateTypeOption {
         if self.time_format != TimeFormat::TwelveHour {
             my_size += ::protobuf::rt::enum_size(2, self.time_format);
         }
+        if self.include_time != false {
+            my_size += 2;
+        }
         my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
         self.cached_size.set(my_size);
         my_size
@@ -120,6 +146,9 @@ impl ::protobuf::Message for DateTypeOption {
         if self.time_format != TimeFormat::TwelveHour {
             os.write_enum(2, ::protobuf::ProtobufEnum::value(&self.time_format))?;
         }
+        if self.include_time != false {
+            os.write_bool(3, self.include_time)?;
+        }
         os.write_unknown_fields(self.get_unknown_fields())?;
         ::std::result::Result::Ok(())
     }
@@ -168,6 +197,11 @@ impl ::protobuf::Message for DateTypeOption {
                 |m: &DateTypeOption| { &m.time_format },
                 |m: &mut DateTypeOption| { &mut m.time_format },
             ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>(
+                "include_time",
+                |m: &DateTypeOption| { &m.include_time },
+                |m: &mut DateTypeOption| { &mut m.include_time },
+            ));
             ::protobuf::reflect::MessageDescriptor::new_pb_name::<DateTypeOption>(
                 "DateTypeOption",
                 fields,
@@ -186,6 +220,7 @@ impl ::protobuf::Clear for DateTypeOption {
     fn clear(&mut self) {
         self.date_format = DateFormat::Local;
         self.time_format = TimeFormat::TwelveHour;
+        self.include_time = false;
         self.unknown_fields.clear();
     }
 }
@@ -309,12 +344,13 @@ impl ::protobuf::reflect::ProtobufValue for TimeFormat {
 }
 
 static file_descriptor_proto_data: &'static [u8] = b"\
-    \n\x16date_type_option.proto\"l\n\x0eDateTypeOption\x12,\n\x0bdate_forma\
-    t\x18\x01\x20\x01(\x0e2\x0b.DateFormatR\ndateFormat\x12,\n\x0btime_forma\
-    t\x18\x02\x20\x01(\x0e2\x0b.TimeFormatR\ntimeFormat*6\n\nDateFormat\x12\
-    \t\n\x05Local\x10\0\x12\x06\n\x02US\x10\x01\x12\x07\n\x03ISO\x10\x02\x12\
-    \x0c\n\x08Friendly\x10\x03*0\n\nTimeFormat\x12\x0e\n\nTwelveHour\x10\0\
-    \x12\x12\n\x0eTwentyFourHour\x10\x01b\x06proto3\
+    \n\x16date_type_option.proto\"\x8f\x01\n\x0eDateTypeOption\x12,\n\x0bdat\
+    e_format\x18\x01\x20\x01(\x0e2\x0b.DateFormatR\ndateFormat\x12,\n\x0btim\
+    e_format\x18\x02\x20\x01(\x0e2\x0b.TimeFormatR\ntimeFormat\x12!\n\x0cinc\
+    lude_time\x18\x03\x20\x01(\x08R\x0bincludeTime*6\n\nDateFormat\x12\t\n\
+    \x05Local\x10\0\x12\x06\n\x02US\x10\x01\x12\x07\n\x03ISO\x10\x02\x12\x0c\
+    \n\x08Friendly\x10\x03*0\n\nTimeFormat\x12\x0e\n\nTwelveHour\x10\0\x12\
+    \x12\n\x0eTwentyFourHour\x10\x01b\x06proto3\
 ";
 
 static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

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

@@ -29,21 +29,21 @@ pub enum GridEvent {
     GetGridBlocks = 1,
     GetFields = 10,
     UpdateField = 11,
-    CreateField = 12,
+    InsertField = 12,
     DeleteField = 13,
     SwitchToField = 14,
     DuplicateField = 15,
     GetEditFieldContext = 16,
     NewSelectOption = 30,
     GetSelectOptionContext = 31,
-    ApplySelectOptionChangeset = 32,
+    UpdateSelectOption = 32,
     CreateRow = 50,
     GetRow = 51,
     DeleteRow = 52,
     DuplicateRow = 53,
     GetCell = 70,
     UpdateCell = 71,
-    ApplySelectOptionCellChangeset = 72,
+    UpdateCellSelectOption = 72,
 }
 
 impl ::protobuf::ProtobufEnum for GridEvent {
@@ -57,21 +57,21 @@ impl ::protobuf::ProtobufEnum for GridEvent {
             1 => ::std::option::Option::Some(GridEvent::GetGridBlocks),
             10 => ::std::option::Option::Some(GridEvent::GetFields),
             11 => ::std::option::Option::Some(GridEvent::UpdateField),
-            12 => ::std::option::Option::Some(GridEvent::CreateField),
+            12 => ::std::option::Option::Some(GridEvent::InsertField),
             13 => ::std::option::Option::Some(GridEvent::DeleteField),
             14 => ::std::option::Option::Some(GridEvent::SwitchToField),
             15 => ::std::option::Option::Some(GridEvent::DuplicateField),
             16 => ::std::option::Option::Some(GridEvent::GetEditFieldContext),
             30 => ::std::option::Option::Some(GridEvent::NewSelectOption),
             31 => ::std::option::Option::Some(GridEvent::GetSelectOptionContext),
-            32 => ::std::option::Option::Some(GridEvent::ApplySelectOptionChangeset),
+            32 => ::std::option::Option::Some(GridEvent::UpdateSelectOption),
             50 => ::std::option::Option::Some(GridEvent::CreateRow),
             51 => ::std::option::Option::Some(GridEvent::GetRow),
             52 => ::std::option::Option::Some(GridEvent::DeleteRow),
             53 => ::std::option::Option::Some(GridEvent::DuplicateRow),
             70 => ::std::option::Option::Some(GridEvent::GetCell),
             71 => ::std::option::Option::Some(GridEvent::UpdateCell),
-            72 => ::std::option::Option::Some(GridEvent::ApplySelectOptionCellChangeset),
+            72 => ::std::option::Option::Some(GridEvent::UpdateCellSelectOption),
             _ => ::std::option::Option::None
         }
     }
@@ -82,21 +82,21 @@ impl ::protobuf::ProtobufEnum for GridEvent {
             GridEvent::GetGridBlocks,
             GridEvent::GetFields,
             GridEvent::UpdateField,
-            GridEvent::CreateField,
+            GridEvent::InsertField,
             GridEvent::DeleteField,
             GridEvent::SwitchToField,
             GridEvent::DuplicateField,
             GridEvent::GetEditFieldContext,
             GridEvent::NewSelectOption,
             GridEvent::GetSelectOptionContext,
-            GridEvent::ApplySelectOptionChangeset,
+            GridEvent::UpdateSelectOption,
             GridEvent::CreateRow,
             GridEvent::GetRow,
             GridEvent::DeleteRow,
             GridEvent::DuplicateRow,
             GridEvent::GetCell,
             GridEvent::UpdateCell,
-            GridEvent::ApplySelectOptionCellChangeset,
+            GridEvent::UpdateCellSelectOption,
         ];
         values
     }
@@ -125,16 +125,16 @@ impl ::protobuf::reflect::ProtobufValue for GridEvent {
 }
 
 static file_descriptor_proto_data: &'static [u8] = b"\
-    \n\x0fevent_map.proto*\xff\x02\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\
+    \n\x0fevent_map.proto*\xef\x02\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\
     \0\x12\x11\n\rGetGridBlocks\x10\x01\x12\r\n\tGetFields\x10\n\x12\x0f\n\
-    \x0bUpdateField\x10\x0b\x12\x0f\n\x0bCreateField\x10\x0c\x12\x0f\n\x0bDe\
+    \x0bUpdateField\x10\x0b\x12\x0f\n\x0bInsertField\x10\x0c\x12\x0f\n\x0bDe\
     leteField\x10\r\x12\x11\n\rSwitchToField\x10\x0e\x12\x12\n\x0eDuplicateF\
     ield\x10\x0f\x12\x17\n\x13GetEditFieldContext\x10\x10\x12\x13\n\x0fNewSe\
-    lectOption\x10\x1e\x12\x1a\n\x16GetSelectOptionContext\x10\x1f\x12\x1e\n\
-    \x1aApplySelectOptionChangeset\x10\x20\x12\r\n\tCreateRow\x102\x12\n\n\
-    \x06GetRow\x103\x12\r\n\tDeleteRow\x104\x12\x10\n\x0cDuplicateRow\x105\
-    \x12\x0b\n\x07GetCell\x10F\x12\x0e\n\nUpdateCell\x10G\x12\"\n\x1eApplySe\
-    lectOptionCellChangeset\x10Hb\x06proto3\
+    lectOption\x10\x1e\x12\x1a\n\x16GetSelectOptionContext\x10\x1f\x12\x16\n\
+    \x12UpdateSelectOption\x10\x20\x12\r\n\tCreateRow\x102\x12\n\n\x06GetRow\
+    \x103\x12\r\n\tDeleteRow\x104\x12\x10\n\x0cDuplicateRow\x105\x12\x0b\n\
+    \x07GetCell\x10F\x12\x0e\n\nUpdateCell\x10G\x12\x1a\n\x16UpdateCellSelec\
+    tOption\x10Hb\x06proto3\
 ";
 
 static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

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

@@ -3,6 +3,7 @@ syntax = "proto3";
 message DateTypeOption {
     DateFormat date_format = 1;
     TimeFormat time_format = 2;
+    bool include_time = 3;
 }
 enum DateFormat {
     Local = 0;

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

@@ -5,19 +5,19 @@ enum GridEvent {
     GetGridBlocks = 1;
     GetFields = 10;
     UpdateField = 11;
-    CreateField = 12;
+    InsertField = 12;
     DeleteField = 13;
     SwitchToField = 14;
     DuplicateField = 15;
     GetEditFieldContext = 16;
     NewSelectOption = 30;
     GetSelectOptionContext = 31;
-    ApplySelectOptionChangeset = 32;
+    UpdateSelectOption = 32;
     CreateRow = 50;
     GetRow = 51;
     DeleteRow = 52;
     DuplicateRow = 53;
     GetCell = 70;
     UpdateCell = 71;
-    ApplySelectOptionCellChangeset = 72;
+    UpdateCellSelectOption = 72;
 }

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

@@ -23,6 +23,9 @@ pub struct DateTypeOption {
 
     #[pb(index = 2)]
     pub time_format: TimeFormat,
+
+    #[pb(index = 3)]
+    pub include_time: bool,
 }
 impl_type_option!(DateTypeOption, FieldType::DateTime);
 
@@ -41,7 +44,11 @@ impl DateTypeOption {
     }
 
     fn fmt_str(&self) -> String {
-        format!("{}", self.date_format.format_str())
+        if self.include_time {
+            format!("{} {}", self.date_format.format_str(), self.time_format.format_str())
+        } else {
+            format!("{}", self.date_format.format_str())
+        }
     }
 }
 
@@ -205,79 +212,79 @@ mod tests {
         );
     }
 
-    // #[test]
-    // fn date_description_date_format_test() {
-    //     let mut type_option = DateTypeOption::default();
-    //     let field_meta = FieldBuilder::from_field_type(&FieldType::Number).build();
-    //     for date_format in DateFormat::iter() {
-    //         type_option.date_format = date_format;
-    //         match date_format {
-    //             DateFormat::Friendly => {
-    //                 assert_eq!(
-    //                     "Mar 14,2022 17:56".to_owned(),
-    //                     type_option.decode_cell_data(data("1647251762"), &field_meta)
-    //                 );
-    //                 assert_eq!(
-    //                     "Mar 14,2022 17:56".to_owned(),
-    //                     type_option.decode_cell_data(data("Mar 14,2022 17:56"), &field_meta)
-    //                 );
-    //             }
-    //             DateFormat::US => {
-    //                 assert_eq!(
-    //                     "2022/03/14 17:56".to_owned(),
-    //                     type_option.decode_cell_data(data("1647251762"), &field_meta)
-    //                 );
-    //                 assert_eq!(
-    //                     "2022/03/14 17:56".to_owned(),
-    //                     type_option.decode_cell_data(data("2022/03/14 17:56"), &field_meta)
-    //                 );
-    //             }
-    //             DateFormat::ISO => {
-    //                 assert_eq!(
-    //                     "2022-03-14 17:56".to_owned(),
-    //                     type_option.decode_cell_data(data("1647251762"), &field_meta)
-    //                 );
-    //             }
-    //             DateFormat::Local => {
-    //                 assert_eq!(
-    //                     "2022/03/14 17:56".to_owned(),
-    //                     type_option.decode_cell_data(data("1647251762"), &field_meta)
-    //                 );
-    //             }
-    //         }
-    //     }
-    // }
-
-    // #[test]
-    // fn date_description_time_format_test() {
-    //     let mut type_option = DateTypeOption::default();
-    //     let field_meta = FieldBuilder::from_field_type(&FieldType::Number).build();
-    //     for time_format in TimeFormat::iter() {
-    //         type_option.time_format = time_format;
-    //         match time_format {
-    //             TimeFormat::TwentyFourHour => {
-    //                 assert_eq!(
-    //                     "Mar 14,2022 17:56".to_owned(),
-    //                     type_option.today_from_timestamp(1647251762)
-    //                 );
-    //                 assert_eq!(
-    //                     "Mar 14,2022 17:56".to_owned(),
-    //                     type_option.decode_cell_data(data("1647251762"), &field_meta)
-    //                 );
-    //             }
-    //             TimeFormat::TwelveHour => {
-    //                 assert_eq!(
-    //                     "Mar 14,2022 05:56:02 PM".to_owned(),
-    //                     type_option.today_from_timestamp(1647251762)
-    //                 );
-    //                 assert_eq!(
-    //                     "Mar 14,2022 05:56:02 PM".to_owned(),
-    //                     type_option.decode_cell_data(data("1647251762"), &field_meta)
-    //                 );
-    //             }
-    //         }
-    //     }
-    // }
+    #[test]
+    fn date_description_date_format_test() {
+        let mut type_option = DateTypeOption::default();
+        let field_meta = FieldBuilder::from_field_type(&FieldType::Number).build();
+        for date_format in DateFormat::iter() {
+            type_option.date_format = date_format;
+            match date_format {
+                DateFormat::Friendly => {
+                    assert_eq!(
+                        "Mar 14,2022 17:56".to_owned(),
+                        type_option.decode_cell_data(data("1647251762"), &field_meta)
+                    );
+                    assert_eq!(
+                        "Mar 14,2022 17:56".to_owned(),
+                        type_option.decode_cell_data(data("Mar 14,2022 17:56"), &field_meta)
+                    );
+                }
+                DateFormat::US => {
+                    assert_eq!(
+                        "2022/03/14 17:56".to_owned(),
+                        type_option.decode_cell_data(data("1647251762"), &field_meta)
+                    );
+                    assert_eq!(
+                        "2022/03/14 17:56".to_owned(),
+                        type_option.decode_cell_data(data("2022/03/14 17:56"), &field_meta)
+                    );
+                }
+                DateFormat::ISO => {
+                    assert_eq!(
+                        "2022-03-14 17:56".to_owned(),
+                        type_option.decode_cell_data(data("1647251762"), &field_meta)
+                    );
+                }
+                DateFormat::Local => {
+                    assert_eq!(
+                        "2022/03/14 17:56".to_owned(),
+                        type_option.decode_cell_data(data("1647251762"), &field_meta)
+                    );
+                }
+            }
+        }
+    }
+
+    #[test]
+    fn date_description_time_format_test() {
+        let mut type_option = DateTypeOption::default();
+        let field_meta = FieldBuilder::from_field_type(&FieldType::Number).build();
+        for time_format in TimeFormat::iter() {
+            type_option.time_format = time_format;
+            match time_format {
+                TimeFormat::TwentyFourHour => {
+                    assert_eq!(
+                        "Mar 14,2022 17:56".to_owned(),
+                        type_option.today_from_timestamp(1647251762)
+                    );
+                    assert_eq!(
+                        "Mar 14,2022 17:56".to_owned(),
+                        type_option.decode_cell_data(data("1647251762"), &field_meta)
+                    );
+                }
+                TimeFormat::TwelveHour => {
+                    assert_eq!(
+                        "Mar 14,2022 05:56:02 PM".to_owned(),
+                        type_option.today_from_timestamp(1647251762)
+                    );
+                    assert_eq!(
+                        "Mar 14,2022 05:56:02 PM".to_owned(),
+                        type_option.decode_cell_data(data("1647251762"), &field_meta)
+                    );
+                }
+            }
+        }
+    }
 
     #[test]
     #[should_panic]
@@ -286,7 +293,7 @@ mod tests {
         type_option.apply_changeset("he", None).unwrap();
     }
 
-    // fn data(s: &str) -> String {
-    //     TypeOptionCellData::new(s, FieldType::DateTime).json()
-    // }
+    fn data(s: &str) -> String {
+        TypeOptionCellData::new(s, FieldType::DateTime).json()
+    }
 }

+ 5 - 3
frontend/rust-lib/flowy-grid/src/services/grid_editor.rs

@@ -51,8 +51,8 @@ impl ClientGridEditor {
         }))
     }
 
-    pub async fn create_field(&self, params: CreateFieldParams) -> FlowyResult<()> {
-        let CreateFieldParams {
+    pub async fn insert_field(&self, params: InsertFieldParams) -> FlowyResult<()> {
+        let InsertFieldParams {
             field,
             type_option_data,
             start_field_id,
@@ -483,6 +483,8 @@ impl JsonDeserializer for TypeOptionJsonDeserializer {
     fn deserialize(&self, type_option_data: Vec<u8>) -> CollaborateResult<String> {
         // The type_option_data sent from Dart is serialized by protobuf.
         let builder = type_option_builder_from_bytes(type_option_data, &self.0);
-        Ok(builder.entry().json_str())
+        let json = builder.entry().json_str();
+        tracing::trace!("Deserialize type option data to: {}", json);
+        Ok(json)
     }
 }

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

@@ -288,7 +288,7 @@ async fn grid_row_add_date_cell_test() {
     let cell_data = context.cell_by_field_id.get(&date_field.id).unwrap().clone();
     assert_eq!(
         decode_cell_data(cell_data.data.clone(), &date_field, &date_field.field_type).unwrap(),
-        "2022/03/16 08:31",
+        "2022/03/16",
     );
     let scripts = vec![CreateRow { context }];
     test.run_scripts(scripts).await;

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

@@ -3,8 +3,8 @@ use flowy_grid::services::field::*;
 use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder};
 use flowy_grid::services::row::CreateRowMetaPayload;
 use flowy_grid_data_model::entities::{
-    BuildGridContext, CellChangeset, CreateFieldParams, Field, FieldChangesetParams, FieldMeta, FieldOrder, FieldType,
-    GridBlockMeta, GridBlockMetaChangeset, RowMeta, RowMetaChangeset, RowOrder, TypeOptionDataEntry,
+    BuildGridContext, CellChangeset, Field, FieldChangesetParams, FieldMeta, FieldOrder, FieldType, GridBlockMeta,
+    GridBlockMetaChangeset, InsertFieldParams, RowMeta, RowMetaChangeset, RowOrder, TypeOptionDataEntry,
 };
 use flowy_revision::REVISION_WRITE_INTERVAL_IN_MILLIS;
 use flowy_sync::client_grid::GridBuilder;
@@ -18,7 +18,7 @@ use tokio::time::sleep;
 
 pub enum EditorScript {
     CreateField {
-        params: CreateFieldParams,
+        params: InsertFieldParams,
     },
     UpdateField {
         changeset: FieldChangesetParams,
@@ -124,7 +124,7 @@ impl GridEditorTest {
                     self.field_count += 1;
                 }
 
-                self.editor.create_field(params).await.unwrap();
+                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());
             }
@@ -249,7 +249,7 @@ async fn get_row_metas(editor: &Arc<ClientGridEditor>) -> Vec<Arc<RowMeta>> {
         .row_metas
 }
 
-pub fn create_text_field(grid_id: &str) -> (CreateFieldParams, FieldMeta) {
+pub fn create_text_field(grid_id: &str) -> (InsertFieldParams, FieldMeta) {
     let field_meta = FieldBuilder::new(RichTextTypeOptionBuilder::default())
         .name("Name")
         .visibility(true)
@@ -273,7 +273,7 @@ pub fn create_text_field(grid_id: &str) -> (CreateFieldParams, FieldMeta) {
         width: field_meta.width,
     };
 
-    let params = CreateFieldParams {
+    let params = InsertFieldParams {
         grid_id: grid_id.to_owned(),
         field,
         type_option_data,
@@ -282,7 +282,7 @@ pub fn create_text_field(grid_id: &str) -> (CreateFieldParams, FieldMeta) {
     (params, cloned_field_meta)
 }
 
-pub fn create_single_select_field(grid_id: &str) -> (CreateFieldParams, FieldMeta) {
+pub fn create_single_select_field(grid_id: &str) -> (InsertFieldParams, FieldMeta) {
     let single_select = SingleSelectTypeOptionBuilder::default()
         .option(SelectOption::new("Done"))
         .option(SelectOption::new("Progress"));
@@ -305,7 +305,7 @@ pub fn create_single_select_field(grid_id: &str) -> (CreateFieldParams, FieldMet
         width: field_meta.width,
     };
 
-    let params = CreateFieldParams {
+    let params = InsertFieldParams {
         grid_id: grid_id.to_owned(),
         field,
         type_option_data,

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

@@ -483,7 +483,7 @@ impl TryInto<CreateRowParams> for CreateRowPayload {
 }
 
 #[derive(ProtoBuf, Default)]
-pub struct CreateFieldPayload {
+pub struct InsertFieldPayload {
     #[pb(index = 1)]
     pub grid_id: String,
 
@@ -498,17 +498,17 @@ pub struct CreateFieldPayload {
 }
 
 #[derive(Clone)]
-pub struct CreateFieldParams {
+pub struct InsertFieldParams {
     pub grid_id: String,
     pub field: Field,
     pub type_option_data: Vec<u8>,
     pub start_field_id: Option<String>,
 }
 
-impl TryInto<CreateFieldParams> for CreateFieldPayload {
+impl TryInto<InsertFieldParams> for InsertFieldPayload {
     type Error = ErrorCode;
 
-    fn try_into(self) -> Result<CreateFieldParams, Self::Error> {
+    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)?;
 
@@ -517,7 +517,7 @@ impl TryInto<CreateFieldParams> for CreateFieldPayload {
             Some(id) => Some(NotEmptyStr::parse(id).map_err(|_| ErrorCode::FieldIdIsEmpty)?.0),
         };
 
-        Ok(CreateFieldParams {
+        Ok(InsertFieldParams {
             grid_id: grid_id.0,
             field: self.field,
             type_option_data: self.type_option_data,

+ 38 - 38
shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs

@@ -5076,31 +5076,31 @@ impl ::protobuf::reflect::ProtobufValue for CreateRowPayload {
 }
 
 #[derive(PartialEq,Clone,Default)]
-pub struct CreateFieldPayload {
+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<CreateFieldPayload_oneof_one_of_start_field_id>,
+    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 CreateFieldPayload {
-    fn default() -> &'a CreateFieldPayload {
-        <CreateFieldPayload as ::protobuf::Message>::default_instance()
+impl<'a> ::std::default::Default for &'a InsertFieldPayload {
+    fn default() -> &'a InsertFieldPayload {
+        <InsertFieldPayload as ::protobuf::Message>::default_instance()
     }
 }
 
 #[derive(Clone,PartialEq,Debug)]
-pub enum CreateFieldPayload_oneof_one_of_start_field_id {
+pub enum InsertFieldPayload_oneof_one_of_start_field_id {
     start_field_id(::std::string::String),
 }
 
-impl CreateFieldPayload {
-    pub fn new() -> CreateFieldPayload {
+impl InsertFieldPayload {
+    pub fn new() -> InsertFieldPayload {
         ::std::default::Default::default()
     }
 
@@ -5194,7 +5194,7 @@ impl CreateFieldPayload {
 
     pub fn get_start_field_id(&self) -> &str {
         match self.one_of_start_field_id {
-            ::std::option::Option::Some(CreateFieldPayload_oneof_one_of_start_field_id::start_field_id(ref v)) => v,
+            ::std::option::Option::Some(InsertFieldPayload_oneof_one_of_start_field_id::start_field_id(ref v)) => v,
             _ => "",
         }
     }
@@ -5204,24 +5204,24 @@ impl CreateFieldPayload {
 
     pub fn has_start_field_id(&self) -> bool {
         match self.one_of_start_field_id {
-            ::std::option::Option::Some(CreateFieldPayload_oneof_one_of_start_field_id::start_field_id(..)) => true,
+            ::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(CreateFieldPayload_oneof_one_of_start_field_id::start_field_id(v))
+        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(CreateFieldPayload_oneof_one_of_start_field_id::start_field_id(_)) = self.one_of_start_field_id {
+        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(CreateFieldPayload_oneof_one_of_start_field_id::start_field_id(::std::string::String::new()));
+            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(CreateFieldPayload_oneof_one_of_start_field_id::start_field_id(ref mut v)) => v,
+            ::std::option::Option::Some(InsertFieldPayload_oneof_one_of_start_field_id::start_field_id(ref mut v)) => v,
             _ => panic!(),
         }
     }
@@ -5230,7 +5230,7 @@ impl CreateFieldPayload {
     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(CreateFieldPayload_oneof_one_of_start_field_id::start_field_id(v)) => v,
+                ::std::option::Option::Some(InsertFieldPayload_oneof_one_of_start_field_id::start_field_id(v)) => v,
                 _ => panic!(),
             }
         } else {
@@ -5239,7 +5239,7 @@ impl CreateFieldPayload {
     }
 }
 
-impl ::protobuf::Message for CreateFieldPayload {
+impl ::protobuf::Message for InsertFieldPayload {
     fn is_initialized(&self) -> bool {
         for v in &self.field {
             if !v.is_initialized() {
@@ -5266,7 +5266,7 @@ impl ::protobuf::Message for CreateFieldPayload {
                     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(CreateFieldPayload_oneof_one_of_start_field_id::start_field_id(is.read_string()?));
+                    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())?;
@@ -5292,7 +5292,7 @@ impl ::protobuf::Message for CreateFieldPayload {
         }
         if let ::std::option::Option::Some(ref v) = self.one_of_start_field_id {
             match v {
-                &CreateFieldPayload_oneof_one_of_start_field_id::start_field_id(ref v) => {
+                &InsertFieldPayload_oneof_one_of_start_field_id::start_field_id(ref v) => {
                     my_size += ::protobuf::rt::string_size(4, &v);
                 },
             };
@@ -5316,7 +5316,7 @@ impl ::protobuf::Message for CreateFieldPayload {
         }
         if let ::std::option::Option::Some(ref v) = self.one_of_start_field_id {
             match v {
-                &CreateFieldPayload_oneof_one_of_start_field_id::start_field_id(ref v) => {
+                &InsertFieldPayload_oneof_one_of_start_field_id::start_field_id(ref v) => {
                     os.write_string(4, v)?;
                 },
             };
@@ -5351,8 +5351,8 @@ impl ::protobuf::Message for CreateFieldPayload {
         Self::descriptor_static()
     }
 
-    fn new() -> CreateFieldPayload {
-        CreateFieldPayload::new()
+    fn new() -> InsertFieldPayload {
+        InsertFieldPayload::new()
     }
 
     fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
@@ -5361,39 +5361,39 @@ impl ::protobuf::Message for CreateFieldPayload {
             let mut fields = ::std::vec::Vec::new();
             fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
                 "grid_id",
-                |m: &CreateFieldPayload| { &m.grid_id },
-                |m: &mut CreateFieldPayload| { &mut m.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: &CreateFieldPayload| { &m.field },
-                |m: &mut CreateFieldPayload| { &mut m.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: &CreateFieldPayload| { &m.type_option_data },
-                |m: &mut CreateFieldPayload| { &mut m.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",
-                CreateFieldPayload::has_start_field_id,
-                CreateFieldPayload::get_start_field_id,
+                InsertFieldPayload::has_start_field_id,
+                InsertFieldPayload::get_start_field_id,
             ));
-            ::protobuf::reflect::MessageDescriptor::new_pb_name::<CreateFieldPayload>(
-                "CreateFieldPayload",
+            ::protobuf::reflect::MessageDescriptor::new_pb_name::<InsertFieldPayload>(
+                "InsertFieldPayload",
                 fields,
                 file_descriptor_proto()
             )
         })
     }
 
-    fn default_instance() -> &'static CreateFieldPayload {
-        static instance: ::protobuf::rt::LazyV2<CreateFieldPayload> = ::protobuf::rt::LazyV2::INIT;
-        instance.get(CreateFieldPayload::new)
+    fn default_instance() -> &'static InsertFieldPayload {
+        static instance: ::protobuf::rt::LazyV2<InsertFieldPayload> = ::protobuf::rt::LazyV2::INIT;
+        instance.get(InsertFieldPayload::new)
     }
 }
 
-impl ::protobuf::Clear for CreateFieldPayload {
+impl ::protobuf::Clear for InsertFieldPayload {
     fn clear(&mut self) {
         self.grid_id.clear();
         self.field.clear();
@@ -5403,13 +5403,13 @@ impl ::protobuf::Clear for CreateFieldPayload {
     }
 }
 
-impl ::std::fmt::Debug for CreateFieldPayload {
+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 CreateFieldPayload {
+impl ::protobuf::reflect::ProtobufValue for InsertFieldPayload {
     fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
         ::protobuf::reflect::ReflectValueRef::Message(self)
     }
@@ -6952,7 +6952,7 @@ static file_descriptor_proto_data: &'static [u8] = b"\
     \x01\x20\x01(\tR\x05value\"#\n\x0bGridBlockId\x12\x14\n\x05value\x18\x01\
     \x20\x01(\tR\x05value\"f\n\x10CreateRowPayload\x12\x17\n\x07grid_id\x18\
     \x01\x20\x01(\tR\x06gridId\x12\"\n\x0cstart_row_id\x18\x02\x20\x01(\tH\0\
-    R\nstartRowIdB\x15\n\x13one_of_start_row_id\"\xb6\x01\n\x12CreateFieldPa\
+    R\nstartRowIdB\x15\n\x13one_of_start_row_id\"\xb6\x01\n\x12InsertFieldPa\
     yload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x1c\n\x05fi\
     eld\x18\x02\x20\x01(\x0b2\x06.FieldR\x05field\x12(\n\x10type_option_data\
     \x18\x03\x20\x01(\x0cR\x0etypeOptionData\x12&\n\x0estart_field_id\x18\

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

@@ -98,7 +98,7 @@ message CreateRowPayload {
     string grid_id = 1;
     oneof one_of_start_row_id { string start_row_id = 2; };
 }
-message CreateFieldPayload {
+message InsertFieldPayload {
     string grid_id = 1;
     Field field = 2;
     bytes type_option_data = 3;