refactor: separate grid revision structs from entities

This commit is contained in:
appflowy 2022-06-15 15:13:50 +08:00
parent 50605186fe
commit a13e6798ee
84 changed files with 7940 additions and 7218 deletions

View File

@ -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';

View File

@ -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';

View File

@ -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';

View File

@ -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';

View File

@ -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';

View File

@ -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';

View File

@ -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';

View File

@ -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';

View File

@ -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';

View File

@ -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';

View File

@ -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';

View File

@ -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';

View File

@ -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';

View File

@ -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';

View File

@ -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';

View File

@ -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 {

View File

@ -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';

View File

@ -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';

View File

@ -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';

View File

@ -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';

View File

@ -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';

View File

@ -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';

View File

@ -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';

View File

@ -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';

View File

@ -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();

View File

@ -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,
];

View File

@ -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');

View File

@ -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);
}

View File

@ -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');

View File

@ -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,

View File

@ -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=');

View File

@ -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);
}

View File

@ -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==');

View File

@ -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';

View File

@ -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);
}

View File

@ -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',

View File

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

View File

@ -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;

View File

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

View File

@ -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>> {

View File

@ -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)
}
}

View File

@ -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,
}

View File

@ -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();

View File

@ -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
}

View File

@ -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)
}
}

View File

@ -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
}
}

View File

@ -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
);
}

View File

@ -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();

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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(),
}

View File

@ -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)
}
}

View File

@ -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;

View File

@ -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)
};

View File

@ -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,
}

View File

@ -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));
}
}

View File

@ -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 {

View File

@ -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,

View File

@ -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 {

View File

@ -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};

View File

@ -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;

View File

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

View File

@ -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;

View File

@ -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; };
}

View File

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

View File

@ -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
}
}

View File

@ -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,
}
}
}

View File

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

View File

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 {

View File

@ -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![],

View File

@ -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()
}
}

View File

@ -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();
}
}

View File

@ -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,
}
}

View File

@ -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::*;