refactor: move entities from flowy-grid-data-model to flowy-grid crate

This commit is contained in:
appflowy 2022-07-01 20:32:11 +08:00
parent a9a797ddaf
commit c1ea97c729
96 changed files with 1392 additions and 1353 deletions

View File

@ -3,7 +3,7 @@ import 'package:flowy_sdk/dispatch/dispatch.dart';
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-sync/text_block_info.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-sync/text_block.pb.dart';
class DocumentService { class DocumentService {
Future<Either<TextBlockDelta, FlowyError>> openDocument({ Future<Either<TextBlockDelta, FlowyError>> openDocument({

View File

@ -7,7 +7,7 @@ import 'package:dartz/dartz.dart';
import 'package:flowy_infra/notifier.dart'; import 'package:flowy_infra/notifier.dart';
import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/log.dart';
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.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/block_entities.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
class GridBlockCache { class GridBlockCache {

View File

@ -6,10 +6,9 @@ import 'package:equatable/equatable.dart';
import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart';
import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/log.dart';
import 'package:flowy_sdk/protobuf/flowy-error/errors.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-data-model/grid.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/cell_entities.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'; import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.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'; import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/url_type_option.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/url_type_option.pb.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';

View File

@ -1,5 +1,5 @@
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:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';
import 'dart:async'; import 'dart:async';

View File

@ -1,5 +1,5 @@
import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/log.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/field.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';
import 'dart:async'; 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_listener.dart';
import 'package:app_flowy/workspace/application/grid/field/field_service.dart'; import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/log.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/field.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';
import 'dart:async'; import 'dart:async';

View File

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

View File

@ -1,11 +1,11 @@
import 'package:dartz/dartz.dart'; import 'package:dartz/dartz.dart';
import 'package:flowy_sdk/protobuf/flowy-error/errors.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_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
import 'package:flowy_infra/notifier.dart'; import 'package:flowy_infra/notifier.dart';
import 'dart:async'; import 'dart:async';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:app_flowy/core/notification_helper.dart'; import 'package:app_flowy/core/notification_helper.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
typedef UpdateFieldNotifiedValue = Either<Field, FlowyError>; typedef UpdateFieldNotifiedValue = Either<Field, FlowyError>;

View File

@ -2,9 +2,8 @@ import 'package:dartz/dartz.dart';
import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart';
import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/log.dart';
import 'package:flowy_sdk/protobuf/flowy-error/errors.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-data-model/grid.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/grid_entities.pb.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:protobuf/protobuf.dart'; import 'package:protobuf/protobuf.dart';

View File

@ -1,11 +1,11 @@
import 'package:dartz/dartz.dart'; import 'package:dartz/dartz.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-error/errors.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
import 'package:flowy_infra/notifier.dart'; import 'package:flowy_infra/notifier.dart';
import 'dart:async'; import 'dart:async';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:app_flowy/core/notification_helper.dart'; import 'package:app_flowy/core/notification_helper.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
typedef UpdateFieldNotifiedValue = Either<GridFieldChangeset, FlowyError>; typedef UpdateFieldNotifiedValue = Either<GridFieldChangeset, FlowyError>;

View File

@ -86,7 +86,7 @@ extension NumberFormatExtension on NumberFormat {
return "New Zealand dollar"; return "New Zealand dollar";
case NumberFormat.NorwegianKrone: case NumberFormat.NorwegianKrone:
return "Norwegian krone"; return "Norwegian krone";
case NumberFormat.Number: case NumberFormat.Num:
return "Number"; return "Number";
case NumberFormat.Percent: case NumberFormat.Percent:
return "Percent"; return "Percent";

View File

@ -4,7 +4,6 @@ import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
import 'package:dartz/dartz.dart'; import 'package:dartz/dartz.dart';
import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart';
import 'package:flowy_sdk/protobuf/flowy-error/errors.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/cell_entities.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/field_entities.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart';

View File

@ -4,7 +4,7 @@ import 'package:equatable/equatable.dart';
import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/log.dart';
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.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-folder-data-model/view.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/protobuf.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/protobuf.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';
import 'block/block_listener.dart'; import 'block/block_listener.dart';

View File

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

View File

@ -6,8 +6,10 @@ import 'package:flowy_sdk/dispatch/dispatch.dart';
import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/log.dart';
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.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-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/block_entities.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:flowy_sdk/protobuf/flowy-grid/grid_entities.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/row_entities.pb.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'cell/cell_service/cell_service.dart'; import 'cell/cell_service/cell_service.dart';
import 'row/row_service.dart'; import 'row/row_service.dart';

View File

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

View File

@ -1,12 +1,12 @@
import 'package:flowy_sdk/protobuf/flowy-error/errors.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/block_entities.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_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
import 'package:flowy_infra/notifier.dart'; import 'package:flowy_infra/notifier.dart';
import 'dart:async'; import 'dart:async';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:app_flowy/core/notification_helper.dart'; import 'package:app_flowy/core/notification_helper.dart';
import 'package:dartz/dartz.dart'; import 'package:dartz/dartz.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
typedef UpdateRowNotifiedValue = Either<Row, FlowyError>; typedef UpdateRowNotifiedValue = Either<Row, FlowyError>;
typedef UpdateFieldNotifiedValue = Either<List<Field>, FlowyError>; typedef UpdateFieldNotifiedValue = Either<List<Field>, FlowyError>;

View File

@ -5,8 +5,9 @@ import 'package:dartz/dartz.dart';
import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart';
import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/log.dart';
import 'package:flowy_sdk/protobuf/flowy-error/errors.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/block_entities.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:flowy_sdk/protobuf/flowy-grid/grid_entities.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/row_entities.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/row_entities.pb.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.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/field/field_service.dart';
import 'package:app_flowy/workspace/application/grid/grid_service.dart'; import 'package:app_flowy/workspace/application/grid/grid_service.dart';
import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/log.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/field.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';
import 'dart:async'; import 'dart:async';

View File

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

View File

@ -1,5 +1,5 @@
import 'package:app_flowy/workspace/application/grid/cell/cell_service/cell_service.dart'; import 'package:app_flowy/workspace/application/grid/cell/cell_service/cell_service.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/field.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter/material.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/button.dart';
import 'package:flowy_infra_ui/style_widget/hover.dart'; import 'package:flowy_infra_ui/style_widget/hover.dart';
import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/field.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'field_type_extension.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/button.dart';
import 'package:flowy_infra_ui/style_widget/text.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-error/errors.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/field.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart';

View File

@ -1,6 +1,6 @@
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/field.pb.dart';
import 'package:app_flowy/generated/locale_keys.g.dart'; import 'package:app_flowy/generated/locale_keys.g.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
extension FieldTypeListExtension on FieldType { extension FieldTypeListExtension on FieldType {
String iconName() { String iconName() {

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/scrolling/styled_list.dart';
import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/field.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'field_type_extension.dart'; import 'field_type_extension.dart';
import 'package:flutter_bloc/flutter_bloc.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/theme.dart';
import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/button.dart';
import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/field.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:reorderables/reorderables.dart'; import 'package:reorderables/reorderables.dart';

View File

@ -14,9 +14,9 @@ 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/icon_button.dart';
import 'package:flowy_infra_ui/style_widget/scrolling/styled_scroll_bar.dart'; import 'package:flowy_infra_ui/style_widget/scrolling/styled_scroll_bar.dart';
import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/field.pb.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:app_flowy/generated/locale_keys.g.dart'; import 'package:app_flowy/generated/locale_keys.g.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:window_size/window_size.dart'; import 'package:window_size/window_size.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/icon_button.dart';
import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/field.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:styled_widget/styled_widget.dart'; import 'package:styled_widget/styled_widget.dart';

View File

@ -4,15 +4,9 @@ import 'package:flowy_sdk/log.dart';
// ignore: unnecessary_import // ignore: unnecessary_import
import 'package:flowy_sdk/protobuf/dart-ffi/ffi_response.pb.dart'; import 'package:flowy_sdk/protobuf/dart-ffi/ffi_response.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.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';
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/row_entities.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-net/network_state.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-net/network_state.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-user/event_map.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-user/event_map.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-folder/event_map.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder/event_map.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/event_map.pb.dart';
import 'package:isolates/isolates.dart'; import 'package:isolates/isolates.dart';
import 'package:isolates/ports.dart'; import 'package:isolates/ports.dart';
import 'package:ffi/ffi.dart'; import 'package:ffi/ffi.dart';
@ -25,7 +19,7 @@ import 'package:flowy_sdk/protobuf/flowy-user-data-model/protobuf.dart';
import 'package:flowy_sdk/protobuf/dart-ffi/protobuf.dart'; import 'package:flowy_sdk/protobuf/dart-ffi/protobuf.dart';
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/protobuf.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/protobuf.dart';
import 'package:flowy_sdk/protobuf/flowy-text-block/protobuf.dart'; import 'package:flowy_sdk/protobuf/flowy-text-block/protobuf.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/protobuf.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/protobuf.dart';
import 'package:flowy_sdk/protobuf/flowy-sync/protobuf.dart'; import 'package:flowy_sdk/protobuf/flowy-sync/protobuf.dart';
// ignore: unused_import // ignore: unused_import

View File

@ -973,17 +973,13 @@ name = "flowy-grid-data-model"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"bytes", "bytes",
"flowy-derive",
"flowy-error-code", "flowy-error-code",
"indexmap", "indexmap",
"lib-infra", "lib-infra",
"nanoid", "nanoid",
"protobuf",
"serde", "serde",
"serde_json", "serde_json",
"serde_repr", "serde_repr",
"strum",
"strum_macros",
] ]
[[package]] [[package]]

View File

@ -17,7 +17,7 @@ use flowy_database::kv::KV;
use flowy_folder_data_model::entities::view::{gen_view_id, ViewDataType}; use flowy_folder_data_model::entities::view::{gen_view_id, ViewDataType};
use flowy_folder_data_model::entities::ViewInfo; use flowy_folder_data_model::entities::ViewInfo;
use flowy_folder_data_model::revision::ViewRevision; use flowy_folder_data_model::revision::ViewRevision;
use flowy_sync::entities::text_block_info::TextBlockId; use flowy_sync::entities::text_block::TextBlockId;
use futures::{FutureExt, StreamExt}; use futures::{FutureExt, StreamExt};
use std::{collections::HashSet, sync::Arc}; use std::{collections::HashSet, sync::Arc};

View File

@ -17,7 +17,7 @@ use flowy_folder_data_model::entities::{
use flowy_revision::disk::RevisionState; use flowy_revision::disk::RevisionState;
use flowy_revision::REVISION_WRITE_INTERVAL_IN_MILLIS; use flowy_revision::REVISION_WRITE_INTERVAL_IN_MILLIS;
use flowy_sync::entities::text_block_info::TextBlockInfo; use flowy_sync::entities::text_block::TextBlockInfo;
use flowy_test::{event_builder::*, FlowySDKTest}; use flowy_test::{event_builder::*, FlowySDKTest};
use std::{sync::Arc, time::Duration}; use std::{sync::Arc, time::Duration};
use tokio::time::sleep; use tokio::time::sleep;

View File

@ -0,0 +1,208 @@
use flowy_derive::ProtoBuf;
use flowy_error::ErrorCode;
use flowy_grid_data_model::parser::NotEmptyStr;
use flowy_grid_data_model::revision::RowRevision;
use std::sync::Arc;
#[derive(Debug, Clone, Default, ProtoBuf)]
pub struct GridBlock {
#[pb(index = 1)]
pub id: String,
#[pb(index = 2)]
pub row_orders: Vec<RowOrder>,
}
impl GridBlock {
pub fn new(block_id: &str, row_orders: Vec<RowOrder>) -> Self {
Self {
id: block_id.to_owned(),
row_orders,
}
}
}
#[derive(Debug, Default, Clone, ProtoBuf)]
pub struct RowOrder {
#[pb(index = 1)]
pub row_id: String,
#[pb(index = 2)]
pub block_id: String,
#[pb(index = 3)]
pub height: i32,
}
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, Default, ProtoBuf)]
pub struct Row {
#[pb(index = 1)]
pub id: String,
#[pb(index = 2)]
pub height: i32,
}
#[derive(Debug, Default, ProtoBuf)]
pub struct OptionalRow {
#[pb(index = 1, one_of)]
pub row: Option<Row>,
}
#[derive(Debug, Default, ProtoBuf)]
pub struct RepeatedRow {
#[pb(index = 1)]
pub items: Vec<Row>,
}
impl std::convert::From<Vec<Row>> for RepeatedRow {
fn from(items: Vec<Row>) -> Self {
Self { items }
}
}
#[derive(Debug, Default, ProtoBuf)]
pub struct RepeatedGridBlock {
#[pb(index = 1)]
pub items: Vec<GridBlock>,
}
impl std::convert::From<Vec<GridBlock>> for RepeatedGridBlock {
fn from(items: Vec<GridBlock>) -> Self {
Self { items }
}
}
#[derive(Debug, Clone, Default, ProtoBuf)]
pub struct IndexRowOrder {
#[pb(index = 1)]
pub row_order: RowOrder,
#[pb(index = 2, one_of)]
pub index: Option<i32>,
}
#[derive(Debug, Default, ProtoBuf)]
pub struct UpdatedRowOrder {
#[pb(index = 1)]
pub row_order: RowOrder,
#[pb(index = 2)]
pub row: Row,
}
impl UpdatedRowOrder {
pub fn new(row_rev: &RowRevision, row: Row) -> Self {
Self {
row_order: RowOrder::from(row_rev),
row,
}
}
}
impl std::convert::From<RowOrder> for IndexRowOrder {
fn from(row_order: RowOrder) -> Self {
Self { row_order, index: None }
}
}
impl std::convert::From<&RowRevision> for IndexRowOrder {
fn from(row: &RowRevision) -> Self {
let row_order = RowOrder::from(row);
Self::from(row_order)
}
}
#[derive(ProtoBuf, Default)]
pub struct GridBlockNotification {
#[pb(index = 1)]
hide_rows: Vec<String>,
}
#[derive(Debug, Default, ProtoBuf)]
pub struct GridRowsChangeset {
#[pb(index = 1)]
pub block_id: String,
#[pb(index = 2)]
pub inserted_rows: Vec<IndexRowOrder>,
#[pb(index = 3)]
pub deleted_rows: Vec<RowOrder>,
#[pb(index = 4)]
pub updated_rows: Vec<UpdatedRowOrder>,
}
impl GridRowsChangeset {
pub fn insert(block_id: &str, inserted_rows: Vec<IndexRowOrder>) -> Self {
Self {
block_id: block_id.to_owned(),
inserted_rows,
deleted_rows: vec![],
updated_rows: vec![],
}
}
pub fn delete(block_id: &str, deleted_rows: Vec<RowOrder>) -> Self {
Self {
block_id: block_id.to_owned(),
inserted_rows: vec![],
deleted_rows,
updated_rows: vec![],
}
}
pub fn update(block_id: &str, updated_rows: Vec<UpdatedRowOrder>) -> Self {
Self {
block_id: block_id.to_owned(),
inserted_rows: vec![],
deleted_rows: vec![],
updated_rows,
}
}
}
#[derive(ProtoBuf, Default)]
pub struct QueryGridBlocksPayload {
#[pb(index = 1)]
pub grid_id: String,
#[pb(index = 2)]
pub block_ids: Vec<String>,
}
pub struct QueryGridBlocksParams {
pub grid_id: String,
pub block_ids: Vec<String>,
}
impl TryInto<QueryGridBlocksParams> for QueryGridBlocksPayload {
type Error = ErrorCode;
fn try_into(self) -> Result<QueryGridBlocksParams, Self::Error> {
let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
Ok(QueryGridBlocksParams {
grid_id: grid_id.0,
block_ids: self.block_ids,
})
}
}

View File

@ -2,6 +2,8 @@ use crate::entities::{FieldIdentifier, FieldIdentifierPayload};
use flowy_derive::ProtoBuf; use flowy_derive::ProtoBuf;
use flowy_error::ErrorCode; use flowy_error::ErrorCode;
use flowy_grid_data_model::parser::NotEmptyStr; use flowy_grid_data_model::parser::NotEmptyStr;
use flowy_grid_data_model::revision::{CellRevision, RowMetaChangeset};
use std::collections::HashMap;
#[derive(ProtoBuf, Default)] #[derive(ProtoBuf, Default)]
pub struct CreateSelectOptionPayload { pub struct CreateSelectOptionPayload {
@ -70,3 +72,85 @@ impl TryInto<CellIdentifier> for CellIdentifierPayload {
}) })
} }
} }
#[derive(Debug, Default, ProtoBuf)]
pub struct Cell {
#[pb(index = 1)]
pub field_id: String,
#[pb(index = 2)]
pub data: Vec<u8>,
}
impl Cell {
pub fn new(field_id: &str, data: Vec<u8>) -> Self {
Self {
field_id: field_id.to_owned(),
data,
}
}
pub fn empty(field_id: &str) -> Self {
Self {
field_id: field_id.to_owned(),
data: vec![],
}
}
}
#[derive(Debug, Default, ProtoBuf)]
pub struct RepeatedCell {
#[pb(index = 1)]
pub items: Vec<Cell>,
}
impl std::ops::Deref for RepeatedCell {
type Target = Vec<Cell>;
fn deref(&self) -> &Self::Target {
&self.items
}
}
impl std::ops::DerefMut for RepeatedCell {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.items
}
}
impl std::convert::From<Vec<Cell>> for RepeatedCell {
fn from(items: Vec<Cell>) -> Self {
Self { items }
}
}
#[derive(Debug, Clone, Default, ProtoBuf)]
pub struct CellChangeset {
#[pb(index = 1)]
pub grid_id: String,
#[pb(index = 2)]
pub row_id: String,
#[pb(index = 3)]
pub field_id: String,
#[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_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,
}
}
}

View File

@ -1,7 +1,571 @@
use flowy_derive::ProtoBuf; use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use flowy_error::ErrorCode; use flowy_error::ErrorCode;
use flowy_grid_data_model::parser::NotEmptyStr; use flowy_grid_data_model::parser::NotEmptyStr;
use flowy_grid_data_model::revision::{FieldRevision, FieldTypeRevision};
use flowy_sync::entities::grid::FieldChangesetParams;
use serde_repr::*;
use std::sync::Arc;
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,
}
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_rev.into(),
frozen: field_rev.frozen,
visibility: field_rev.visibility,
width: field_rev.width,
is_primary: field_rev.is_primary,
}
}
}
impl std::convert::From<Arc<FieldRevision>> for Field {
fn from(field_rev: Arc<FieldRevision>) -> Self {
let field_rev = field_rev.as_ref().clone();
Field::from(field_rev)
}
}
#[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 }
}
}
impl std::convert::From<&Arc<FieldRevision>> for FieldOrder {
fn from(field_rev: &Arc<FieldRevision>) -> Self {
Self {
field_id: field_rev.id.clone(),
}
}
}
#[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: &Arc<FieldRevision>, index: usize) -> Self {
Self {
field: Field::from(field_rev.as_ref().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>>,
}
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)?;
let field_type = self.field_type.map(FieldTypeRevision::from);
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,
frozen: self.frozen,
visibility: self.visibility,
width: self.width,
type_option_data: self.type_option_data,
})
}
}
#[derive(
Debug,
Clone,
PartialEq,
Hash,
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 {
(self.clone() as u8).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
}
}
impl std::convert::From<&FieldType> for FieldTypeRevision {
fn from(ty: &FieldType) -> Self {
ty.clone() as u8
}
}
impl std::convert::From<FieldType> for FieldTypeRevision {
fn from(ty: FieldType) -> Self {
ty as u8
}
}
impl std::convert::From<&FieldTypeRevision> for FieldType {
fn from(ty: &FieldTypeRevision) -> Self {
FieldType::from(*ty)
}
}
impl std::convert::From<FieldTypeRevision> for FieldType {
fn from(ty: FieldTypeRevision) -> Self {
match ty {
0 => FieldType::RichText,
1 => FieldType::Number,
2 => FieldType::DateTime,
3 => FieldType::SingleSelect,
4 => FieldType::MultiSelect,
5 => FieldType::Checkbox,
6 => FieldType::URL,
_ => {
tracing::error!("Can't parser FieldTypeRevision: {} to FieldType", ty);
FieldType::RichText
}
}
}
}
#[derive(Debug, Clone, Default, ProtoBuf)] #[derive(Debug, Clone, Default, ProtoBuf)]
pub struct FieldIdentifierPayload { pub struct FieldIdentifierPayload {
#[pb(index = 1)] #[pb(index = 1)]

View File

@ -1,8 +1,9 @@
use crate::entities::FieldType; use crate::entities::FieldType;
use crate::parser::NotEmptyStr;
use crate::revision::{FieldRevision, GridFilterRevision};
use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use flowy_error_code::ErrorCode; use flowy_error::ErrorCode;
use flowy_grid_data_model::parser::NotEmptyStr;
use flowy_grid_data_model::revision::{FieldRevision, GridFilterRevision};
use flowy_sync::entities::grid::{CreateGridFilterParams, DeleteFilterParams};
use std::convert::TryInto; use std::convert::TryInto;
use std::sync::Arc; use std::sync::Arc;
@ -47,11 +48,6 @@ pub struct DeleteFilterPayload {
pub field_type: FieldType, pub field_type: FieldType,
} }
pub struct DeleteFilterParams {
pub filter_id: String,
pub field_type: FieldType,
}
impl TryInto<DeleteFilterParams> for DeleteFilterPayload { impl TryInto<DeleteFilterParams> for DeleteFilterPayload {
type Error = ErrorCode; type Error = ErrorCode;
@ -61,7 +57,7 @@ impl TryInto<DeleteFilterParams> for DeleteFilterPayload {
.0; .0;
Ok(DeleteFilterParams { Ok(DeleteFilterParams {
filter_id, filter_id,
field_type: self.field_type, field_type_rev: self.field_type.into(),
}) })
} }
} }
@ -86,20 +82,13 @@ impl CreateGridFilterPayload {
pub fn new<T: Into<i32>>(field_rev: &FieldRevision, condition: T, content: Option<String>) -> Self { pub fn new<T: Into<i32>>(field_rev: &FieldRevision, condition: T, content: Option<String>) -> Self {
Self { Self {
field_id: field_rev.id.clone(), field_id: field_rev.id.clone(),
field_type: field_rev.field_type.clone(), field_type: field_rev.field_type_rev.into(),
condition: condition.into(), condition: condition.into(),
content, content,
} }
} }
} }
pub struct CreateGridFilterParams {
pub field_id: String,
pub field_type: FieldType,
pub condition: u8,
pub content: Option<String>,
}
impl TryInto<CreateGridFilterParams> for CreateGridFilterPayload { impl TryInto<CreateGridFilterParams> for CreateGridFilterPayload {
type Error = ErrorCode; type Error = ErrorCode;
@ -128,7 +117,7 @@ impl TryInto<CreateGridFilterParams> for CreateGridFilterPayload {
Ok(CreateGridFilterParams { Ok(CreateGridFilterParams {
field_id, field_id,
field_type: self.field_type, field_type_rev: self.field_type.into(),
condition, condition,
content: self.content, content: self.content,
}) })

View File

@ -0,0 +1,106 @@
use crate::entities::{FieldOrder, GridBlock};
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use flowy_error::ErrorCode;
use flowy_grid_data_model::parser::NotEmptyStr;
#[derive(Debug, Clone, Default, ProtoBuf)]
pub struct Grid {
#[pb(index = 1)]
pub id: String,
#[pb(index = 2)]
pub field_orders: Vec<FieldOrder>,
#[pb(index = 3)]
pub blocks: Vec<GridBlock>,
}
#[derive(ProtoBuf, Default)]
pub struct CreateGridPayload {
#[pb(index = 1)]
pub name: String,
}
#[derive(Clone, ProtoBuf, Default, Debug)]
pub struct GridId {
#[pb(index = 1)]
pub value: String,
}
impl AsRef<str> for GridId {
fn as_ref(&self) -> &str {
&self.value
}
}
#[derive(Clone, ProtoBuf, Default, Debug)]
pub struct GridBlockId {
#[pb(index = 1)]
pub value: String,
}
impl AsRef<str> for GridBlockId {
fn as_ref(&self) -> &str {
&self.value
}
}
impl std::convert::From<&str> for GridBlockId {
fn from(s: &str) -> Self {
GridBlockId { value: s.to_owned() }
}
}
#[derive(Debug, Clone, ProtoBuf_Enum)]
pub enum MoveItemType {
MoveField = 0,
MoveRow = 1,
}
impl std::default::Default for MoveItemType {
fn default() -> Self {
MoveItemType::MoveField
}
}
#[derive(Debug, Clone, Default, ProtoBuf)]
pub struct MoveItemPayload {
#[pb(index = 1)]
pub grid_id: String,
#[pb(index = 2)]
pub item_id: String,
#[pb(index = 3)]
pub from_index: i32,
#[pb(index = 4)]
pub to_index: i32,
#[pb(index = 5)]
pub ty: MoveItemType,
}
#[derive(Clone)]
pub struct MoveItemParams {
pub grid_id: String,
pub item_id: String,
pub from_index: i32,
pub to_index: i32,
pub ty: MoveItemType,
}
impl TryInto<MoveItemParams> for MoveItemPayload {
type Error = ErrorCode;
fn try_into(self) -> Result<MoveItemParams, Self::Error> {
let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
let item_id = NotEmptyStr::parse(self.item_id).map_err(|_| ErrorCode::InvalidData)?;
Ok(MoveItemParams {
grid_id: grid_id.0,
item_id: item_id.0,
from_index: self.from_index,
to_index: self.to_index,
ty: self.ty,
})
}
}

View File

@ -1,8 +1,8 @@
use crate::parser::NotEmptyStr;
use flowy_derive::ProtoBuf; use flowy_derive::ProtoBuf;
use flowy_error_code::ErrorCode; use flowy_error::ErrorCode;
use flowy_grid_data_model::parser::NotEmptyStr;
use crate::revision::GridGroupRevision; use flowy_grid_data_model::revision::GridGroupRevision;
use flowy_sync::entities::grid::CreateGridGroupParams;
use std::convert::TryInto; use std::convert::TryInto;
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] #[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
@ -56,11 +56,6 @@ pub struct CreateGridGroupPayload {
pub sub_field_id: Option<String>, pub sub_field_id: Option<String>,
} }
pub struct CreateGridGroupParams {
pub field_id: Option<String>,
pub sub_field_id: Option<String>,
}
impl TryInto<CreateGridGroupParams> for CreateGridGroupPayload { impl TryInto<CreateGridGroupParams> for CreateGridGroupPayload {
type Error = ErrorCode; type Error = ErrorCode;

View File

@ -1,7 +1,19 @@
mod block_entities;
mod cell_entities; mod cell_entities;
mod field_entities; mod field_entities;
mod filter_entities;
mod grid_entities;
mod group_entities;
mod row_entities; mod row_entities;
mod setting_entities;
mod sort_entities;
pub use block_entities::*;
pub use cell_entities::*; pub use cell_entities::*;
pub use field_entities::*; pub use field_entities::*;
pub use filter_entities::*;
pub use grid_entities::*;
pub use group_entities::*;
pub use row_entities::*; pub use row_entities::*;
pub use setting_entities::*;
pub use sort_entities::*;

View File

@ -29,3 +29,30 @@ impl TryInto<RowIdentifier> for RowIdentifierPayload {
}) })
} }
} }
#[derive(ProtoBuf, Default)]
pub struct CreateRowPayload {
#[pb(index = 1)]
pub grid_id: String,
#[pb(index = 2, one_of)]
pub start_row_id: Option<String>,
}
#[derive(Default)]
pub struct CreateRowParams {
pub grid_id: String,
pub start_row_id: Option<String>,
}
impl TryInto<CreateRowParams> for CreateRowPayload {
type Error = ErrorCode;
fn try_into(self) -> Result<CreateRowParams, Self::Error> {
let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
Ok(CreateRowParams {
grid_id: grid_id.0,
start_row_id: self.start_row_id,
})
}
}

View File

@ -1,12 +1,12 @@
use crate::entities::{ use crate::entities::{
CreateGridFilterParams, CreateGridFilterPayload, CreateGridGroupParams, CreateGridGroupPayload, CreateGridFilterPayload, CreateGridGroupPayload, CreateGridSortPayload, DeleteFilterPayload, RepeatedGridFilter,
CreateGridSortParams, CreateGridSortPayload, DeleteFilterParams, DeleteFilterPayload, RepeatedGridFilter,
RepeatedGridGroup, RepeatedGridSort, RepeatedGridGroup, RepeatedGridSort,
}; };
use crate::parser::NotEmptyStr;
use crate::revision::GridLayoutRevision;
use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use flowy_error_code::ErrorCode; use flowy_error::ErrorCode;
use flowy_grid_data_model::parser::NotEmptyStr;
use flowy_grid_data_model::revision::GridLayoutRevision;
use flowy_sync::entities::grid::GridSettingChangesetParams;
use std::collections::HashMap; use std::collections::HashMap;
use std::convert::TryInto; use std::convert::TryInto;
@ -109,23 +109,6 @@ pub struct GridSettingChangesetPayload {
pub delete_sort: Option<String>, pub delete_sort: Option<String>,
} }
pub struct GridSettingChangesetParams {
pub grid_id: String,
pub layout_type: GridLayoutType,
pub insert_filter: Option<CreateGridFilterParams>,
pub delete_filter: Option<DeleteFilterParams>,
pub insert_group: Option<CreateGridGroupParams>,
pub delete_group: Option<String>,
pub insert_sort: Option<CreateGridSortParams>,
pub delete_sort: Option<String>,
}
impl GridSettingChangesetParams {
pub fn is_filter_changed(&self) -> bool {
self.insert_filter.is_some() || self.delete_filter.is_some()
}
}
impl TryInto<GridSettingChangesetParams> for GridSettingChangesetPayload { impl TryInto<GridSettingChangesetParams> for GridSettingChangesetPayload {
type Error = ErrorCode; type Error = ErrorCode;
@ -166,7 +149,7 @@ impl TryInto<GridSettingChangesetParams> for GridSettingChangesetPayload {
Ok(GridSettingChangesetParams { Ok(GridSettingChangesetParams {
grid_id: view_id, grid_id: view_id,
layout_type: self.layout_type, layout_type: self.layout_type.into(),
insert_filter, insert_filter,
delete_filter, delete_filter,
insert_group, insert_group,

View File

@ -1,8 +1,8 @@
use crate::parser::NotEmptyStr;
use flowy_derive::ProtoBuf; use flowy_derive::ProtoBuf;
use flowy_error_code::ErrorCode; use flowy_error::ErrorCode;
use flowy_grid_data_model::parser::NotEmptyStr;
use crate::revision::GridSortRevision; use flowy_grid_data_model::revision::GridSortRevision;
use flowy_sync::entities::grid::CreateGridSortParams;
use std::convert::TryInto; use std::convert::TryInto;
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] #[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
@ -50,10 +50,6 @@ pub struct CreateGridSortPayload {
pub field_id: Option<String>, pub field_id: Option<String>,
} }
pub struct CreateGridSortParams {
pub field_id: Option<String>,
}
impl TryInto<CreateGridSortParams> for CreateGridSortPayload { impl TryInto<CreateGridSortParams> for CreateGridSortPayload {
type Error = ErrorCode; type Error = ErrorCode;

View File

@ -3,8 +3,8 @@ use crate::manager::GridManager;
use crate::services::field::type_options::*; use crate::services::field::type_options::*;
use crate::services::field::{default_type_option_builder_from_type, type_option_builder_from_json_str}; use crate::services::field::{default_type_option_builder_from_type, type_option_builder_from_json_str};
use flowy_error::{ErrorCode, FlowyError, FlowyResult}; use flowy_error::{ErrorCode, FlowyError, FlowyResult};
use flowy_grid_data_model::entities::*;
use flowy_grid_data_model::revision::FieldRevision; use flowy_grid_data_model::revision::FieldRevision;
use flowy_sync::entities::grid::{FieldChangesetParams, GridSettingChangesetParams};
use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; use lib_dispatch::prelude::{data_result, AppData, Data, DataResult};
use std::sync::Arc; use std::sync::Arc;
@ -59,7 +59,12 @@ pub(crate) async fn get_fields_handler(
) -> DataResult<RepeatedField, FlowyError> { ) -> DataResult<RepeatedField, FlowyError> {
let params: QueryFieldParams = data.into_inner().try_into()?; let params: QueryFieldParams = data.into_inner().try_into()?;
let editor = manager.get_grid_editor(&params.grid_id)?; let editor = manager.get_grid_editor(&params.grid_id)?;
let field_orders = params.field_orders.items; let field_orders = params
.field_orders
.items
.into_iter()
.map(|field_order| field_order.field_id)
.collect();
let field_revs = editor.get_field_revs(Some(field_orders)).await?; 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(); let repeated_field: RepeatedField = field_revs.into_iter().map(Field::from).collect::<Vec<_>>().into();
data_result(repeated_field) data_result(repeated_field)
@ -160,7 +165,8 @@ pub(crate) async fn get_field_type_option_data_handler(
match editor.get_field_rev(&params.field_id).await { match editor.get_field_rev(&params.field_id).await {
None => Err(FlowyError::record_not_found()), None => Err(FlowyError::record_not_found()),
Some(field_rev) => { Some(field_rev) => {
let type_option_data = get_type_option_data(&field_rev, &field_rev.field_type).await?; let field_type = field_rev.field_type_rev.into();
let type_option_data = get_type_option_data(&field_rev, &field_type).await?;
let data = FieldTypeOptionData { let data = FieldTypeOptionData {
grid_id: params.grid_id, grid_id: params.grid_id,
field: field_rev.into(), field: field_rev.into(),
@ -180,7 +186,8 @@ pub(crate) async fn create_field_type_option_data_handler(
let params: CreateFieldParams = data.into_inner().try_into()?; let params: CreateFieldParams = data.into_inner().try_into()?;
let editor = manager.get_grid_editor(&params.grid_id)?; let editor = manager.get_grid_editor(&params.grid_id)?;
let field_rev = editor.create_next_field_rev(&params.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?; let field_type: FieldType = field_rev.field_type_rev.into();
let type_option_data = get_type_option_data(&field_rev, &field_type).await?;
data_result(FieldTypeOptionData { data_result(FieldTypeOptionData {
grid_id: params.grid_id, grid_id: params.grid_id,
@ -205,7 +212,8 @@ async fn get_type_option_data(field_rev: &FieldRevision, field_type: &FieldType)
let s = field_rev let s = field_rev
.get_type_option_str(field_type) .get_type_option_str(field_type)
.unwrap_or_else(|| default_type_option_builder_from_type(field_type).entry().json_str()); .unwrap_or_else(|| default_type_option_builder_from_type(field_type).entry().json_str());
let builder = type_option_builder_from_json_str(&s, &field_rev.field_type); let field_type: FieldType = field_rev.field_type_rev.into();
let builder = type_option_builder_from_json_str(&s, &field_type);
let type_option_data = builder.entry().protobuf_bytes().to_vec(); let type_option_data = builder.entry().protobuf_bytes().to_vec();
Ok(type_option_data) Ok(type_option_data)

View File

@ -30,7 +30,7 @@ macro_rules! impl_type_option {
($target: ident, $field_type:expr) => { ($target: ident, $field_type:expr) => {
impl std::convert::From<&FieldRevision> for $target { impl std::convert::From<&FieldRevision> for $target {
fn from(field_rev: &FieldRevision) -> $target { fn from(field_rev: &FieldRevision) -> $target {
match field_rev.get_type_option_entry::<$target>(&$field_type) { match field_rev.get_type_option_entry::<$target, _>(&$field_type) {
None => $target::default(), None => $target::default(),
Some(target) => target, Some(target) => target,
} }
@ -39,7 +39,7 @@ macro_rules! impl_type_option {
impl std::convert::From<&std::sync::Arc<FieldRevision>> for $target { impl std::convert::From<&std::sync::Arc<FieldRevision>> for $target {
fn from(field_rev: &std::sync::Arc<FieldRevision>) -> $target { fn from(field_rev: &std::sync::Arc<FieldRevision>) -> $target {
match field_rev.get_type_option_entry::<$target>(&$field_type) { match field_rev.get_type_option_entry::<$target, _>(&$field_type) {
None => $target::default(), None => $target::default(),
Some(target) => target, Some(target) => target,
} }
@ -53,10 +53,6 @@ macro_rules! impl_type_option {
} }
impl TypeOptionDataEntry for $target { impl TypeOptionDataEntry for $target {
fn field_type(&self) -> FieldType {
$field_type
}
fn json_str(&self) -> String { fn json_str(&self) -> String {
match serde_json::to_string(&self) { match serde_json::to_string(&self) {
Ok(s) => s, Ok(s) => s,

View File

@ -1,13 +1,11 @@
use crate::dart_notification::{send_dart_notification, GridNotification}; use crate::dart_notification::{send_dart_notification, GridNotification};
use crate::entities::{CellChangeset, GridRowsChangeset, IndexRowOrder, Row, RowOrder, UpdatedRowOrder};
use crate::manager::GridUser; use crate::manager::GridUser;
use crate::services::block_revision_editor::GridBlockRevisionEditor; use crate::services::block_revision_editor::GridBlockRevisionEditor;
use crate::services::persistence::block_index::BlockIndexCache; use crate::services::persistence::block_index::BlockIndexCache;
use crate::services::row::{block_from_row_orders, GridBlockSnapshot}; use crate::services::row::{block_from_row_orders, GridBlockSnapshot};
use dashmap::DashMap; use dashmap::DashMap;
use flowy_error::FlowyResult; use flowy_error::FlowyResult;
use flowy_grid_data_model::entities::{
CellChangeset, GridRowsChangeset, IndexRowOrder, Row, RowOrder, UpdatedRowOrder,
};
use flowy_grid_data_model::revision::{ use flowy_grid_data_model::revision::{
GridBlockMetaRevision, GridBlockMetaRevisionChangeset, RowMetaChangeset, RowRevision, GridBlockMetaRevision, GridBlockMetaRevisionChangeset, RowMetaChangeset, RowRevision,
}; };

View File

@ -1,6 +1,5 @@
use bytes::Bytes; use bytes::Bytes;
use flowy_error::{FlowyError, FlowyResult}; use flowy_error::{FlowyError, FlowyResult};
use flowy_grid_data_model::entities::RowOrder;
use flowy_grid_data_model::revision::{CellRevision, GridBlockRevision, RowMetaChangeset, RowRevision}; use flowy_grid_data_model::revision::{CellRevision, GridBlockRevision, RowMetaChangeset, RowRevision};
use flowy_revision::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; use flowy_revision::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder};
use flowy_sync::client_grid::{GridBlockMetaChange, GridBlockRevisionPad}; use flowy_sync::client_grid::{GridBlockMetaChange, GridBlockRevisionPad};
@ -11,6 +10,7 @@ use lib_ot::core::PlainTextAttributes;
use std::borrow::Cow; use std::borrow::Cow;
use std::sync::Arc; use std::sync::Arc;
use tokio::sync::RwLock; use tokio::sync::RwLock;
use crate::entities::RowOrder;
pub struct GridBlockRevisionEditor { pub struct GridBlockRevisionEditor {
user_id: String, user_id: String,

View File

@ -1,6 +1,6 @@
use crate::entities::{Field, FieldType};
use crate::services::field::type_options::*; use crate::services::field::type_options::*;
use bytes::Bytes; use bytes::Bytes;
use flowy_grid_data_model::entities::{Field, FieldType};
use flowy_grid_data_model::revision::{FieldRevision, TypeOptionDataEntry}; use flowy_grid_data_model::revision::{FieldRevision, TypeOptionDataEntry};
use indexmap::IndexMap; use indexmap::IndexMap;
@ -14,7 +14,9 @@ pub type BoxTypeOptionBuilder = Box<dyn TypeOptionBuilder + 'static>;
impl FieldBuilder { impl FieldBuilder {
pub fn new<T: Into<BoxTypeOptionBuilder>>(type_option_builder: T) -> Self { pub fn new<T: Into<BoxTypeOptionBuilder>>(type_option_builder: T) -> Self {
let type_option_builder = type_option_builder.into(); let type_option_builder = type_option_builder.into();
let field_rev = FieldRevision::new("", "", type_option_builder.field_type(), false); let field_type = type_option_builder.field_type();
let width = field_type.default_cell_width();
let field_rev = FieldRevision::new("", "", field_type, width, false);
Self { Self {
field_rev, field_rev,
type_option_builder, type_option_builder,
@ -31,7 +33,7 @@ impl FieldBuilder {
id: field.id, id: field.id,
name: field.name, name: field.name,
desc: field.desc, desc: field.desc,
field_type: field.field_type, field_type_rev: field.field_type.into(),
frozen: field.frozen, frozen: field.frozen,
visibility: field.visibility, visibility: field.visibility,
width: field.width, width: field.width,
@ -75,7 +77,6 @@ impl FieldBuilder {
} }
pub fn build(self) -> FieldRevision { 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; let mut field_rev = self.field_rev;
field_rev.insert_type_option_entry(self.type_option_builder.entry()); field_rev.insert_type_option_entry(self.type_option_builder.entry());
field_rev field_rev

View File

@ -1,10 +1,10 @@
use crate::entities::{FieldType, GridCheckboxFilter};
use crate::impl_type_option; use crate::impl_type_option;
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
use crate::services::row::{CellContentChangeset, CellDataOperation, DecodedCellData}; use crate::services::row::{CellContentChangeset, CellDataOperation, DecodedCellData};
use bytes::Bytes; use bytes::Bytes;
use flowy_derive::ProtoBuf; use flowy_derive::ProtoBuf;
use flowy_error::{FlowyError, FlowyResult}; use flowy_error::{FlowyError, FlowyResult};
use flowy_grid_data_model::entities::{FieldType, GridCheckboxFilter};
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry}; use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -22,7 +22,7 @@ impl CheckboxTypeOptionBuilder {
impl TypeOptionBuilder for CheckboxTypeOptionBuilder { impl TypeOptionBuilder for CheckboxTypeOptionBuilder {
fn field_type(&self) -> FieldType { fn field_type(&self) -> FieldType {
self.0.field_type() FieldType::Checkbox
} }
fn entry(&self) -> &dyn TypeOptionDataEntry { fn entry(&self) -> &dyn TypeOptionDataEntry {
@ -99,7 +99,7 @@ mod tests {
use crate::services::field::FieldBuilder; use crate::services::field::FieldBuilder;
use crate::services::row::{apply_cell_data_changeset, decode_cell_data}; use crate::services::row::{apply_cell_data_changeset, decode_cell_data};
use flowy_grid_data_model::entities::FieldType; use crate::entities::FieldType;
#[test] #[test]
fn checkout_box_description_test() { fn checkout_box_description_test() {

View File

@ -1,3 +1,4 @@
use crate::entities::{CellChangeset, FieldType, GridDateFilter};
use crate::entities::{CellIdentifier, CellIdentifierPayload}; use crate::entities::{CellIdentifier, CellIdentifierPayload};
use crate::impl_type_option; use crate::impl_type_option;
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
@ -7,7 +8,6 @@ use chrono::format::strftime::StrftimeItems;
use chrono::{NaiveDateTime, Timelike}; use chrono::{NaiveDateTime, Timelike};
use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use flowy_error::{ErrorCode, FlowyError, FlowyResult}; use flowy_error::{ErrorCode, FlowyError, FlowyResult};
use flowy_grid_data_model::entities::{CellChangeset, FieldType, GridDateFilter};
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry}; use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use strum_macros::EnumIter; use strum_macros::EnumIter;
@ -181,7 +181,7 @@ impl DateTypeOptionBuilder {
} }
impl TypeOptionBuilder for DateTypeOptionBuilder { impl TypeOptionBuilder for DateTypeOptionBuilder {
fn field_type(&self) -> FieldType { fn field_type(&self) -> FieldType {
self.0.field_type() FieldType::DateTime
} }
fn entry(&self) -> &dyn TypeOptionDataEntry { fn entry(&self) -> &dyn TypeOptionDataEntry {
@ -358,11 +358,11 @@ impl std::convert::From<DateCellContentChangeset> for CellContentChangeset {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::entities::FieldType;
use crate::services::field::FieldBuilder; use crate::services::field::FieldBuilder;
use crate::services::field::{DateCellContentChangeset, DateCellData, DateFormat, DateTypeOption, TimeFormat}; use crate::services::field::{DateCellContentChangeset, DateCellData, DateFormat, DateTypeOption, TimeFormat};
use crate::services::row::CellDataOperation; use crate::services::row::CellDataOperation;
use flowy_grid_data_model::entities::FieldType; use flowy_grid_data_model::revision::FieldRevision;
use flowy_grid_data_model::revision::{FieldRevision, TypeOptionDataEntry};
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
#[test] #[test]
@ -534,7 +534,7 @@ mod tests {
fn date_type_option_apply_changeset_error_test() { fn date_type_option_apply_changeset_error_test() {
let mut type_option = DateTypeOption::new(); let mut type_option = DateTypeOption::new();
type_option.include_time = true; type_option.include_time = true;
let field_rev = FieldBuilder::from_field_type(&type_option.field_type()).build(); let field_rev = FieldBuilder::from_field_type(&FieldType::DateTime).build();
let date_timestamp = "1653609600".to_owned(); let date_timestamp = "1653609600".to_owned();
assert_changeset_result( assert_changeset_result(
@ -543,7 +543,7 @@ mod tests {
date: Some(date_timestamp.clone()), date: Some(date_timestamp.clone()),
time: Some("1:".to_owned()), time: Some("1:".to_owned()),
}, },
&type_option.field_type(), &FieldType::DateTime,
&field_rev, &field_rev,
"May 27,2022 01:00", "May 27,2022 01:00",
); );
@ -554,7 +554,7 @@ mod tests {
date: Some(date_timestamp), date: Some(date_timestamp),
time: Some("1:00".to_owned()), time: Some("1:00".to_owned()),
}, },
&type_option.field_type(), &FieldType::DateTime,
&field_rev, &field_rev,
"May 27,2022 01:00", "May 27,2022 01:00",
); );
@ -565,7 +565,7 @@ mod tests {
fn date_type_option_twelve_hours_to_twenty_four_hours() { fn date_type_option_twelve_hours_to_twenty_four_hours() {
let mut type_option = DateTypeOption::new(); let mut type_option = DateTypeOption::new();
type_option.include_time = true; type_option.include_time = true;
let field_rev = FieldBuilder::from_field_type(&type_option.field_type()).build(); let field_rev = FieldBuilder::from_field_type(&FieldType::DateTime).build();
let date_timestamp = "1653609600".to_owned(); let date_timestamp = "1653609600".to_owned();
assert_changeset_result( assert_changeset_result(
@ -574,7 +574,7 @@ mod tests {
date: Some(date_timestamp), date: Some(date_timestamp),
time: Some("1:00 am".to_owned()), time: Some("1:00 am".to_owned()),
}, },
&type_option.field_type(), &FieldType::DateTime,
&field_rev, &field_rev,
"May 27,2022 01:00", "May 27,2022 01:00",
); );

View File

@ -15,7 +15,7 @@ lazy_static! {
#[derive(Clone, Copy, Debug, PartialEq, Eq, EnumIter, Serialize, Deserialize, ProtoBuf_Enum)] #[derive(Clone, Copy, Debug, PartialEq, Eq, EnumIter, Serialize, Deserialize, ProtoBuf_Enum)]
pub enum NumberFormat { pub enum NumberFormat {
Number = 0, Num = 0,
USD = 1, USD = 1,
CanadianDollar = 2, CanadianDollar = 2,
EUR = 4, EUR = 4,
@ -55,7 +55,7 @@ pub enum NumberFormat {
impl std::default::Default for NumberFormat { impl std::default::Default for NumberFormat {
fn default() -> Self { fn default() -> Self {
NumberFormat::Number NumberFormat::Num
} }
} }
@ -400,7 +400,7 @@ define_currency_set!(
impl NumberFormat { impl NumberFormat {
pub fn currency(&self) -> &'static number_currency::Currency { pub fn currency(&self) -> &'static number_currency::Currency {
match self { match self {
NumberFormat::Number => number_currency::NUMBER, NumberFormat::Num => number_currency::NUMBER,
NumberFormat::USD => number_currency::USD, NumberFormat::USD => number_currency::USD,
NumberFormat::CanadianDollar => number_currency::CANADIAN_DOLLAR, NumberFormat::CanadianDollar => number_currency::CANADIAN_DOLLAR,
NumberFormat::EUR => number_currency::EUR, NumberFormat::EUR => number_currency::EUR,

View File

@ -1,12 +1,12 @@
use crate::impl_type_option; use crate::impl_type_option;
use crate::entities::{FieldType, GridNumberFilter};
use crate::services::field::type_options::number_type_option::format::*; use crate::services::field::type_options::number_type_option::format::*;
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
use crate::services::row::{CellContentChangeset, CellDataOperation, DecodedCellData}; use crate::services::row::{CellContentChangeset, CellDataOperation, DecodedCellData};
use bytes::Bytes; use bytes::Bytes;
use flowy_derive::ProtoBuf; use flowy_derive::ProtoBuf;
use flowy_error::{FlowyError, FlowyResult}; use flowy_error::{FlowyError, FlowyResult};
use flowy_grid_data_model::entities::{FieldType, GridNumberFilter};
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry}; use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry};
use rust_decimal::Decimal; use rust_decimal::Decimal;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -41,7 +41,7 @@ impl NumberTypeOptionBuilder {
impl TypeOptionBuilder for NumberTypeOptionBuilder { impl TypeOptionBuilder for NumberTypeOptionBuilder {
fn field_type(&self) -> FieldType { fn field_type(&self) -> FieldType {
self.0.field_type() FieldType::Number
} }
fn entry(&self) -> &dyn TypeOptionDataEntry { fn entry(&self) -> &dyn TypeOptionDataEntry {
@ -76,7 +76,7 @@ impl NumberTypeOption {
fn cell_content_from_number_str(&self, s: &str) -> FlowyResult<String> { fn cell_content_from_number_str(&self, s: &str) -> FlowyResult<String> {
match self.format { match self.format {
NumberFormat::Number => { NumberFormat::Num => {
if let Ok(v) = s.parse::<f64>() { if let Ok(v) = s.parse::<f64>() {
return Ok(v.to_string()); return Ok(v.to_string());
} }
@ -155,7 +155,7 @@ impl CellDataOperation<String, GridNumberFilter> for NumberTypeOption {
let cell_data = encoded_data.into(); let cell_data = encoded_data.into();
match self.format { match self.format {
NumberFormat::Number => { NumberFormat::Num => {
if let Ok(v) = cell_data.parse::<f64>() { if let Ok(v) = cell_data.parse::<f64>() {
return Ok(DecodedCellData::new(v.to_string())); return Ok(DecodedCellData::new(v.to_string()));
} }
@ -210,10 +210,10 @@ impl std::default::Default for NumberTypeOption {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::entities::FieldType;
use crate::services::field::FieldBuilder; use crate::services::field::FieldBuilder;
use crate::services::field::{NumberFormat, NumberTypeOption}; use crate::services::field::{NumberFormat, NumberTypeOption};
use crate::services::row::CellDataOperation; use crate::services::row::CellDataOperation;
use flowy_grid_data_model::entities::FieldType;
use flowy_grid_data_model::revision::FieldRevision; use flowy_grid_data_model::revision::FieldRevision;
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
@ -245,7 +245,7 @@ mod tests {
for format in NumberFormat::iter() { for format in NumberFormat::iter() {
type_option.format = format; type_option.format = format;
match format { match format {
NumberFormat::Number => { NumberFormat::Num => {
assert_equal(&type_option, "18443", "18443", &field_type, &field_rev); assert_equal(&type_option, "18443", "18443", &field_type, &field_rev);
} }
NumberFormat::USD => { NumberFormat::USD => {
@ -274,7 +274,7 @@ mod tests {
for format in NumberFormat::iter() { for format in NumberFormat::iter() {
type_option.format = format; type_option.format = format;
match format { match format {
NumberFormat::Number => { NumberFormat::Num => {
assert_equal(&type_option, "18443", "18443", &field_type, &field_rev); assert_equal(&type_option, "18443", "18443", &field_type, &field_rev);
assert_equal(&type_option, "0.2", "0.2", &field_type, &field_rev); assert_equal(&type_option, "0.2", "0.2", &field_type, &field_rev);
} }
@ -314,7 +314,7 @@ mod tests {
for format in NumberFormat::iter() { for format in NumberFormat::iter() {
type_option.format = format; type_option.format = format;
match format { match format {
NumberFormat::Number => { NumberFormat::Num => {
assert_equal(&type_option, "18443", "18443", &field_type, &field_rev); assert_equal(&type_option, "18443", "18443", &field_type, &field_rev);
} }
NumberFormat::USD => { NumberFormat::USD => {

View File

@ -1,3 +1,4 @@
use crate::entities::{CellChangeset, FieldType, GridSelectOptionFilter};
use crate::entities::{CellIdentifier, CellIdentifierPayload}; use crate::entities::{CellIdentifier, CellIdentifierPayload};
use crate::impl_type_option; use crate::impl_type_option;
use crate::services::field::type_options::util::get_cell_data; use crate::services::field::type_options::util::get_cell_data;
@ -6,7 +7,6 @@ use crate::services::row::{CellContentChangeset, CellDataOperation, DecodedCellD
use bytes::Bytes; use bytes::Bytes;
use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use flowy_error::{ErrorCode, FlowyError, FlowyResult}; use flowy_error::{ErrorCode, FlowyError, FlowyResult};
use flowy_grid_data_model::entities::{CellChangeset, FieldType, GridSelectOptionFilter};
use flowy_grid_data_model::parser::NotEmptyStr; use flowy_grid_data_model::parser::NotEmptyStr;
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry}; use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry};
use nanoid::nanoid; use nanoid::nanoid;
@ -49,7 +49,8 @@ pub trait SelectOptionOperation: TypeOptionDataEntry + Send + Sync {
} }
pub fn select_option_operation(field_rev: &FieldRevision) -> FlowyResult<Box<dyn SelectOptionOperation>> { pub fn select_option_operation(field_rev: &FieldRevision) -> FlowyResult<Box<dyn SelectOptionOperation>> {
match &field_rev.field_type { let field_type: FieldType = field_rev.field_type_rev.into();
match &field_type {
FieldType::SingleSelect => { FieldType::SingleSelect => {
let type_option = SingleSelectTypeOption::from(field_rev); let type_option = SingleSelectTypeOption::from(field_rev);
Ok(Box::new(type_option)) Ok(Box::new(type_option))
@ -159,7 +160,7 @@ impl SingleSelectTypeOptionBuilder {
impl TypeOptionBuilder for SingleSelectTypeOptionBuilder { impl TypeOptionBuilder for SingleSelectTypeOptionBuilder {
fn field_type(&self) -> FieldType { fn field_type(&self) -> FieldType {
self.0.field_type() FieldType::SingleSelect
} }
fn entry(&self) -> &dyn TypeOptionDataEntry { fn entry(&self) -> &dyn TypeOptionDataEntry {
@ -277,7 +278,7 @@ impl MultiSelectTypeOptionBuilder {
impl TypeOptionBuilder for MultiSelectTypeOptionBuilder { impl TypeOptionBuilder for MultiSelectTypeOptionBuilder {
fn field_type(&self) -> FieldType { fn field_type(&self) -> FieldType {
self.0.field_type() FieldType::MultiSelect
} }
fn entry(&self) -> &dyn TypeOptionDataEntry { fn entry(&self) -> &dyn TypeOptionDataEntry {
@ -510,6 +511,7 @@ fn make_select_context_from(cell_rev: &Option<CellRevision>, options: &[SelectOp
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::entities::FieldType;
use crate::services::field::FieldBuilder; use crate::services::field::FieldBuilder;
use crate::services::field::{ use crate::services::field::{
MultiSelectTypeOption, MultiSelectTypeOptionBuilder, SelectOption, SelectOptionCellContentChangeset, MultiSelectTypeOption, MultiSelectTypeOptionBuilder, SelectOption, SelectOptionCellContentChangeset,
@ -614,10 +616,11 @@ mod tests {
field_rev: &FieldRevision, field_rev: &FieldRevision,
expected: Vec<SelectOption>, expected: Vec<SelectOption>,
) { ) {
let field_type: FieldType = field_rev.field_type_rev.into();
assert_eq!( assert_eq!(
expected, expected,
type_option type_option
.decode_cell_data(cell_data, &field_rev.field_type, field_rev) .decode_cell_data(cell_data, &field_type, field_rev)
.unwrap() .unwrap()
.parse::<SelectOptionCellData>() .parse::<SelectOptionCellData>()
.unwrap() .unwrap()
@ -631,10 +634,11 @@ mod tests {
field_rev: &FieldRevision, field_rev: &FieldRevision,
expected: Vec<SelectOption>, expected: Vec<SelectOption>,
) { ) {
let field_type: FieldType = field_rev.field_type_rev.into();
assert_eq!( assert_eq!(
expected, expected,
type_option type_option
.decode_cell_data(cell_data, &field_rev.field_type, field_rev) .decode_cell_data(cell_data, &field_type, field_rev)
.unwrap() .unwrap()
.parse::<SelectOptionCellData>() .parse::<SelectOptionCellData>()
.unwrap() .unwrap()

View File

@ -1,10 +1,10 @@
use crate::entities::{FieldType, GridTextFilter};
use crate::impl_type_option; use crate::impl_type_option;
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
use crate::services::row::{try_decode_cell_data, CellContentChangeset, CellDataOperation, DecodedCellData}; use crate::services::row::{try_decode_cell_data, CellContentChangeset, CellDataOperation, DecodedCellData};
use bytes::Bytes; use bytes::Bytes;
use flowy_derive::ProtoBuf; use flowy_derive::ProtoBuf;
use flowy_error::{FlowyError, FlowyResult}; use flowy_error::{FlowyError, FlowyResult};
use flowy_grid_data_model::entities::{FieldType, GridTextFilter};
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry}; use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -15,7 +15,7 @@ impl_builder_from_json_str_and_from_bytes!(RichTextTypeOptionBuilder, RichTextTy
impl TypeOptionBuilder for RichTextTypeOptionBuilder { impl TypeOptionBuilder for RichTextTypeOptionBuilder {
fn field_type(&self) -> FieldType { fn field_type(&self) -> FieldType {
self.0.field_type() FieldType::RichText
} }
fn entry(&self) -> &dyn TypeOptionDataEntry { fn entry(&self) -> &dyn TypeOptionDataEntry {
@ -71,10 +71,10 @@ impl CellDataOperation<String, GridTextFilter> for RichTextTypeOption {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::entities::FieldType;
use crate::services::field::FieldBuilder; use crate::services::field::FieldBuilder;
use crate::services::field::*; use crate::services::field::*;
use crate::services::row::CellDataOperation; use crate::services::row::CellDataOperation;
use flowy_grid_data_model::entities::FieldType;
#[test] #[test]
fn text_description_test() { fn text_description_test() {

View File

@ -1,3 +1,4 @@
use crate::entities::{FieldType, GridTextFilter};
use crate::impl_type_option; use crate::impl_type_option;
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
use crate::services::row::{CellContentChangeset, CellDataOperation, DecodedCellData, EncodedCellData}; use crate::services::row::{CellContentChangeset, CellDataOperation, DecodedCellData, EncodedCellData};
@ -5,7 +6,6 @@ use bytes::Bytes;
use fancy_regex::Regex; use fancy_regex::Regex;
use flowy_derive::ProtoBuf; use flowy_derive::ProtoBuf;
use flowy_error::{internal_error, FlowyError, FlowyResult}; use flowy_error::{internal_error, FlowyError, FlowyResult};
use flowy_grid_data_model::entities::{FieldType, GridTextFilter};
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry}; use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry};
use lazy_static::lazy_static; use lazy_static::lazy_static;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -18,7 +18,7 @@ impl_builder_from_json_str_and_from_bytes!(URLTypeOptionBuilder, URLTypeOption);
impl TypeOptionBuilder for URLTypeOptionBuilder { impl TypeOptionBuilder for URLTypeOptionBuilder {
fn field_type(&self) -> FieldType { fn field_type(&self) -> FieldType {
self.0.field_type() FieldType::URL
} }
fn entry(&self) -> &dyn TypeOptionDataEntry { fn entry(&self) -> &dyn TypeOptionDataEntry {
@ -126,10 +126,10 @@ lazy_static! {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::entities::FieldType;
use crate::services::field::FieldBuilder; use crate::services::field::FieldBuilder;
use crate::services::field::{URLCellData, URLTypeOption}; use crate::services::field::{URLCellData, URLTypeOption};
use crate::services::row::{CellDataOperation, EncodedCellData}; use crate::services::row::{CellDataOperation, EncodedCellData};
use flowy_grid_data_model::entities::FieldType;
use flowy_grid_data_model::revision::FieldRevision; use flowy_grid_data_model::revision::FieldRevision;
#[test] #[test]

View File

@ -1,24 +1,25 @@
use crate::entities::{
FieldType, GridCheckboxFilter, GridDateFilter, GridNumberFilter, GridSelectOptionFilter, GridTextFilter,
};
use crate::services::block_manager::GridBlockManager; use crate::services::block_manager::GridBlockManager;
use crate::services::grid_editor_task::GridServiceTaskScheduler; use crate::services::grid_editor_task::GridServiceTaskScheduler;
use crate::services::row::GridBlockSnapshot; use crate::services::row::GridBlockSnapshot;
use crate::services::tasks::{FilterTaskContext, Task, TaskContent}; use crate::services::tasks::{FilterTaskContext, Task, TaskContent};
use flowy_error::FlowyResult; use flowy_error::FlowyResult;
use flowy_grid_data_model::entities::{ use flowy_grid_data_model::revision::{CellRevision, FieldId, FieldRevision, RowRevision};
FieldType, GridCheckboxFilter, GridDateFilter, GridNumberFilter, GridSelectOptionFilter,
GridSettingChangesetParams, GridTextFilter,
};
use flowy_grid_data_model::revision::{FieldRevision, RowRevision};
use flowy_sync::client_grid::GridRevisionPad; use flowy_sync::client_grid::GridRevisionPad;
use flowy_sync::entities::grid::GridSettingChangesetParams;
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::Arc; use std::sync::Arc;
use tokio::sync::RwLock; use tokio::sync::RwLock;
pub(crate) struct GridFilterService { pub(crate) struct GridFilterService {
grid_id: String,
scheduler: Arc<dyn GridServiceTaskScheduler>, scheduler: Arc<dyn GridServiceTaskScheduler>,
grid_pad: Arc<RwLock<GridRevisionPad>>, grid_pad: Arc<RwLock<GridRevisionPad>>,
block_manager: Arc<GridBlockManager>, block_manager: Arc<GridBlockManager>,
filter_cache: Arc<RwLock<FilterCache>>, filter_cache: Arc<RwLock<FilterCache>>,
filter_result: Arc<RwLock<GridFilterResult>>, filter_result_cache: Arc<RwLock<FilterResultCache>>,
} }
impl GridFilterService { impl GridFilterService {
pub async fn new<S: GridServiceTaskScheduler>( pub async fn new<S: GridServiceTaskScheduler>(
@ -26,26 +27,38 @@ impl GridFilterService {
block_manager: Arc<GridBlockManager>, block_manager: Arc<GridBlockManager>,
scheduler: S, scheduler: S,
) -> Self { ) -> Self {
let grid_id = grid_pad.read().await.grid_id();
let filter_cache = Arc::new(RwLock::new(FilterCache::from_grid_pad(&grid_pad).await)); let filter_cache = Arc::new(RwLock::new(FilterCache::from_grid_pad(&grid_pad).await));
let filter_result = Arc::new(RwLock::new(GridFilterResult::default())); let filter_result_cache = Arc::new(RwLock::new(FilterResultCache::default()));
Self { Self {
grid_id,
grid_pad, grid_pad,
block_manager, block_manager,
scheduler: Arc::new(scheduler), scheduler: Arc::new(scheduler),
filter_cache, filter_cache,
filter_result, filter_result_cache,
} }
} }
pub async fn process(&self, task_context: FilterTaskContext) -> FlowyResult<()> { pub async fn process(&self, task_context: FilterTaskContext) -> FlowyResult<()> {
let mut filter_result = self.filter_result.write().await; let field_revs = self
for block in task_context.blocks { .grid_pad
for row_rev in block.row_revs { .read()
let row_filter_result = RowFilterResult::new(&row_rev); .await
.get_field_revs(None)?
.into_iter()
.map(|field_rev| (field_rev.id.clone(), field_rev))
.collect::<HashMap<String, Arc<FieldRevision>>>();
filter_result.insert(&row_rev.id, row_filter_result); let mut changes = vec![];
} for block in task_context.blocks {
block.row_revs.iter().for_each(|row_rev| {
if let Some(change) = filter_row(row_rev, &self.filter_cache, &self.filter_result_cache, &field_revs) {
changes.push(change);
}
});
} }
self.notify(changes).await;
Ok(()) Ok(())
} }
@ -86,7 +99,28 @@ impl GridFilterService {
task task
} }
async fn notify(&self, _changes: Vec<FilterResult>) {
// let notification = GridNotification {};
// send_dart_notification(grid_id, GridNotification::DidUpdateGrid)
// .payload(updated_field)
// .send();
}
} }
fn filter_row(
row_rev: &Arc<RowRevision>,
_filter_cache: &Arc<RwLock<FilterCache>>,
_filter_result_cache: &Arc<RwLock<FilterResultCache>>,
_field_revs: &HashMap<FieldId, Arc<FieldRevision>>,
) -> Option<FilterResult> {
let _filter_result = FilterResult::new(row_rev);
row_rev.cells.iter().for_each(|(_k, cell_rev)| {
let _cell_rev: &CellRevision = cell_rev;
});
todo!()
}
pub struct GridFilterChangeset { pub struct GridFilterChangeset {
insert_filter: Option<FilterId>, insert_filter: Option<FilterId>,
delete_filter: Option<FilterId>, delete_filter: Option<FilterId>,
@ -102,12 +136,12 @@ impl std::convert::From<&GridSettingChangesetParams> for GridFilterChangeset {
fn from(params: &GridSettingChangesetParams) -> Self { fn from(params: &GridSettingChangesetParams) -> Self {
let insert_filter = params.insert_filter.as_ref().map(|insert_filter_params| FilterId { let insert_filter = params.insert_filter.as_ref().map(|insert_filter_params| FilterId {
field_id: insert_filter_params.field_id.clone(), field_id: insert_filter_params.field_id.clone(),
field_type: insert_filter_params.field_type.clone(), field_type: insert_filter_params.field_type_rev.into(),
}); });
let delete_filter = params.delete_filter.as_ref().map(|delete_filter_params| FilterId { let delete_filter = params.delete_filter.as_ref().map(|delete_filter_params| FilterId {
field_id: delete_filter_params.filter_id.clone(), field_id: delete_filter_params.filter_id.clone(),
field_type: delete_filter_params.field_type.clone(), field_type: delete_filter_params.field_type_rev.into(),
}); });
GridFilterChangeset { GridFilterChangeset {
insert_filter, insert_filter,
@ -117,24 +151,26 @@ impl std::convert::From<&GridSettingChangesetParams> for GridFilterChangeset {
} }
#[derive(Default)] #[derive(Default)]
struct GridFilterResult { struct FilterResultCache {
rows: HashMap<String, RowFilterResult>, rows: HashMap<String, FilterResult>,
} }
impl GridFilterResult { impl FilterResultCache {
fn insert(&mut self, row_id: &str, result: RowFilterResult) { fn insert(&mut self, row_id: &str, result: FilterResult) {
self.rows.insert(row_id.to_owned(), result); self.rows.insert(row_id.to_owned(), result);
} }
} }
#[derive(Default)] #[derive(Default)]
struct RowFilterResult { struct FilterResult {
row_id: String,
cell_by_field_id: HashMap<String, bool>, cell_by_field_id: HashMap<String, bool>,
} }
impl RowFilterResult { impl FilterResult {
fn new(row_rev: &RowRevision) -> Self { fn new(row_rev: &RowRevision) -> Self {
Self { Self {
row_id: row_rev.id.clone(),
cell_by_field_id: row_rev.cells.iter().map(|(k, _)| (k.clone(), true)).collect(), cell_by_field_id: row_rev.cells.iter().map(|(k, _)| (k.clone(), true)).collect(),
} }
} }
@ -201,7 +237,8 @@ async fn reload_filter_cache(
None => {} None => {}
Some((_, field_rev)) => { Some((_, field_rev)) => {
let filter_id = FilterId::from(field_rev); let filter_id = FilterId::from(field_rev);
match &field_rev.field_type { let field_type: FieldType = field_rev.field_type_rev.into();
match &field_type {
FieldType::RichText => { FieldType::RichText => {
let _ = cache.text_filter.insert(filter_id, GridTextFilter::from(filter_rev)); let _ = cache.text_filter.insert(filter_id, GridTextFilter::from(filter_rev));
} }
@ -241,7 +278,7 @@ impl std::convert::From<&Arc<FieldRevision>> for FilterId {
fn from(rev: &Arc<FieldRevision>) -> Self { fn from(rev: &Arc<FieldRevision>) -> Self {
Self { Self {
field_id: rev.id.clone(), field_id: rev.id.clone(),
field_type: rev.field_type.clone(), field_type: rev.field_type_rev.into(),
} }
} }
} }

View File

@ -7,12 +7,13 @@ use crate::services::filter::{GridFilterChangeset, GridFilterService};
use crate::services::persistence::block_index::BlockIndexCache; use crate::services::persistence::block_index::BlockIndexCache;
use crate::services::row::*; use crate::services::row::*;
use crate::entities::*;
use bytes::Bytes; use bytes::Bytes;
use flowy_error::{ErrorCode, FlowyError, FlowyResult}; use flowy_error::{ErrorCode, FlowyError, FlowyResult};
use flowy_grid_data_model::entities::*;
use flowy_grid_data_model::revision::*; use flowy_grid_data_model::revision::*;
use flowy_revision::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; use flowy_revision::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder};
use flowy_sync::client_grid::{GridChangeset, GridRevisionPad, JsonDeserializer}; use flowy_sync::client_grid::{GridChangeset, GridRevisionPad, JsonDeserializer};
use flowy_sync::entities::grid::{FieldChangesetParams, GridSettingChangesetParams};
use flowy_sync::entities::revision::Revision; use flowy_sync::entities::revision::Revision;
use flowy_sync::errors::CollaborateResult; use flowy_sync::errors::CollaborateResult;
use flowy_sync::util::make_delta_from_revisions; use flowy_sync::util::make_delta_from_revisions;
@ -84,7 +85,7 @@ impl GridRevisionEditor {
grid_id, grid_id,
name: Some(field.name), name: Some(field.name),
desc: Some(field.desc), desc: Some(field.desc),
field_type: Some(field.field_type), field_type: Some(field.field_type.into()),
frozen: Some(field.frozen), frozen: Some(field.frozen),
visibility: Some(field.visibility), visibility: Some(field.visibility),
width: Some(field.width), width: Some(field.width),
@ -123,7 +124,8 @@ impl GridRevisionEditor {
let field_rev = result.unwrap(); let field_rev = result.unwrap();
let _ = self let _ = self
.modify(|grid| { .modify(|grid| {
let deserializer = TypeOptionJsonDeserializer(field_rev.field_type.clone()); let field_type = field_rev.field_type_rev.into();
let deserializer = TypeOptionJsonDeserializer(field_type);
let changeset = FieldChangesetParams { let changeset = FieldChangesetParams {
field_id: field_id.to_owned(), field_id: field_id.to_owned(),
grid_id: grid_id.to_owned(), grid_id: grid_id.to_owned(),
@ -161,7 +163,7 @@ impl GridRevisionEditor {
let field_id = params.field_id.clone(); let field_id = params.field_id.clone();
let json_deserializer = match self.grid_pad.read().await.get_field_rev(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()), None => return Err(ErrorCode::FieldDoesNotExist.into()),
Some((_, field_rev)) => TypeOptionJsonDeserializer(field_rev.field_type.clone()), Some((_, field_rev)) => TypeOptionJsonDeserializer(field_rev.field_type_rev.into()),
}; };
let _ = self let _ = self
@ -201,8 +203,9 @@ impl GridRevisionEditor {
// .get_cell_revs(block_ids, field_id, None) // .get_cell_revs(block_ids, field_id, None)
// .await?; // .await?;
let type_option_json_builder = |field_type: &FieldType| -> String { let type_option_json_builder = |field_type: &FieldTypeRevision| -> String {
return default_type_option_builder_from_type(field_type).entry().json_str(); let field_type: FieldType = field_type.into();
return default_type_option_builder_from_type(&field_type).entry().json_str();
}; };
let _ = self let _ = self
@ -229,19 +232,15 @@ impl GridRevisionEditor {
Some(field_rev) Some(field_rev)
} }
pub async fn get_field_revs<T>(&self, field_ids: Option<Vec<T>>) -> FlowyResult<Vec<Arc<FieldRevision>>> pub async fn get_field_revs(&self, field_ids: Option<Vec<String>>) -> FlowyResult<Vec<Arc<FieldRevision>>> {
where
T: Into<FieldOrder>,
{
if field_ids.is_none() { if field_ids.is_none() {
let field_revs = self.grid_pad.read().await.get_field_revs(None)?; let field_revs = self.grid_pad.read().await.get_field_revs(None)?;
return Ok(field_revs); return Ok(field_revs);
} }
let to_field_orders = |item: Vec<T>| item.into_iter().map(|data| data.into()).collect(); let field_ids = field_ids.unwrap_or_default();
let field_orders = field_ids.map_or(vec![], to_field_orders); let expected_len = field_ids.len();
let expected_len = field_orders.len(); let field_revs = self.grid_pad.read().await.get_field_revs(Some(field_ids))?;
let field_revs = self.grid_pad.read().await.get_field_revs(Some(field_orders))?;
if expected_len != 0 && field_revs.len() != expected_len { if expected_len != 0 && field_revs.len() != expected_len {
tracing::error!( tracing::error!(
"This is a bug. The len of the field_revs should equal to {}", "This is a bug. The len of the field_revs should equal to {}",
@ -304,7 +303,7 @@ impl GridRevisionEditor {
} }
pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult<()> { pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult<()> {
let field_revs = self.get_field_revs::<FieldOrder>(None).await?; let field_revs = self.get_field_revs(None).await?;
self.block_manager self.block_manager
.update_row(changeset, |row_rev| make_row_from_row_rev(&field_revs, row_rev)) .update_row(changeset, |row_rev| make_row_from_row_rev(&field_revs, row_rev))
.await .await
@ -319,7 +318,7 @@ impl GridRevisionEditor {
debug_assert_eq!(grid_block_snapshot.len(), 1); debug_assert_eq!(grid_block_snapshot.len(), 1);
if grid_block_snapshot.len() == 1 { if grid_block_snapshot.len() == 1 {
let snapshot = grid_block_snapshot.pop().unwrap(); let snapshot = grid_block_snapshot.pop().unwrap();
let field_revs = self.get_field_revs::<FieldOrder>(None).await?; let field_revs = self.get_field_revs(None).await?;
let rows = make_rows_from_row_revs(&field_revs, &snapshot.row_revs); let rows = make_rows_from_row_revs(&field_revs, &snapshot.row_revs);
Ok(rows.into()) Ok(rows.into())
} else { } else {
@ -331,7 +330,7 @@ impl GridRevisionEditor {
match self.block_manager.get_row_rev(row_id).await? { match self.block_manager.get_row_rev(row_id).await? {
None => Ok(None), None => Ok(None),
Some(row_rev) => { Some(row_rev) => {
let field_revs = self.get_field_revs::<FieldOrder>(None).await?; let field_revs = self.get_field_revs(None).await?;
let row_revs = vec![row_rev]; let row_revs = vec![row_rev];
let mut rows = make_rows_from_row_revs(&field_revs, &row_revs); let mut rows = make_rows_from_row_revs(&field_revs, &row_revs);
debug_assert!(rows.len() == 1); debug_assert!(rows.len() == 1);
@ -396,7 +395,7 @@ impl GridRevisionEditor {
cell_rev, cell_rev,
field_rev, field_rev,
)?); )?);
let field_revs = self.get_field_revs::<FieldOrder>(None).await?; let field_revs = self.get_field_revs(None).await?;
let cell_changeset = CellChangeset { let cell_changeset = CellChangeset {
grid_id, grid_id,
row_id, row_id,
@ -432,7 +431,11 @@ impl GridRevisionEditor {
pub async fn get_grid_data(&self) -> FlowyResult<Grid> { pub async fn get_grid_data(&self) -> FlowyResult<Grid> {
let pad_read_guard = self.grid_pad.read().await; let pad_read_guard = self.grid_pad.read().await;
let field_orders = pad_read_guard.get_field_orders(); let field_orders = pad_read_guard
.get_field_revs(None)?
.iter()
.map(FieldOrder::from)
.collect();
let mut block_orders = vec![]; let mut block_orders = vec![];
for block_rev in pad_read_guard.get_block_meta_revs() { for block_rev in pad_read_guard.get_block_meta_revs() {
let row_orders = self.block_manager.get_row_orders(&block_rev.block_id).await?; let row_orders = self.block_manager.get_row_orders(&block_rev.block_id).await?;

View File

@ -1,12 +1,11 @@
use crate::entities::FieldType;
use crate::services::field::*; use crate::services::field::*;
use bytes::Bytes; use bytes::Bytes;
use flowy_error::{internal_error, ErrorCode, FlowyError, FlowyResult}; use flowy_error::{internal_error, ErrorCode, FlowyError, FlowyResult};
use flowy_grid_data_model::entities::FieldType; use flowy_grid_data_model::revision::{CellRevision, FieldRevision};
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, GridFilterRevision};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::fmt::Formatter; use std::fmt::Formatter;
use std::str::FromStr; use std::str::FromStr;
use std::sync::Arc;
pub trait CellDataOperation<D, F> { pub trait CellDataOperation<D, F> {
fn decode_cell_data<T>( fn decode_cell_data<T>(
@ -115,14 +114,6 @@ impl TypeOptionCellData {
} }
} }
pub fn apply_cell_filter(
_filter_rev: Arc<GridFilterRevision>,
_field_rev: &FieldRevision,
_cell_rev: Option<CellRevision>,
) -> bool {
todo!()
}
/// The changeset will be deserialized into specific data base on the FieldType. /// The changeset will be deserialized into specific data base on the FieldType.
/// For example, it's String on FieldType::RichText, and SelectOptionChangeset on FieldType::SingleSelect /// For example, it's String on FieldType::RichText, and SelectOptionChangeset on FieldType::SingleSelect
pub fn apply_cell_data_changeset<C: Into<CellContentChangeset>, T: AsRef<FieldRevision>>( pub fn apply_cell_data_changeset<C: Into<CellContentChangeset>, T: AsRef<FieldRevision>>(
@ -131,7 +122,8 @@ pub fn apply_cell_data_changeset<C: Into<CellContentChangeset>, T: AsRef<FieldRe
field_rev: T, field_rev: T,
) -> Result<String, FlowyError> { ) -> Result<String, FlowyError> {
let field_rev = field_rev.as_ref(); let field_rev = field_rev.as_ref();
let s = match field_rev.field_type { let field_type = field_rev.field_type_rev.into();
let s = match field_type {
FieldType::RichText => RichTextTypeOption::from(field_rev).apply_changeset(changeset, cell_rev), FieldType::RichText => RichTextTypeOption::from(field_rev).apply_changeset(changeset, cell_rev),
FieldType::Number => NumberTypeOption::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::DateTime => DateTypeOption::from(field_rev).apply_changeset(changeset, cell_rev),
@ -141,14 +133,14 @@ pub fn apply_cell_data_changeset<C: Into<CellContentChangeset>, T: AsRef<FieldRe
FieldType::URL => URLTypeOption::from(field_rev).apply_changeset(changeset, cell_rev), FieldType::URL => URLTypeOption::from(field_rev).apply_changeset(changeset, cell_rev),
}?; }?;
Ok(TypeOptionCellData::new(s, field_rev.field_type.clone()).json()) Ok(TypeOptionCellData::new(s, field_type).json())
} }
pub fn decode_cell_data<T: TryInto<TypeOptionCellData>>(data: T, field_rev: &FieldRevision) -> DecodedCellData { pub fn decode_cell_data<T: TryInto<TypeOptionCellData>>(data: T, field_rev: &FieldRevision) -> DecodedCellData {
if let Ok(type_option_cell_data) = data.try_into() { if let Ok(type_option_cell_data) = data.try_into() {
let TypeOptionCellData { data, field_type } = type_option_cell_data; let TypeOptionCellData { data, field_type } = type_option_cell_data;
let to_field_type = &field_rev.field_type; let to_field_type = field_rev.field_type_rev.into();
match try_decode_cell_data(data, field_rev, &field_type, to_field_type) { match try_decode_cell_data(data, field_rev, &field_type, &to_field_type) {
Ok(cell_data) => cell_data, Ok(cell_data) => cell_data,
Err(e) => { Err(e) => {
tracing::error!("Decode cell data failed, {:?}", e); tracing::error!("Decode cell data failed, {:?}", e);
@ -170,25 +162,25 @@ pub fn try_decode_cell_data(
let get_cell_data = || { let get_cell_data = || {
let data = match t_field_type { let data = match t_field_type {
FieldType::RichText => field_rev FieldType::RichText => field_rev
.get_type_option_entry::<RichTextTypeOption>(t_field_type)? .get_type_option_entry::<RichTextTypeOption, _>(t_field_type)?
.decode_cell_data(encoded_data, s_field_type, field_rev), .decode_cell_data(encoded_data, s_field_type, field_rev),
FieldType::Number => field_rev FieldType::Number => field_rev
.get_type_option_entry::<NumberTypeOption>(t_field_type)? .get_type_option_entry::<NumberTypeOption, _>(t_field_type)?
.decode_cell_data(encoded_data, s_field_type, field_rev), .decode_cell_data(encoded_data, s_field_type, field_rev),
FieldType::DateTime => field_rev FieldType::DateTime => field_rev
.get_type_option_entry::<DateTypeOption>(t_field_type)? .get_type_option_entry::<DateTypeOption, _>(t_field_type)?
.decode_cell_data(encoded_data, s_field_type, field_rev), .decode_cell_data(encoded_data, s_field_type, field_rev),
FieldType::SingleSelect => field_rev FieldType::SingleSelect => field_rev
.get_type_option_entry::<SingleSelectTypeOption>(t_field_type)? .get_type_option_entry::<SingleSelectTypeOption, _>(t_field_type)?
.decode_cell_data(encoded_data, s_field_type, field_rev), .decode_cell_data(encoded_data, s_field_type, field_rev),
FieldType::MultiSelect => field_rev FieldType::MultiSelect => field_rev
.get_type_option_entry::<MultiSelectTypeOption>(t_field_type)? .get_type_option_entry::<MultiSelectTypeOption, _>(t_field_type)?
.decode_cell_data(encoded_data, s_field_type, field_rev), .decode_cell_data(encoded_data, s_field_type, field_rev),
FieldType::Checkbox => field_rev FieldType::Checkbox => field_rev
.get_type_option_entry::<CheckboxTypeOption>(t_field_type)? .get_type_option_entry::<CheckboxTypeOption, _>(t_field_type)?
.decode_cell_data(encoded_data, s_field_type, field_rev), .decode_cell_data(encoded_data, s_field_type, field_rev),
FieldType::URL => field_rev FieldType::URL => field_rev
.get_type_option_entry::<URLTypeOption>(t_field_type)? .get_type_option_entry::<URLTypeOption, _>(t_field_type)?
.decode_cell_data(encoded_data, s_field_type, field_rev), .decode_cell_data(encoded_data, s_field_type, field_rev),
}; };
Some(data) Some(data)

View File

@ -1,5 +1,5 @@
use crate::entities::{GridBlock, RepeatedGridBlock, Row, RowOrder};
use flowy_error::FlowyResult; use flowy_error::FlowyResult;
use flowy_grid_data_model::entities::{GridBlock, RepeatedGridBlock, Row, RowOrder};
use flowy_grid_data_model::revision::{FieldRevision, RowRevision}; use flowy_grid_data_model::revision::{FieldRevision, RowRevision};
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::Arc; use std::sync::Arc;

View File

@ -1,6 +1,5 @@
use flowy_grid_data_model::entities::{ use crate::entities::GridLayoutType;
CreateGridFilterParams, DeleteFilterParams, GridLayoutType, GridSettingChangesetParams, use flowy_sync::entities::grid::{CreateGridFilterParams, DeleteFilterParams, GridSettingChangesetParams};
};
pub struct GridSettingChangesetBuilder { pub struct GridSettingChangesetBuilder {
params: GridSettingChangesetParams, params: GridSettingChangesetParams,
@ -10,7 +9,7 @@ impl GridSettingChangesetBuilder {
pub fn new(grid_id: &str, layout_type: &GridLayoutType) -> Self { pub fn new(grid_id: &str, layout_type: &GridLayoutType) -> Self {
let params = GridSettingChangesetParams { let params = GridSettingChangesetParams {
grid_id: grid_id.to_string(), grid_id: grid_id.to_string(),
layout_type: layout_type.clone(), layout_type: layout_type.clone().into(),
insert_filter: None, insert_filter: None,
delete_filter: None, delete_filter: None,
insert_group: None, insert_group: None,

View File

@ -1,5 +1,5 @@
use crate::entities::FieldType;
use crate::services::field::*; use crate::services::field::*;
use flowy_grid_data_model::entities::FieldType;
use flowy_grid_data_model::revision::BuildGridContext; use flowy_grid_data_model::revision::BuildGridContext;
use flowy_sync::client_grid::GridBuilder; use flowy_sync::client_grid::GridBuilder;

View File

@ -1,8 +1,8 @@
use crate::grid::field_util::make_date_cell_string; use crate::grid::field_util::make_date_cell_string;
use crate::grid::script::EditorScript::*; use crate::grid::script::EditorScript::*;
use crate::grid::script::*; use crate::grid::script::*;
use flowy_grid::entities::{CellChangeset, FieldType};
use flowy_grid::services::field::{MultiSelectTypeOption, SelectOptionCellContentChangeset, SingleSelectTypeOption}; use flowy_grid::services::field::{MultiSelectTypeOption, SelectOptionCellContentChangeset, SingleSelectTypeOption};
use flowy_grid_data_model::entities::{CellChangeset, FieldType};
#[tokio::test] #[tokio::test]
async fn grid_cell_update() { async fn grid_cell_update() {
@ -17,7 +17,8 @@ async fn grid_cell_update() {
let mut scripts = vec![]; let mut scripts = vec![];
for (_, row_rev) in row_revs.iter().enumerate() { for (_, row_rev) in row_revs.iter().enumerate() {
for field_rev in field_revs { for field_rev in field_revs {
let data = match field_rev.field_type { let field_type: FieldType = field_rev.field_type_rev.into();
let data = match field_type {
FieldType::RichText => "".to_string(), FieldType::RichText => "".to_string(),
FieldType::Number => "123".to_string(), FieldType::Number => "123".to_string(),
FieldType::DateTime => make_date_cell_string("123"), FieldType::DateTime => make_date_cell_string("123"),

View File

@ -2,8 +2,8 @@ use crate::grid::field_util::*;
use crate::grid::script::EditorScript::*; use crate::grid::script::EditorScript::*;
use crate::grid::script::*; use crate::grid::script::*;
use flowy_grid::services::field::{SelectOption, SingleSelectTypeOption}; use flowy_grid::services::field::{SelectOption, SingleSelectTypeOption};
use flowy_grid_data_model::entities::FieldChangesetParams;
use flowy_grid_data_model::revision::TypeOptionDataEntry; use flowy_grid_data_model::revision::TypeOptionDataEntry;
use flowy_sync::entities::grid::FieldChangesetParams;
#[tokio::test] #[tokio::test]
async fn grid_create_field() { async fn grid_create_field() {

View File

@ -1,6 +1,6 @@
use flowy_grid::services::field::*; use flowy_grid::services::field::*;
use flowy_grid_data_model::entities::*; use flowy_grid::entities::*;
use flowy_grid_data_model::revision::*; use flowy_grid_data_model::revision::*;
pub fn create_text_field(grid_id: &str) -> (InsertFieldParams, FieldRevision) { pub fn create_text_field(grid_id: &str) -> (InsertFieldParams, FieldRevision) {
@ -12,7 +12,7 @@ pub fn create_text_field(grid_id: &str) -> (InsertFieldParams, FieldRevision) {
let cloned_field_rev = field_rev.clone(); let cloned_field_rev = field_rev.clone();
let type_option_data = field_rev let type_option_data = field_rev
.get_type_option_entry::<RichTextTypeOption>(&field_rev.field_type) .get_type_option_entry::<RichTextTypeOption, _>(field_rev.field_type_rev)
.unwrap() .unwrap()
.protobuf_bytes() .protobuf_bytes()
.to_vec(); .to_vec();
@ -21,7 +21,7 @@ pub fn create_text_field(grid_id: &str) -> (InsertFieldParams, FieldRevision) {
id: field_rev.id, id: field_rev.id,
name: field_rev.name, name: field_rev.name,
desc: field_rev.desc, desc: field_rev.desc,
field_type: field_rev.field_type, field_type: field_rev.field_type_rev.into(),
frozen: field_rev.frozen, frozen: field_rev.frozen,
visibility: field_rev.visibility, visibility: field_rev.visibility,
width: field_rev.width, width: field_rev.width,
@ -44,8 +44,9 @@ pub fn create_single_select_field(grid_id: &str) -> (InsertFieldParams, FieldRev
let field_rev = FieldBuilder::new(single_select).name("Name").visibility(true).build(); let field_rev = FieldBuilder::new(single_select).name("Name").visibility(true).build();
let cloned_field_rev = field_rev.clone(); let cloned_field_rev = field_rev.clone();
let field_type: FieldType = field_rev.field_type_rev.into();
let type_option_data = field_rev let type_option_data = field_rev
.get_type_option_entry::<SingleSelectTypeOption>(&field_rev.field_type) .get_type_option_entry::<SingleSelectTypeOption, _>(&field_type)
.unwrap() .unwrap()
.protobuf_bytes() .protobuf_bytes()
.to_vec(); .to_vec();
@ -54,7 +55,7 @@ pub fn create_single_select_field(grid_id: &str) -> (InsertFieldParams, FieldRev
id: field_rev.id, id: field_rev.id,
name: field_rev.name, name: field_rev.name,
desc: field_rev.desc, desc: field_rev.desc,
field_type: field_rev.field_type, field_type,
frozen: field_rev.frozen, frozen: field_rev.frozen,
visibility: field_rev.visibility, visibility: field_rev.visibility,
width: field_rev.width, width: field_rev.width,

View File

@ -1,6 +1,6 @@
use crate::grid::script::EditorScript::*; use crate::grid::script::EditorScript::*;
use crate::grid::script::*; use crate::grid::script::*;
use flowy_grid_data_model::entities::{CreateGridFilterPayload, TextFilterCondition}; use flowy_grid::entities::CreateGridFilterPayload;
#[tokio::test] #[tokio::test]
async fn grid_filter_create_test() { async fn grid_filter_create_test() {

View File

@ -3,11 +3,11 @@ use crate::grid::row_util::GridRowTestBuilder;
use crate::grid::script::EditorScript::*; use crate::grid::script::EditorScript::*;
use crate::grid::script::*; use crate::grid::script::*;
use chrono::NaiveDateTime; use chrono::NaiveDateTime;
use flowy_grid::entities::FieldType;
use flowy_grid::services::field::{ use flowy_grid::services::field::{
DateCellData, MultiSelectTypeOption, SingleSelectTypeOption, SELECTION_IDS_SEPARATOR, DateCellData, MultiSelectTypeOption, SingleSelectTypeOption, SELECTION_IDS_SEPARATOR,
}; };
use flowy_grid::services::row::{decode_cell_data, CreateRowRevisionBuilder}; use flowy_grid::services::row::{decode_cell_data, CreateRowRevisionBuilder};
use flowy_grid_data_model::entities::FieldType;
use flowy_grid_data_model::revision::RowMetaChangeset; use flowy_grid_data_model::revision::RowMetaChangeset;
#[tokio::test] #[tokio::test]
@ -75,7 +75,8 @@ async fn grid_row_add_cells_test() {
let mut test = GridEditorTest::new().await; let mut test = GridEditorTest::new().await;
let mut builder = CreateRowRevisionBuilder::new(&test.field_revs); let mut builder = CreateRowRevisionBuilder::new(&test.field_revs);
for field in &test.field_revs { for field in &test.field_revs {
match field.field_type { let field_type: FieldType = field.field_type_rev.into();
match field_type {
FieldType::RichText => { FieldType::RichText => {
builder.add_cell(&field.id, "hello world".to_owned()).unwrap(); builder.add_cell(&field.id, "hello world".to_owned()).unwrap();
} }
@ -122,7 +123,8 @@ async fn grid_row_add_date_cell_test() {
let mut date_field = None; let mut date_field = None;
let timestamp = 1647390674; let timestamp = 1647390674;
for field in &test.field_revs { for field in &test.field_revs {
if field.field_type == FieldType::DateTime { let field_type: FieldType = field.field_type_rev.into();
if field_type == FieldType::DateTime {
date_field = Some(field.clone()); date_field = Some(field.clone());
NaiveDateTime::from_timestamp(123, 0); NaiveDateTime::from_timestamp(123, 0);
// The data should not be empty // The data should not be empty

View File

@ -1,7 +1,7 @@
use crate::grid::script::GridEditorTest; use crate::grid::script::GridEditorTest;
use flowy_grid::entities::FieldType;
use flowy_grid::services::field::DateCellContentChangeset; use flowy_grid::services::field::DateCellContentChangeset;
use flowy_grid::services::row::{CreateRowRevisionBuilder, CreateRowRevisionPayload}; use flowy_grid::services::row::{CreateRowRevisionBuilder, CreateRowRevisionPayload};
use flowy_grid_data_model::entities::FieldType;
use flowy_grid_data_model::revision::FieldRevision; use flowy_grid_data_model::revision::FieldRevision;
use strum::EnumCount; use strum::EnumCount;
@ -61,7 +61,10 @@ impl<'a> GridRowTestBuilder<'a> {
self.test self.test
.field_revs .field_revs
.iter() .iter()
.find(|field_rev| &field_rev.field_type == field_type) .find(|field_rev| {
let t_field_type: FieldType = field_rev.field_type_rev.into();
&t_field_type == field_type
})
.unwrap() .unwrap()
.as_ref() .as_ref()
.clone() .clone()

View File

@ -4,7 +4,7 @@ use flowy_grid::services::field::*;
use flowy_grid::services::grid_editor::{GridPadBuilder, GridRevisionEditor}; use flowy_grid::services::grid_editor::{GridPadBuilder, GridRevisionEditor};
use flowy_grid::services::row::CreateRowRevisionPayload; use flowy_grid::services::row::CreateRowRevisionPayload;
use flowy_grid::services::setting::GridSettingChangesetBuilder; use flowy_grid::services::setting::GridSettingChangesetBuilder;
use flowy_grid_data_model::entities::*; use flowy_grid::entities::*;
use flowy_grid_data_model::revision::*; use flowy_grid_data_model::revision::*;
use flowy_revision::REVISION_WRITE_INTERVAL_IN_MILLIS; use flowy_revision::REVISION_WRITE_INTERVAL_IN_MILLIS;
use flowy_sync::client_grid::GridBuilder; use flowy_sync::client_grid::GridBuilder;
@ -15,6 +15,7 @@ use std::sync::Arc;
use std::time::Duration; use std::time::Duration;
use strum::EnumCount; use strum::EnumCount;
use tokio::time::sleep; use tokio::time::sleep;
use flowy_sync::entities::grid::{CreateGridFilterParams, DeleteFilterParams, FieldChangesetParams, GridSettingChangesetParams};
pub enum EditorScript { pub enum EditorScript {
CreateField { CreateField {
@ -106,7 +107,7 @@ impl GridEditorTest {
let view_data: Bytes = build_context.into(); let view_data: Bytes = build_context.into();
let test = ViewTest::new_grid_view(&sdk, view_data.to_vec()).await; 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 editor = sdk.grid_manager.open_grid(&test.view.id).await.unwrap();
let field_revs = editor.get_field_revs::<FieldOrder>(None).await.unwrap(); let field_revs = editor.get_field_revs(None).await.unwrap();
let block_meta_revs = editor.get_block_meta_revs().await.unwrap(); let block_meta_revs = editor.get_block_meta_revs().await.unwrap();
let row_revs = editor.grid_block_snapshots(None).await.unwrap().pop().unwrap().row_revs; let row_revs = editor.grid_block_snapshots(None).await.unwrap().pop().unwrap().row_revs;
assert_eq!(row_revs.len(), 3); assert_eq!(row_revs.len(), 3);
@ -148,12 +149,12 @@ impl GridEditorTest {
} }
self.editor.insert_field(params).await.unwrap(); self.editor.insert_field(params).await.unwrap();
self.field_revs = self.editor.get_field_revs::<FieldOrder>(None).await.unwrap(); self.field_revs = self.editor.get_field_revs(None).await.unwrap();
assert_eq!(self.field_count, self.field_revs.len()); assert_eq!(self.field_count, self.field_revs.len());
} }
EditorScript::UpdateField { changeset: change } => { EditorScript::UpdateField { changeset: change } => {
self.editor.update_field(change).await.unwrap(); self.editor.update_field(change).await.unwrap();
self.field_revs = self.editor.get_field_revs::<FieldOrder>(None).await.unwrap(); self.field_revs = self.editor.get_field_revs(None).await.unwrap();
} }
EditorScript::DeleteField { field_rev } => { EditorScript::DeleteField { field_rev } => {
if self.editor.contain_field(&field_rev.id).await { if self.editor.contain_field(&field_rev.id).await {
@ -161,17 +162,17 @@ impl GridEditorTest {
} }
self.editor.delete_field(&field_rev.id).await.unwrap(); self.editor.delete_field(&field_rev.id).await.unwrap();
self.field_revs = self.editor.get_field_revs::<FieldOrder>(None).await.unwrap(); self.field_revs = self.editor.get_field_revs(None).await.unwrap();
assert_eq!(self.field_count, self.field_revs.len()); assert_eq!(self.field_count, self.field_revs.len());
} }
EditorScript::AssertFieldCount(count) => { EditorScript::AssertFieldCount(count) => {
assert_eq!( assert_eq!(
self.editor.get_field_revs::<FieldOrder>(None).await.unwrap().len(), self.editor.get_field_revs(None).await.unwrap().len(),
count count
); );
} }
EditorScript::AssertFieldEqual { field_index, field_rev } => { EditorScript::AssertFieldEqual { field_index, field_rev } => {
let field_revs = self.editor.get_field_revs::<FieldOrder>(None).await.unwrap(); let field_revs = self.editor.get_field_revs(None).await.unwrap();
assert_eq!(field_revs[field_index].as_ref(), &field_rev); assert_eq!(field_revs[field_index].as_ref(), &field_rev);
} }
EditorScript::CreateBlock { block } => { EditorScript::CreateBlock { block } => {
@ -269,7 +270,7 @@ impl GridEditorTest {
EditorScript::DeleteGridTableFilter { filter_id ,field_type} => { EditorScript::DeleteGridTableFilter { filter_id ,field_type} => {
let layout_type = GridLayoutType::Table; let layout_type = GridLayoutType::Table;
let params = GridSettingChangesetBuilder::new(&self.grid_id, &layout_type) let params = GridSettingChangesetBuilder::new(&self.grid_id, &layout_type)
.delete_filter(DeleteFilterParams { filter_id, field_type }) .delete_filter(DeleteFilterParams { filter_id, field_type_rev: field_type.into() })
.build(); .build();
let _ = self.editor.update_grid_setting(params).await.unwrap(); let _ = self.editor.update_grid_setting(params).await.unwrap();
} }
@ -304,7 +305,10 @@ impl GridEditorTest {
pub fn text_field(&self) -> &FieldRevision { pub fn text_field(&self) -> &FieldRevision {
self.field_revs self.field_revs
.iter() .iter()
.filter(|field_rev| field_rev.field_type == FieldType::RichText) .filter(|field_rev| {
let t_field_type: FieldType = field_rev.field_type_rev.into();
t_field_type == FieldType::RichText
})
.collect::<Vec<_>>() .collect::<Vec<_>>()
.pop() .pop()
.unwrap() .unwrap()

View File

@ -3,7 +3,7 @@ use crate::{
request::{HttpRequestBuilder, ResponseMiddleware}, request::{HttpRequestBuilder, ResponseMiddleware},
}; };
use flowy_error::FlowyError; use flowy_error::FlowyError;
use flowy_sync::entities::text_block_info::{CreateTextBlockParams, ResetTextBlockParams, TextBlockId, TextBlockInfo}; use flowy_sync::entities::text_block::{CreateTextBlockParams, ResetTextBlockParams, TextBlockId, TextBlockInfo};
use flowy_text_block::BlockCloudService; use flowy_text_block::BlockCloudService;
use http_flowy::response::FlowyResponse; use http_flowy::response::FlowyResponse;
use lazy_static::lazy_static; use lazy_static::lazy_static;

View File

@ -1,5 +1,5 @@
use flowy_sync::{ use flowy_sync::{
entities::{folder_info::FolderInfo, text_block_info::TextBlockInfo}, entities::{folder::FolderInfo, text_block::TextBlockInfo},
errors::CollaborateError, errors::CollaborateError,
protobuf::{RepeatedRevision as RepeatedRevisionPB, Revision as RevisionPB}, protobuf::{RepeatedRevision as RepeatedRevisionPB, Revision as RevisionPB},
server_document::*, server_document::*,

View File

@ -6,7 +6,7 @@ use flowy_folder::event_map::FolderCouldServiceV1;
use flowy_sync::{ use flowy_sync::{
client_document::default::initial_quill_delta_string, client_document::default::initial_quill_delta_string,
entities::{ entities::{
text_block_info::{CreateTextBlockParams, ResetTextBlockParams, TextBlockId, TextBlockInfo}, text_block::{CreateTextBlockParams, ResetTextBlockParams, TextBlockId, TextBlockInfo},
ws_data::{ClientRevisionWSData, ClientRevisionWSDataType}, ws_data::{ClientRevisionWSData, ClientRevisionWSDataType},
}, },
errors::CollaborateError, errors::CollaborateError,

View File

@ -9,7 +9,7 @@ use flowy_error::{internal_error, FlowyResult};
use flowy_revision::{RevisionCloudService, RevisionManager, RevisionObjectBuilder, RevisionWebSocket}; use flowy_revision::{RevisionCloudService, RevisionManager, RevisionObjectBuilder, RevisionWebSocket};
use flowy_sync::entities::ws_data::ServerRevisionWSData; use flowy_sync::entities::ws_data::ServerRevisionWSData;
use flowy_sync::{ use flowy_sync::{
entities::{revision::Revision, text_block_info::TextBlockInfo}, entities::{revision::Revision, text_block::TextBlockInfo},
errors::CollaborateResult, errors::CollaborateResult,
util::make_delta_from_revisions, util::make_delta_from_revisions,
}; };

View File

@ -1,7 +1,7 @@
use crate::entities::{ExportData, ExportParams, ExportPayload}; use crate::entities::{ExportData, ExportParams, ExportPayload};
use crate::TextBlockManager; use crate::TextBlockManager;
use flowy_error::FlowyError; use flowy_error::FlowyError;
use flowy_sync::entities::text_block_info::{TextBlockDelta, TextBlockId}; use flowy_sync::entities::text_block::{TextBlockDelta, TextBlockId};
use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; use lib_dispatch::prelude::{data_result, AppData, Data, DataResult};
use std::convert::TryInto; use std::convert::TryInto;
use std::sync::Arc; use std::sync::Arc;

View File

@ -15,7 +15,7 @@ pub mod errors {
pub const TEXT_BLOCK_SYNC_INTERVAL_IN_MILLIS: u64 = 1000; pub const TEXT_BLOCK_SYNC_INTERVAL_IN_MILLIS: u64 = 1000;
use crate::errors::FlowyError; use crate::errors::FlowyError;
use flowy_sync::entities::text_block_info::{CreateTextBlockParams, ResetTextBlockParams, TextBlockId, TextBlockInfo}; use flowy_sync::entities::text_block::{CreateTextBlockParams, ResetTextBlockParams, TextBlockId, TextBlockInfo};
use lib_infra::future::FutureResult; use lib_infra::future::FutureResult;
pub trait BlockCloudService: Send + Sync { pub trait BlockCloudService: Send + Sync {

View File

@ -7,7 +7,7 @@ use flowy_revision::disk::SQLiteTextBlockRevisionPersistence;
use flowy_revision::{RevisionCloudService, RevisionManager, RevisionPersistence, RevisionWebSocket}; use flowy_revision::{RevisionCloudService, RevisionManager, RevisionPersistence, RevisionWebSocket};
use flowy_sync::entities::{ use flowy_sync::entities::{
revision::{md5, RepeatedRevision, Revision}, revision::{md5, RepeatedRevision, Revision},
text_block_info::{TextBlockDelta, TextBlockId}, text_block::{TextBlockDelta, TextBlockId},
ws_data::ServerRevisionWSData, ws_data::ServerRevisionWSData,
}; };
use lib_infra::future::FutureResult; use lib_infra::future::FutureResult;

4
shared-lib/Cargo.lock generated
View File

@ -447,17 +447,13 @@ name = "flowy-grid-data-model"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"bytes", "bytes",
"flowy-derive",
"flowy-error-code", "flowy-error-code",
"indexmap", "indexmap",
"lib-infra", "lib-infra",
"nanoid", "nanoid",
"protobuf",
"serde", "serde",
"serde_json", "serde_json",
"serde_repr", "serde_repr",
"strum",
"strum_macros",
] ]
[[package]] [[package]]

View File

@ -6,17 +6,14 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
flowy-derive = { path = "../flowy-derive" }
protobuf = {version = "2.18.0"}
bytes = "1.0" bytes = "1.0"
strum = "0.21"
strum_macros = "0.21"
serde = { version = "1.0", features = ["derive", "rc"] } serde = { version = "1.0", features = ["derive", "rc"] }
serde_json = {version = "1.0"} serde_json = {version = "1.0"}
serde_repr = "0.1" serde_repr = "0.1"
nanoid = "0.4.0" nanoid = "0.4.0"
flowy-error-code = { path = "../flowy-error-code"} flowy-error-code = { path = "../flowy-error-code"}
indexmap = {version = "1.8.1", features = ["serde"]} indexmap = {version = "1.8.1", features = ["serde"]}
[build-dependencies] [build-dependencies]
lib-infra = { path = "../lib-infra", features = ["protobuf_file_gen"] } lib-infra = { path = "../lib-infra", features = ["protobuf_file_gen"] }

View File

@ -1,2 +0,0 @@
# Check out the FlowyConfig (located in flowy_toml.rs) for more details.
proto_input = ["src/entities/",]

View File

@ -1,5 +0,0 @@
use lib_infra::code_gen;
fn main() {
code_gen::protobuf_file::gen(env!("CARGO_PKG_NAME"));
}

View File

@ -1,552 +0,0 @@
use crate::parser::NotEmptyStr;
use crate::revision::FieldRevision;
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use flowy_error_code::ErrorCode;
use serde_repr::*;
use std::sync::Arc;
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,
}
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<Arc<FieldRevision>> for Field {
fn from(field_rev: Arc<FieldRevision>) -> Self {
let field_rev = field_rev.as_ref().clone();
Field::from(field_rev)
}
}
#[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 }
}
}
impl std::convert::From<&Arc<FieldRevision>> for FieldOrder {
fn from(field_rev: &Arc<FieldRevision>) -> Self {
Self {
field_id: field_rev.id.clone(),
}
}
}
#[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: &Arc<FieldRevision>, index: usize) -> Self {
Self {
field: Field::from(field_rev.as_ref().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,
Hash,
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 {
(self.clone() as u8).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,379 +0,0 @@
use crate::entities::FieldOrder;
use crate::parser::NotEmptyStr;
use crate::revision::RowRevision;
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use flowy_error_code::ErrorCode;
#[derive(Debug, Clone, Default, ProtoBuf)]
pub struct Grid {
#[pb(index = 1)]
pub id: String,
#[pb(index = 2)]
pub field_orders: Vec<FieldOrder>,
#[pb(index = 3)]
pub blocks: Vec<GridBlock>,
}
#[derive(Debug, Default, Clone, ProtoBuf)]
pub struct RowOrder {
#[pb(index = 1)]
pub row_id: String,
#[pb(index = 2)]
pub block_id: String,
#[pb(index = 3)]
pub height: i32,
}
#[derive(Debug, Default, ProtoBuf)]
pub struct Row {
#[pb(index = 1)]
pub id: String,
#[pb(index = 2)]
pub height: i32,
}
#[derive(Debug, Default, ProtoBuf)]
pub struct OptionalRow {
#[pb(index = 1, one_of)]
pub row: Option<Row>,
}
#[derive(Debug, Default, ProtoBuf)]
pub struct RepeatedRow {
#[pb(index = 1)]
pub items: Vec<Row>,
}
impl std::convert::From<Vec<Row>> for RepeatedRow {
fn from(items: Vec<Row>) -> Self {
Self { items }
}
}
#[derive(Debug, Default, ProtoBuf)]
pub struct RepeatedGridBlock {
#[pb(index = 1)]
pub items: Vec<GridBlock>,
}
impl std::convert::From<Vec<GridBlock>> for RepeatedGridBlock {
fn from(items: Vec<GridBlock>) -> Self {
Self { items }
}
}
#[derive(Debug, Clone, Default, ProtoBuf)]
pub struct IndexRowOrder {
#[pb(index = 1)]
pub row_order: RowOrder,
#[pb(index = 2, one_of)]
pub index: Option<i32>,
}
#[derive(Debug, Default, ProtoBuf)]
pub struct UpdatedRowOrder {
#[pb(index = 1)]
pub row_order: RowOrder,
#[pb(index = 2)]
pub row: Row,
}
impl UpdatedRowOrder {
pub fn new(row_rev: &RowRevision, row: Row) -> Self {
Self {
row_order: RowOrder::from(row_rev),
row,
}
}
}
#[derive(Debug, Default, ProtoBuf)]
pub struct GridRowsChangeset {
#[pb(index = 1)]
pub block_id: String,
#[pb(index = 2)]
pub inserted_rows: Vec<IndexRowOrder>,
#[pb(index = 3)]
pub deleted_rows: Vec<RowOrder>,
#[pb(index = 4)]
pub updated_rows: Vec<UpdatedRowOrder>,
}
impl std::convert::From<RowOrder> for IndexRowOrder {
fn from(row_order: RowOrder) -> Self {
Self { row_order, index: None }
}
}
impl std::convert::From<&RowRevision> for IndexRowOrder {
fn from(row: &RowRevision) -> Self {
let row_order = RowOrder::from(row);
Self::from(row_order)
}
}
impl GridRowsChangeset {
pub fn insert(block_id: &str, inserted_rows: Vec<IndexRowOrder>) -> Self {
Self {
block_id: block_id.to_owned(),
inserted_rows,
deleted_rows: vec![],
updated_rows: vec![],
}
}
pub fn delete(block_id: &str, deleted_rows: Vec<RowOrder>) -> Self {
Self {
block_id: block_id.to_owned(),
inserted_rows: vec![],
deleted_rows,
updated_rows: vec![],
}
}
pub fn update(block_id: &str, updated_rows: Vec<UpdatedRowOrder>) -> Self {
Self {
block_id: block_id.to_owned(),
inserted_rows: vec![],
deleted_rows: vec![],
updated_rows,
}
}
}
#[derive(Debug, Clone, Default, ProtoBuf)]
pub struct GridBlock {
#[pb(index = 1)]
pub id: String,
#[pb(index = 2)]
pub row_orders: Vec<RowOrder>,
}
impl GridBlock {
pub fn new(block_id: &str, row_orders: Vec<RowOrder>) -> Self {
Self {
id: block_id.to_owned(),
row_orders,
}
}
}
#[derive(Debug, Default, ProtoBuf)]
pub struct Cell {
#[pb(index = 1)]
pub field_id: String,
#[pb(index = 2)]
pub data: Vec<u8>,
}
impl Cell {
pub fn new(field_id: &str, data: Vec<u8>) -> Self {
Self {
field_id: field_id.to_owned(),
data,
}
}
pub fn empty(field_id: &str) -> Self {
Self {
field_id: field_id.to_owned(),
data: vec![],
}
}
}
#[derive(Debug, Default, ProtoBuf)]
pub struct RepeatedCell {
#[pb(index = 1)]
pub items: Vec<Cell>,
}
impl std::ops::Deref for RepeatedCell {
type Target = Vec<Cell>;
fn deref(&self) -> &Self::Target {
&self.items
}
}
impl std::ops::DerefMut for RepeatedCell {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.items
}
}
impl std::convert::From<Vec<Cell>> for RepeatedCell {
fn from(items: Vec<Cell>) -> Self {
Self { items }
}
}
#[derive(ProtoBuf, Default)]
pub struct CreateGridPayload {
#[pb(index = 1)]
pub name: String,
}
#[derive(Clone, ProtoBuf, Default, Debug)]
pub struct GridId {
#[pb(index = 1)]
pub value: String,
}
impl AsRef<str> for GridId {
fn as_ref(&self) -> &str {
&self.value
}
}
#[derive(Clone, ProtoBuf, Default, Debug)]
pub struct GridBlockId {
#[pb(index = 1)]
pub value: String,
}
impl AsRef<str> for GridBlockId {
fn as_ref(&self) -> &str {
&self.value
}
}
impl std::convert::From<&str> for GridBlockId {
fn from(s: &str) -> Self {
GridBlockId { value: s.to_owned() }
}
}
#[derive(ProtoBuf, Default)]
pub struct CreateRowPayload {
#[pb(index = 1)]
pub grid_id: String,
#[pb(index = 2, one_of)]
pub start_row_id: Option<String>,
}
#[derive(Default)]
pub struct CreateRowParams {
pub grid_id: String,
pub start_row_id: Option<String>,
}
impl TryInto<CreateRowParams> for CreateRowPayload {
type Error = ErrorCode;
fn try_into(self) -> Result<CreateRowParams, Self::Error> {
let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
Ok(CreateRowParams {
grid_id: grid_id.0,
start_row_id: self.start_row_id,
})
}
}
#[derive(ProtoBuf, Default)]
pub struct QueryGridBlocksPayload {
#[pb(index = 1)]
pub grid_id: String,
#[pb(index = 2)]
pub block_ids: Vec<String>,
}
pub struct QueryGridBlocksParams {
pub grid_id: String,
pub block_ids: Vec<String>,
}
impl TryInto<QueryGridBlocksParams> for QueryGridBlocksPayload {
type Error = ErrorCode;
fn try_into(self) -> Result<QueryGridBlocksParams, Self::Error> {
let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
Ok(QueryGridBlocksParams {
grid_id: grid_id.0,
block_ids: self.block_ids,
})
}
}
#[derive(Debug, Clone, ProtoBuf_Enum)]
pub enum MoveItemType {
MoveField = 0,
MoveRow = 1,
}
impl std::default::Default for MoveItemType {
fn default() -> Self {
MoveItemType::MoveField
}
}
#[derive(Debug, Clone, Default, ProtoBuf)]
pub struct MoveItemPayload {
#[pb(index = 1)]
pub grid_id: String,
#[pb(index = 2)]
pub item_id: String,
#[pb(index = 3)]
pub from_index: i32,
#[pb(index = 4)]
pub to_index: i32,
#[pb(index = 5)]
pub ty: MoveItemType,
}
#[derive(Clone)]
pub struct MoveItemParams {
pub grid_id: String,
pub item_id: String,
pub from_index: i32,
pub to_index: i32,
pub ty: MoveItemType,
}
impl TryInto<MoveItemParams> for MoveItemPayload {
type Error = ErrorCode;
fn try_into(self) -> Result<MoveItemParams, Self::Error> {
let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
let item_id = NotEmptyStr::parse(self.item_id).map_err(|_| ErrorCode::InvalidData)?;
Ok(MoveItemParams {
grid_id: grid_id.0,
item_id: item_id.0,
from_index: self.from_index,
to_index: self.to_index,
ty: self.ty,
})
}
}
#[derive(Debug, Clone, Default, ProtoBuf)]
pub struct CellChangeset {
#[pb(index = 1)]
pub grid_id: String,
#[pb(index = 2)]
pub row_id: String,
#[pb(index = 3)]
pub field_id: String,
#[pb(index = 4, one_of)]
pub cell_content_changeset: Option<String>,
}

View File

@ -1,13 +0,0 @@
mod field;
mod grid;
mod grid_filter;
mod grid_group;
mod grid_setting;
mod grid_sort;
pub use field::*;
pub use grid::*;
pub use grid_filter::*;
pub use grid_group::*;
pub use grid_setting::*;
pub use grid_sort::*;

View File

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

View File

@ -1,4 +1,3 @@
use crate::entities::{CellChangeset, FieldType, RowOrder};
use crate::revision::GridSettingRevision; use crate::revision::GridSettingRevision;
use bytes::Bytes; use bytes::Bytes;
use indexmap::IndexMap; use indexmap::IndexMap;
@ -112,7 +111,8 @@ pub struct FieldRevision {
pub desc: String, pub desc: String,
pub field_type: FieldType, #[serde(rename = "field_type")]
pub field_type_rev: FieldTypeRevision,
pub frozen: bool, pub frozen: bool,
@ -140,13 +140,18 @@ impl AsRef<FieldRevision> for FieldRevision {
const DEFAULT_IS_PRIMARY: fn() -> bool = || false; const DEFAULT_IS_PRIMARY: fn() -> bool = || false;
impl FieldRevision { impl FieldRevision {
pub fn new(name: &str, desc: &str, field_type: FieldType, is_primary: bool) -> Self { pub fn new<T: Into<FieldTypeRevision>>(
let width = field_type.default_cell_width(); name: &str,
desc: &str,
field_type: T,
width: i32,
is_primary: bool,
) -> Self {
Self { Self {
id: gen_field_id(), id: gen_field_id(),
name: name.to_string(), name: name.to_string(),
desc: desc.to_string(), desc: desc.to_string(),
field_type, field_type_rev: field_type.into(),
frozen: false, frozen: false,
visibility: true, visibility: true,
width, width,
@ -159,26 +164,32 @@ impl FieldRevision {
where where
T: TypeOptionDataEntry + ?Sized, T: TypeOptionDataEntry + ?Sized,
{ {
self.type_options.insert(entry.field_type().type_id(), entry.json_str()); let id = self.field_type_rev.to_string();
self.type_options.insert(id, entry.json_str());
} }
pub fn get_type_option_entry<T: TypeOptionDataDeserializer>(&self, field_type: &FieldType) -> Option<T> { pub fn get_type_option_entry<T1: TypeOptionDataDeserializer, T2: Into<FieldTypeRevision>>(
self.type_options &self,
.get(&field_type.type_id()) field_type: T2,
.map(|s| T::from_json_str(s)) ) -> Option<T1> {
let field_type_rev = field_type.into();
let id = field_type_rev.to_string();
self.type_options.get(&id).map(|s| T1::from_json_str(s))
} }
pub fn insert_type_option_str(&mut self, field_type: &FieldType, json_str: String) { pub fn insert_type_option_str(&mut self, field_type: &FieldTypeRevision, json_str: String) {
self.type_options.insert(field_type.type_id(), json_str); let id = field_type.to_string();
self.type_options.insert(id, json_str);
} }
pub fn get_type_option_str(&self, field_type: &FieldType) -> Option<String> { pub fn get_type_option_str<T: Into<FieldTypeRevision>>(&self, field_type: T) -> Option<String> {
self.type_options.get(&field_type.type_id()).map(|s| s.to_owned()) let field_type_rev = field_type.into();
let id = field_type_rev.to_string();
self.type_options.get(&id).map(|s| s.to_owned())
} }
} }
pub trait TypeOptionDataEntry { pub trait TypeOptionDataEntry {
fn field_type(&self) -> FieldType;
fn json_str(&self) -> String; fn json_str(&self) -> String;
fn protobuf_bytes(&self) -> Bytes; fn protobuf_bytes(&self) -> Bytes;
} }
@ -187,7 +198,7 @@ pub trait TypeOptionDataDeserializer {
fn from_json_str(s: &str) -> Self; fn from_json_str(s: &str) -> Self;
fn from_protobuf_bytes(bytes: Bytes) -> Self; fn from_protobuf_bytes(bytes: Bytes) -> Self;
} }
pub type FieldId = String;
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct RowRevision { pub struct RowRevision {
pub id: String, pub id: String,
@ -196,7 +207,7 @@ pub struct RowRevision {
/// key: field id, /// key: field id,
/// value: CellMeta /// value: CellMeta
#[serde(with = "indexmap::serde_seq")] #[serde(with = "indexmap::serde_seq")]
pub cells: IndexMap<String, CellRevision>, pub cells: IndexMap<FieldId, CellRevision>,
pub height: i32, pub height: i32,
pub visibility: bool, pub visibility: bool,
} }
@ -212,51 +223,12 @@ impl RowRevision {
} }
} }
} }
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)] #[derive(Debug, Clone, Default)]
pub struct RowMetaChangeset { pub struct RowMetaChangeset {
pub row_id: String, pub row_id: String,
pub height: Option<i32>, pub height: Option<i32>,
pub visibility: Option<bool>, pub visibility: Option<bool>,
pub cell_by_field_id: HashMap<String, CellRevision>, pub cell_by_field_id: HashMap<FieldId, 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)] #[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
@ -298,3 +270,5 @@ impl std::convert::TryFrom<Bytes> for BuildGridContext {
Ok(ctx) Ok(ctx)
} }
} }
pub type FieldTypeRevision = u8;

View File

@ -1,4 +1,4 @@
use crate::entities::FieldType; use crate::revision::FieldTypeRevision;
use indexmap::IndexMap; use indexmap::IndexMap;
use nanoid::nanoid; use nanoid::nanoid;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -44,7 +44,7 @@ impl GridSettingRevision {
&mut self, &mut self,
layout: &GridLayoutRevision, layout: &GridLayoutRevision,
field_id: &str, field_id: &str,
field_type: &FieldType, field_type: &FieldTypeRevision,
) -> Option<&mut Vec<Arc<GridFilterRevision>>> { ) -> Option<&mut Vec<Arc<GridFilterRevision>>> {
self.filters self.filters
.get_mut(layout) .get_mut(layout)
@ -56,7 +56,7 @@ impl GridSettingRevision {
&self, &self,
layout: &GridLayoutRevision, layout: &GridLayoutRevision,
field_id: &str, field_id: &str,
field_type: &FieldType, field_type: &FieldTypeRevision,
) -> Option<Vec<Arc<GridFilterRevision>>> { ) -> Option<Vec<Arc<GridFilterRevision>>> {
self.filters self.filters
.get(layout) .get(layout)
@ -69,7 +69,7 @@ impl GridSettingRevision {
&mut self, &mut self,
layout: &GridLayoutRevision, layout: &GridLayoutRevision,
field_id: &str, field_id: &str,
field_type: &FieldType, field_type: &FieldTypeRevision,
filter_rev: GridFilterRevision, filter_rev: GridFilterRevision,
) { ) {
let filter_rev_map_by_field_id = self.filters.entry(layout.clone()).or_insert_with(IndexMap::new); let filter_rev_map_by_field_id = self.filters.entry(layout.clone()).or_insert_with(IndexMap::new);
@ -78,7 +78,7 @@ impl GridSettingRevision {
.or_insert_with(GridFilterRevisionMap::new); .or_insert_with(GridFilterRevisionMap::new);
filter_rev_map filter_rev_map
.entry(field_type.clone()) .entry(field_type.to_owned())
.or_insert_with(Vec::new) .or_insert_with(Vec::new)
.push(Arc::new(filter_rev)) .push(Arc::new(filter_rev))
} }
@ -88,7 +88,7 @@ impl GridSettingRevision {
#[serde(transparent)] #[serde(transparent)]
pub struct GridFilterRevisionMap { pub struct GridFilterRevisionMap {
#[serde(with = "indexmap::serde_seq")] #[serde(with = "indexmap::serde_seq")]
pub filter_by_field_type: IndexMap<FieldType, Vec<Arc<GridFilterRevision>>>, pub filter_by_field_type: IndexMap<FieldTypeRevision, Vec<Arc<GridFilterRevision>>>,
} }
impl GridFilterRevisionMap { impl GridFilterRevisionMap {
@ -98,7 +98,7 @@ impl GridFilterRevisionMap {
} }
impl std::ops::Deref for GridFilterRevisionMap { impl std::ops::Deref for GridFilterRevisionMap {
type Target = IndexMap<FieldType, Vec<Arc<GridFilterRevision>>>; type Target = IndexMap<FieldTypeRevision, Vec<Arc<GridFilterRevision>>>;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
&self.filter_by_field_type &self.filter_by_field_type

View File

@ -1,4 +1,4 @@
use crate::entities::folder_info::FolderDelta; use crate::entities::folder::FolderDelta;
use crate::util::make_delta_from_revisions; use crate::util::make_delta_from_revisions;
use crate::{ use crate::{
client_folder::{default_folder_delta, FolderPad}, client_folder::{default_folder_delta, FolderPad},

View File

@ -3,7 +3,7 @@ use crate::util::cal_diff;
use crate::{ use crate::{
client_folder::builder::FolderPadBuilder, client_folder::builder::FolderPadBuilder,
entities::{ entities::{
folder_info::FolderDelta, folder::FolderDelta,
revision::{md5, Revision}, revision::{md5, Revision},
}, },
errors::{CollaborateError, CollaborateResult}, errors::{CollaborateError, CollaborateResult},
@ -431,7 +431,7 @@ pub struct FolderChange {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
#![allow(clippy::all)] #![allow(clippy::all)]
use crate::{client_folder::folder_pad::FolderPad, entities::folder_info::FolderDelta}; use crate::{client_folder::folder_pad::FolderPad, entities::folder::FolderDelta};
use chrono::Utc; use chrono::Utc;
use flowy_folder_data_model::revision::{AppRevision, TrashRevision, ViewRevision, WorkspaceRevision}; use flowy_folder_data_model::revision::{AppRevision, TrashRevision, ViewRevision, WorkspaceRevision};

View File

@ -57,36 +57,3 @@ fn check_rows(fields: &[FieldRevision], rows: &[RowRevision]) -> CollaborateResu
} }
Ok(()) Ok(())
} }
#[cfg(test)]
mod tests {
use crate::client_grid::{make_block_meta_delta, make_grid_delta, GridBuilder};
use flowy_grid_data_model::entities::FieldType;
use flowy_grid_data_model::revision::{FieldRevision, GridBlockRevision, GridRevision};
use std::sync::Arc;
#[test]
fn create_default_grid_test() {
let grid_id = "1".to_owned();
let build_context = GridBuilder::default()
.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_rev = GridRevision {
grid_id,
fields: build_context.field_revs.into_iter().map(Arc::new).collect(),
blocks: build_context.blocks.into_iter().map(Arc::new).collect(),
setting: Default::default(),
};
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 _: GridBlockRevision = serde_json::from_str(&grid_block_meta_delta.to_str().unwrap()).unwrap();
}
}

View File

@ -1,13 +1,12 @@
use crate::entities::grid::{FieldChangesetParams, GridSettingChangesetParams};
use crate::entities::revision::{md5, RepeatedRevision, Revision}; use crate::entities::revision::{md5, RepeatedRevision, Revision};
use crate::errors::{internal_error, CollaborateError, CollaborateResult}; use crate::errors::{internal_error, CollaborateError, CollaborateResult};
use crate::util::{cal_diff, make_delta_from_revisions}; use crate::util::{cal_diff, make_delta_from_revisions};
use bytes::Bytes; use bytes::Bytes;
use flowy_grid_data_model::entities::{FieldChangesetParams, FieldOrder};
use flowy_grid_data_model::entities::{FieldType, GridSettingChangesetParams};
use flowy_grid_data_model::revision::{ use flowy_grid_data_model::revision::{
gen_block_id, gen_grid_filter_id, gen_grid_group_id, gen_grid_id, gen_grid_sort_id, FieldRevision, gen_block_id, gen_grid_filter_id, gen_grid_group_id, gen_grid_id, gen_grid_sort_id, FieldRevision,
GridBlockMetaRevision, GridBlockMetaRevisionChangeset, GridFilterRevision, GridGroupRevision, GridLayoutRevision, FieldTypeRevision, GridBlockMetaRevision, GridBlockMetaRevisionChangeset, GridFilterRevision, GridGroupRevision,
GridRevision, GridSettingRevision, GridSortRevision, GridLayoutRevision, GridRevision, GridSettingRevision, GridSortRevision,
}; };
use lib_infra::util::move_vec_element; use lib_infra::util::move_vec_element;
use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder};
@ -129,15 +128,17 @@ impl GridRevisionPad {
) )
} }
pub fn switch_to_field<B>( pub fn switch_to_field<B, T>(
&mut self, &mut self,
field_id: &str, field_id: &str,
field_type: FieldType, field_type: T,
type_option_json_builder: B, type_option_json_builder: B,
) -> CollaborateResult<Option<GridChangeset>> ) -> CollaborateResult<Option<GridChangeset>>
where where
B: FnOnce(&FieldType) -> String, B: FnOnce(&FieldTypeRevision) -> String,
T: Into<FieldTypeRevision>,
{ {
let field_type = field_type.into();
self.modify_grid(|grid_meta| { self.modify_grid(|grid_meta| {
// //
match grid_meta.fields.iter_mut().find(|field_rev| field_rev.id == field_id) { match grid_meta.fields.iter_mut().find(|field_rev| field_rev.id == field_id) {
@ -147,12 +148,12 @@ impl GridRevisionPad {
} }
Some(field_rev) => { Some(field_rev) => {
let mut_field_rev = Arc::make_mut(field_rev); let mut_field_rev = Arc::make_mut(field_rev);
if mut_field_rev.get_type_option_str(&field_type).is_none() { if mut_field_rev.get_type_option_str(field_type).is_none() {
let type_option_json = type_option_json_builder(&field_type); let type_option_json = type_option_json_builder(&field_type);
mut_field_rev.insert_type_option_str(&field_type, type_option_json); mut_field_rev.insert_type_option_str(&field_type, type_option_json);
} }
mut_field_rev.field_type = field_type; mut_field_rev.field_type_rev = field_type;
Ok(Some(())) Ok(Some(()))
} }
} }
@ -178,7 +179,7 @@ impl GridRevisionPad {
} }
if let Some(field_type) = changeset.field_type { if let Some(field_type) = changeset.field_type {
field.field_type = field_type; field.field_type_rev = field_type;
is_changed = Some(()) is_changed = Some(())
} }
@ -200,7 +201,7 @@ impl GridRevisionPad {
if let Some(type_option_data) = changeset.type_option_data { if let Some(type_option_data) = changeset.type_option_data {
match deserializer.deserialize(type_option_data) { match deserializer.deserialize(type_option_data) {
Ok(json_str) => { Ok(json_str) => {
let field_type = field.field_type.clone(); let field_type = field.field_type_rev;
field.insert_type_option_str(&field_type, json_str); field.insert_type_option_str(&field_type, json_str);
is_changed = Some(()) is_changed = Some(())
} }
@ -260,14 +261,10 @@ impl GridRevisionPad {
self.grid_rev.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> { pub fn get_field_revs(&self, field_ids: Option<Vec<String>>) -> CollaborateResult<Vec<Arc<FieldRevision>>> {
self.grid_rev.fields.iter().map(FieldOrder::from).collect() match field_ids {
}
pub fn get_field_revs(&self, field_orders: Option<Vec<FieldOrder>>) -> CollaborateResult<Vec<Arc<FieldRevision>>> {
match field_orders {
None => Ok(self.grid_rev.fields.clone()), None => Ok(self.grid_rev.fields.clone()),
Some(field_orders) => { Some(field_ids) => {
let field_by_field_id = self let field_by_field_id = self
.grid_rev .grid_rev
.fields .fields
@ -275,11 +272,11 @@ impl GridRevisionPad {
.map(|field| (&field.id, field)) .map(|field| (&field.id, field))
.collect::<HashMap<&String, &Arc<FieldRevision>>>(); .collect::<HashMap<&String, &Arc<FieldRevision>>>();
let fields = field_orders let fields = field_ids
.iter() .iter()
.flat_map(|field_order| match field_by_field_id.get(&field_order.field_id) { .flat_map(|field_id| match field_by_field_id.get(&field_id) {
None => { None => {
tracing::error!("Can't find the field with id: {}", field_order.field_id); tracing::error!("Can't find the field with id: {}", field_id);
None None
} }
Some(field) => Some((*field).clone()), Some(field) => Some((*field).clone()),
@ -364,7 +361,7 @@ impl GridRevisionPad {
if let Some(mut t_filter_revs) = if let Some(mut t_filter_revs) =
self.grid_rev self.grid_rev
.setting .setting
.get_filters(layout_ty, &field_rev.id, &field_rev.field_type) .get_filters(layout_ty, &field_rev.id, &field_rev.field_type_rev)
{ {
filter_revs.append(&mut t_filter_revs); filter_revs.append(&mut t_filter_revs);
} }
@ -380,7 +377,7 @@ impl GridRevisionPad {
) -> CollaborateResult<Option<GridChangeset>> { ) -> CollaborateResult<Option<GridChangeset>> {
self.modify_grid(|grid_rev| { self.modify_grid(|grid_rev| {
let mut is_changed = None; let mut is_changed = None;
let layout_rev: GridLayoutRevision = changeset.layout_type.into(); let layout_rev = changeset.layout_type;
if let Some(params) = changeset.insert_filter { if let Some(params) = changeset.insert_filter {
let filter_rev = GridFilterRevision { let filter_rev = GridFilterRevision {
@ -392,14 +389,14 @@ impl GridRevisionPad {
grid_rev grid_rev
.setting .setting
.insert_filter(&layout_rev, &params.field_id, &params.field_type, filter_rev); .insert_filter(&layout_rev, &params.field_id, &params.field_type_rev, filter_rev);
is_changed = Some(()) is_changed = Some(())
} }
if let Some(params) = changeset.delete_filter { if let Some(params) = changeset.delete_filter {
match grid_rev match grid_rev
.setting .setting
.get_mut_filters(&layout_rev, &params.filter_id, &params.field_type) .get_mut_filters(&layout_rev, &params.filter_id, &params.field_type_rev)
{ {
Some(filters) => { Some(filters) => {
filters.retain(|filter| filter.id != params.filter_id); filters.retain(|filter| filter.id != params.filter_id);

View File

@ -0,0 +1,57 @@
use flowy_grid_data_model::revision::{FieldTypeRevision, GridLayoutRevision};
pub struct GridSettingChangesetParams {
pub grid_id: String,
pub layout_type: GridLayoutRevision,
pub insert_filter: Option<CreateGridFilterParams>,
pub delete_filter: Option<DeleteFilterParams>,
pub insert_group: Option<CreateGridGroupParams>,
pub delete_group: Option<String>,
pub insert_sort: Option<CreateGridSortParams>,
pub delete_sort: Option<String>,
}
impl GridSettingChangesetParams {
pub fn is_filter_changed(&self) -> bool {
self.insert_filter.is_some() || self.delete_filter.is_some()
}
}
pub struct CreateGridFilterParams {
pub field_id: String,
pub field_type_rev: FieldTypeRevision,
pub condition: u8,
pub content: Option<String>,
}
pub struct DeleteFilterParams {
pub filter_id: String,
pub field_type_rev: FieldTypeRevision,
}
pub struct CreateGridGroupParams {
pub field_id: Option<String>,
pub sub_field_id: Option<String>,
}
pub struct CreateGridSortParams {
pub field_id: Option<String>,
}
#[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<FieldTypeRevision>,
pub frozen: Option<bool>,
pub visibility: Option<bool>,
pub width: Option<i32>,
pub type_option_data: Option<Vec<u8>>,
}

View File

@ -1,5 +1,6 @@
pub mod folder_info; pub mod folder;
pub mod grid;
pub mod parser; pub mod parser;
pub mod revision; pub mod revision;
pub mod text_block_info; pub mod text_block;
pub mod ws_data; pub mod ws_data;

View File

@ -1,5 +1,5 @@
use crate::{ use crate::{
entities::{text_block_info::TextBlockInfo, ws_data::ServerRevisionWSDataBuilder}, entities::{text_block::TextBlockInfo, ws_data::ServerRevisionWSDataBuilder},
errors::{internal_error, CollaborateError, CollaborateResult}, errors::{internal_error, CollaborateError, CollaborateResult},
protobuf::{ClientRevisionWSData, RepeatedRevision as RepeatedRevisionPB, Revision as RevisionPB}, protobuf::{ClientRevisionWSData, RepeatedRevision as RepeatedRevisionPB, Revision as RevisionPB},
server_document::document_pad::ServerDocument, server_document::document_pad::ServerDocument,

View File

@ -1,6 +1,6 @@
use crate::{ use crate::{
entities::{ entities::{
folder_info::{FolderDelta, FolderInfo}, folder::{FolderDelta, FolderInfo},
ws_data::ServerRevisionWSDataBuilder, ws_data::ServerRevisionWSDataBuilder,
}, },
errors::{internal_error, CollaborateError, CollaborateResult}, errors::{internal_error, CollaborateError, CollaborateResult},

View File

@ -1,4 +1,4 @@
use crate::{entities::folder_info::FolderDelta, errors::CollaborateError, synchronizer::RevisionSyncObject}; use crate::{entities::folder::FolderDelta, errors::CollaborateError, synchronizer::RevisionSyncObject};
use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta}; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta};
pub struct ServerFolder { pub struct ServerFolder {

View File

@ -1,8 +1,8 @@
use crate::{ use crate::{
entities::{ entities::{
folder_info::{FolderDelta, FolderInfo}, folder::{FolderDelta, FolderInfo},
revision::{RepeatedRevision, Revision}, revision::{RepeatedRevision, Revision},
text_block_info::TextBlockInfo, text_block::TextBlockInfo,
}, },
errors::{CollaborateError, CollaborateResult}, errors::{CollaborateError, CollaborateResult},
protobuf::{ protobuf::{