Merge pull request #446 from AppFlowy-IO/fix_data_error

Fix: grid data parser error
This commit is contained in:
Nathan.fooo 2022-04-11 15:37:27 +08:00 committed by GitHub
commit 6af78641d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
81 changed files with 2175 additions and 5526 deletions

View File

@ -65,7 +65,7 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
await _subscription?.cancel();
}
service.closeDocument(docId: view.id);
await service.closeDocument(docId: view.id);
return super.close();
}

View File

@ -1,8 +1,7 @@
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
import 'package:dartz/dartz.dart';
import 'package:flowy_sdk/dispatch/dispatch.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Cell;
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.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';
class CellService {
@ -14,7 +13,7 @@ class CellService {
required String rowId,
required String data,
}) {
final payload = CellMetaChangeset.create()
final payload = CellChangeset.create()
..gridId = gridId
..fieldId = fieldId
..rowId = rowId

View File

@ -3,7 +3,6 @@ import 'package:equatable/equatable.dart';
import 'package:flowy_sdk/dispatch/dispatch.dart';
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
class FieldService {

View File

@ -13,16 +13,15 @@ import 'grid_service.dart';
part 'grid_bloc.freezed.dart';
class GridBloc extends Bloc<GridEvent, GridState> {
final View view;
final GridService _gridService;
final GridListener _gridListener;
final GridFieldsListener _fieldListener;
GridBloc({required this.view})
GridBloc({required View view})
: _fieldListener = GridFieldsListener(gridId: view.id),
_gridService = GridService(),
_gridService = GridService(gridId: view.id),
_gridListener = GridListener(gridId: view.id),
super(GridState.initial()) {
super(GridState.initial(view.id)) {
on<GridEvent>(
(event, emit) async {
await event.map(
@ -31,7 +30,7 @@ class GridBloc extends Bloc<GridEvent, GridState> {
_startListening();
},
createRow: (_CreateRow value) {
_gridService.createRow(gridId: view.id);
_gridService.createRow();
},
updateDesc: (_Desc value) {},
didReceiveRowUpdate: (_DidReceiveRowUpdate value) {
@ -47,6 +46,7 @@ class GridBloc extends Bloc<GridEvent, GridState> {
@override
Future<void> close() async {
await _gridService.closeGrid();
await _fieldListener.stop();
await _gridListener.stop();
return super.close();
@ -86,7 +86,7 @@ class GridBloc extends Bloc<GridEvent, GridState> {
}
Future<void> _loadGrid(Emitter<GridState> emit) async {
final result = await _gridService.loadGrid(gridId: view.id);
final result = await _gridService.loadGrid();
return Future(
() => result.fold(
(grid) async => await _loadFields(grid, emit),
@ -96,7 +96,7 @@ class GridBloc extends Bloc<GridEvent, GridState> {
}
Future<void> _loadFields(Grid grid, Emitter<GridState> emit) async {
final result = await _gridService.getFields(gridId: grid.id, fieldOrders: grid.fieldOrders);
final result = await _gridService.getFields(fieldOrders: grid.fieldOrders);
return Future(
() => result.fold(
(fields) {
@ -162,17 +162,19 @@ class GridEvent with _$GridEvent {
@freezed
class GridState with _$GridState {
const factory GridState({
required String gridId,
required GridLoadingState loadingState,
required List<Field> fields,
required List<RowOrder> rows,
required Option<Grid> grid,
}) = _GridState;
factory GridState.initial() => GridState(
factory GridState.initial(String gridId) => GridState(
loadingState: const _Loading(),
fields: [],
rows: [],
grid: none(),
gridId: gridId,
);
}

View File

@ -1,27 +1,37 @@
import 'package:dartz/dartz.dart';
import 'package:flowy_sdk/dispatch/dispatch.dart';
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
import 'package:dartz/dartz.dart';
class GridService {
Future<Either<Grid, FlowyError>> loadGrid({required String gridId}) async {
final String gridId;
GridService({
required this.gridId,
});
Future<Either<Grid, FlowyError>> loadGrid() async {
await FolderEventSetLatestView(ViewId(value: gridId)).send();
final payload = GridId(value: gridId);
return GridEventGetGridData(payload).send();
}
Future<Either<Row, FlowyError>> createRow({required String gridId, Option<String>? startRowId}) {
Future<Either<Row, FlowyError>> createRow({Option<String>? startRowId}) {
CreateRowPayload payload = CreateRowPayload.create()..gridId = gridId;
startRowId?.fold(() => null, (id) => payload.startRowId = id);
return GridEventCreateRow(payload).send();
}
Future<Either<RepeatedField, FlowyError>> getFields({required String gridId, required List<FieldOrder> fieldOrders}) {
Future<Either<RepeatedField, FlowyError>> getFields({required List<FieldOrder> fieldOrders}) {
final payload = QueryFieldPayload.create()
..gridId = gridId
..fieldOrders = RepeatedFieldOrder(items: fieldOrders);
return GridEventGetFields(payload).send();
}
Future<Either<Unit, FlowyError>> closeGrid() {
final request = ViewId(value: gridId);
return FolderEventCloseView(request).send();
}
}

View File

@ -73,7 +73,7 @@ class FlowyGrid extends StatefulWidget {
class _FlowyGridState extends State<FlowyGrid> {
final _scrollController = GridScrollController();
// final _key = GlobalKey<SliverAnimatedListState>();
final _key = GlobalKey<SliverAnimatedListState>();
@override
void dispose() {
@ -83,8 +83,6 @@ class _FlowyGridState extends State<FlowyGrid> {
@override
Widget build(BuildContext context) {
final gridId = context.read<GridBloc>().view.id;
return BlocBuilder<GridBloc, GridState>(
buildWhen: (previous, current) => previous.fields != current.fields,
builder: (context, state) {
@ -103,9 +101,9 @@ class _FlowyGridState extends State<FlowyGrid> {
physics: StyledScrollPhysics(),
controller: _scrollController.verticalController,
slivers: [
_renderToolbar(gridId),
GridHeader(gridId: gridId, fields: List.from(state.fields)),
_renderRows(gridId: gridId, context: context),
_renderToolbar(state.gridId),
GridHeader(gridId: state.gridId, fields: List.from(state.fields)),
_renderRows(gridId: state.gridId, context: context),
const GridFooter(),
],
),

View File

@ -1,5 +1,5 @@
import 'package:app_flowy/workspace/application/grid/row/row_service.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show FieldType;
import 'package:flutter/widgets.dart';
import 'checkbox_cell.dart';
import 'date_cell.dart';

View File

@ -1,5 +1,6 @@
import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/application/grid/prelude.dart';
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flutter/widgets.dart';
@ -7,7 +8,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:table_calendar/table_calendar.dart';
import 'package:window_size/window_size.dart';
class DateCell extends StatefulWidget {
class DateCell extends GridCell {
final CellData cellData;
const DateCell({
@ -37,10 +38,16 @@ class _DateCellState extends State<DateCell> {
return SizedBox.expand(
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () => _CellCalendar.show(
context,
onSelected: (day) => context.read<DateCellBloc>().add(DateCellEvent.selectDay(day)),
),
onTap: () {
widget.setFocus(context, true);
_CellCalendar.show(
context,
onSelected: (day) {
widget.setFocus(context, false);
context.read<DateCellBloc>().add(DateCellEvent.selectDay(day));
},
);
},
child: MouseRegion(
opaque: false,
cursor: SystemMouseCursors.click,

View File

@ -6,7 +6,7 @@ import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/c
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class NumberCell extends StatefulWidget {
class NumberCell extends GridCell {
final CellData cellData;
const NumberCell({

View File

@ -1,12 +1,13 @@
import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/application/grid/prelude.dart';
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'extension.dart';
import 'selection_editor.dart';
class SingleSelectCell extends StatefulWidget {
class SingleSelectCell extends GridCell {
final CellData cellData;
const SingleSelectCell({
@ -37,7 +38,14 @@ class _SingleSelectCellState extends State<SingleSelectCell> {
return SizedBox.expand(
child: InkWell(
onTap: () {
SelectOptionCellEditor.show(context, state.cellData, state.options, state.selectedOptions);
widget.setFocus(context, true);
SelectOptionCellEditor.show(
context,
state.cellData,
state.options,
state.selectedOptions,
() => widget.setFocus(context, false),
);
},
child: Row(children: children),
),
@ -55,7 +63,7 @@ class _SingleSelectCellState extends State<SingleSelectCell> {
}
//----------------------------------------------------------------
class MultiSelectCell extends StatefulWidget {
class MultiSelectCell extends GridCell {
final CellData cellData;
const MultiSelectCell({
@ -86,11 +94,13 @@ class _MultiSelectCellState extends State<MultiSelectCell> {
return SizedBox.expand(
child: InkWell(
onTap: () {
widget.setFocus(context, true);
SelectOptionCellEditor.show(
context,
state.cellData,
state.options,
state.selectedOptions,
() => widget.setFocus(context, false),
);
},
child: Row(children: children),

View File

@ -28,11 +28,13 @@ class SelectOptionCellEditor extends StatelessWidget with FlowyOverlayDelegate {
final CellData cellData;
final List<SelectOption> options;
final List<SelectOption> selectedOptions;
final VoidCallback onDismissed;
const SelectOptionCellEditor({
required this.cellData,
required this.options,
required this.selectedOptions,
required this.onDismissed,
Key? key,
}) : super(key: key);
@ -67,12 +69,14 @@ class SelectOptionCellEditor extends StatelessWidget with FlowyOverlayDelegate {
CellData cellData,
List<SelectOption> options,
List<SelectOption> selectedOptions,
VoidCallback onDismissed,
) {
SelectOptionCellEditor.remove(context);
final editor = SelectOptionCellEditor(
cellData: cellData,
options: options,
selectedOptions: selectedOptions,
onDismissed: onDismissed,
);
//
@ -98,6 +102,9 @@ class SelectOptionCellEditor extends StatelessWidget with FlowyOverlayDelegate {
@override
bool asBarrier() => true;
@override
void didRemove() => onDismissed();
}
class _OptionList extends StatelessWidget {

View File

@ -10,7 +10,6 @@ import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_sdk/log.dart';
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/checkbox_type_option.pbserver.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/text_type_option.pb.dart';
import 'package:flutter/material.dart';

View File

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

View File

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

View File

@ -46,7 +46,7 @@ class _GridHeaderDelegate extends SliverPersistentHeaderDelegate {
@override
Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
return _GridHeaderWidget(gridId: gridId, fields: fields);
return _GridHeaderWidget(gridId: gridId, fields: fields, key: ObjectKey(fields));
}
@override

View File

@ -291,7 +291,7 @@ class GridEventGetCell {
}
class GridEventUpdateCell {
CellMetaChangeset request;
CellChangeset request;
GridEventUpdateCell(this.request);
Future<Either<Unit, FlowyError>> send() {

View File

@ -9,7 +9,9 @@ import 'dart:core' as $core;
import 'package:protobuf/protobuf.dart' as $pb;
import 'meta.pbenum.dart' as $0;
import 'grid.pbenum.dart';
export 'grid.pbenum.dart';
class Grid extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Grid', createEmptyInstance: create)
@ -79,7 +81,7 @@ class Field extends $pb.GeneratedMessage {
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id')
..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name')
..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc')
..e<$0.FieldType>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldType', $pb.PbFieldType.OE, defaultOrMaker: $0.FieldType.RichText, valueOf: $0.FieldType.valueOf, enumValues: $0.FieldType.values)
..e<FieldType>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldType', $pb.PbFieldType.OE, defaultOrMaker: FieldType.RichText, valueOf: FieldType.valueOf, enumValues: FieldType.values)
..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'frozen')
..aOB(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility')
..a<$core.int>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'width', $pb.PbFieldType.O3)
@ -91,7 +93,7 @@ class Field extends $pb.GeneratedMessage {
$core.String? id,
$core.String? name,
$core.String? desc,
$0.FieldType? fieldType,
FieldType? fieldType,
$core.bool? frozen,
$core.bool? visibility,
$core.int? width,
@ -169,9 +171,9 @@ class Field extends $pb.GeneratedMessage {
void clearDesc() => clearField(3);
@$pb.TagNumber(4)
$0.FieldType get fieldType => $_getN(3);
FieldType get fieldType => $_getN(3);
@$pb.TagNumber(4)
set fieldType($0.FieldType v) { setField(4, v); }
set fieldType(FieldType v) { setField(4, v); }
@$pb.TagNumber(4)
$core.bool hasFieldType() => $_has(3);
@$pb.TagNumber(4)
@ -266,7 +268,7 @@ class GetEditFieldContextPayload extends $pb.GeneratedMessage {
..oo(0, [2])
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId')
..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId')
..e<$0.FieldType>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldType', $pb.PbFieldType.OE, defaultOrMaker: $0.FieldType.RichText, valueOf: $0.FieldType.valueOf, enumValues: $0.FieldType.values)
..e<FieldType>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldType', $pb.PbFieldType.OE, defaultOrMaker: FieldType.RichText, valueOf: FieldType.valueOf, enumValues: FieldType.values)
..hasRequiredFields = false
;
@ -274,7 +276,7 @@ class GetEditFieldContextPayload extends $pb.GeneratedMessage {
factory GetEditFieldContextPayload({
$core.String? gridId,
$core.String? fieldId,
$0.FieldType? fieldType,
FieldType? fieldType,
}) {
final _result = create();
if (gridId != null) {
@ -331,9 +333,9 @@ class GetEditFieldContextPayload extends $pb.GeneratedMessage {
void clearFieldId() => clearField(2);
@$pb.TagNumber(3)
$0.FieldType get fieldType => $_getN(2);
FieldType get fieldType => $_getN(2);
@$pb.TagNumber(3)
set fieldType($0.FieldType v) { setField(3, v); }
set fieldType(FieldType v) { setField(3, v); }
@$pb.TagNumber(3)
$core.bool hasFieldType() => $_has(2);
@$pb.TagNumber(3)
@ -344,7 +346,7 @@ class EditFieldPayload extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'EditFieldPayload', createEmptyInstance: create)
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId')
..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId')
..e<$0.FieldType>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldType', $pb.PbFieldType.OE, defaultOrMaker: $0.FieldType.RichText, valueOf: $0.FieldType.valueOf, enumValues: $0.FieldType.values)
..e<FieldType>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldType', $pb.PbFieldType.OE, defaultOrMaker: FieldType.RichText, valueOf: FieldType.valueOf, enumValues: FieldType.values)
..hasRequiredFields = false
;
@ -352,7 +354,7 @@ class EditFieldPayload extends $pb.GeneratedMessage {
factory EditFieldPayload({
$core.String? gridId,
$core.String? fieldId,
$0.FieldType? fieldType,
FieldType? fieldType,
}) {
final _result = create();
if (gridId != null) {
@ -406,9 +408,9 @@ class EditFieldPayload extends $pb.GeneratedMessage {
void clearFieldId() => clearField(2);
@$pb.TagNumber(3)
$0.FieldType get fieldType => $_getN(2);
FieldType get fieldType => $_getN(2);
@$pb.TagNumber(3)
set fieldType($0.FieldType v) { setField(3, v); }
set fieldType(FieldType v) { setField(3, v); }
@$pb.TagNumber(3)
$core.bool hasFieldType() => $_has(2);
@$pb.TagNumber(3)
@ -1698,3 +1700,355 @@ class QueryGridBlocksPayload extends $pb.GeneratedMessage {
$core.List<GridBlockOrder> get blockOrders => $_getList(1);
}
enum FieldChangesetPayload_OneOfName {
name,
notSet
}
enum FieldChangesetPayload_OneOfDesc {
desc,
notSet
}
enum FieldChangesetPayload_OneOfFieldType {
fieldType,
notSet
}
enum FieldChangesetPayload_OneOfFrozen {
frozen,
notSet
}
enum FieldChangesetPayload_OneOfVisibility {
visibility,
notSet
}
enum FieldChangesetPayload_OneOfWidth {
width,
notSet
}
enum FieldChangesetPayload_OneOfTypeOptionData {
typeOptionData,
notSet
}
class FieldChangesetPayload extends $pb.GeneratedMessage {
static const $core.Map<$core.int, FieldChangesetPayload_OneOfName> _FieldChangesetPayload_OneOfNameByTag = {
3 : FieldChangesetPayload_OneOfName.name,
0 : FieldChangesetPayload_OneOfName.notSet
};
static const $core.Map<$core.int, FieldChangesetPayload_OneOfDesc> _FieldChangesetPayload_OneOfDescByTag = {
4 : FieldChangesetPayload_OneOfDesc.desc,
0 : FieldChangesetPayload_OneOfDesc.notSet
};
static const $core.Map<$core.int, FieldChangesetPayload_OneOfFieldType> _FieldChangesetPayload_OneOfFieldTypeByTag = {
5 : FieldChangesetPayload_OneOfFieldType.fieldType,
0 : FieldChangesetPayload_OneOfFieldType.notSet
};
static const $core.Map<$core.int, FieldChangesetPayload_OneOfFrozen> _FieldChangesetPayload_OneOfFrozenByTag = {
6 : FieldChangesetPayload_OneOfFrozen.frozen,
0 : FieldChangesetPayload_OneOfFrozen.notSet
};
static const $core.Map<$core.int, FieldChangesetPayload_OneOfVisibility> _FieldChangesetPayload_OneOfVisibilityByTag = {
7 : FieldChangesetPayload_OneOfVisibility.visibility,
0 : FieldChangesetPayload_OneOfVisibility.notSet
};
static const $core.Map<$core.int, FieldChangesetPayload_OneOfWidth> _FieldChangesetPayload_OneOfWidthByTag = {
8 : FieldChangesetPayload_OneOfWidth.width,
0 : FieldChangesetPayload_OneOfWidth.notSet
};
static const $core.Map<$core.int, FieldChangesetPayload_OneOfTypeOptionData> _FieldChangesetPayload_OneOfTypeOptionDataByTag = {
9 : FieldChangesetPayload_OneOfTypeOptionData.typeOptionData,
0 : FieldChangesetPayload_OneOfTypeOptionData.notSet
};
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FieldChangesetPayload', createEmptyInstance: create)
..oo(0, [3])
..oo(1, [4])
..oo(2, [5])
..oo(3, [6])
..oo(4, [7])
..oo(5, [8])
..oo(6, [9])
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId')
..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId')
..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name')
..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'desc')
..e<FieldType>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldType', $pb.PbFieldType.OE, defaultOrMaker: FieldType.RichText, valueOf: FieldType.valueOf, enumValues: FieldType.values)
..aOB(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'frozen')
..aOB(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility')
..a<$core.int>(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'width', $pb.PbFieldType.O3)
..a<$core.List<$core.int>>(9, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptionData', $pb.PbFieldType.OY)
..hasRequiredFields = false
;
FieldChangesetPayload._() : super();
factory FieldChangesetPayload({
$core.String? fieldId,
$core.String? gridId,
$core.String? name,
$core.String? desc,
FieldType? fieldType,
$core.bool? frozen,
$core.bool? visibility,
$core.int? width,
$core.List<$core.int>? typeOptionData,
}) {
final _result = create();
if (fieldId != null) {
_result.fieldId = fieldId;
}
if (gridId != null) {
_result.gridId = gridId;
}
if (name != null) {
_result.name = name;
}
if (desc != null) {
_result.desc = desc;
}
if (fieldType != null) {
_result.fieldType = fieldType;
}
if (frozen != null) {
_result.frozen = frozen;
}
if (visibility != null) {
_result.visibility = visibility;
}
if (width != null) {
_result.width = width;
}
if (typeOptionData != null) {
_result.typeOptionData = typeOptionData;
}
return _result;
}
factory FieldChangesetPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory FieldChangesetPayload.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
FieldChangesetPayload clone() => FieldChangesetPayload()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
FieldChangesetPayload copyWith(void Function(FieldChangesetPayload) updates) => super.copyWith((message) => updates(message as FieldChangesetPayload)) as FieldChangesetPayload; // ignore: deprecated_member_use
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static FieldChangesetPayload create() => FieldChangesetPayload._();
FieldChangesetPayload createEmptyInstance() => create();
static $pb.PbList<FieldChangesetPayload> createRepeated() => $pb.PbList<FieldChangesetPayload>();
@$core.pragma('dart2js:noInline')
static FieldChangesetPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<FieldChangesetPayload>(create);
static FieldChangesetPayload? _defaultInstance;
FieldChangesetPayload_OneOfName whichOneOfName() => _FieldChangesetPayload_OneOfNameByTag[$_whichOneof(0)]!;
void clearOneOfName() => clearField($_whichOneof(0));
FieldChangesetPayload_OneOfDesc whichOneOfDesc() => _FieldChangesetPayload_OneOfDescByTag[$_whichOneof(1)]!;
void clearOneOfDesc() => clearField($_whichOneof(1));
FieldChangesetPayload_OneOfFieldType whichOneOfFieldType() => _FieldChangesetPayload_OneOfFieldTypeByTag[$_whichOneof(2)]!;
void clearOneOfFieldType() => clearField($_whichOneof(2));
FieldChangesetPayload_OneOfFrozen whichOneOfFrozen() => _FieldChangesetPayload_OneOfFrozenByTag[$_whichOneof(3)]!;
void clearOneOfFrozen() => clearField($_whichOneof(3));
FieldChangesetPayload_OneOfVisibility whichOneOfVisibility() => _FieldChangesetPayload_OneOfVisibilityByTag[$_whichOneof(4)]!;
void clearOneOfVisibility() => clearField($_whichOneof(4));
FieldChangesetPayload_OneOfWidth whichOneOfWidth() => _FieldChangesetPayload_OneOfWidthByTag[$_whichOneof(5)]!;
void clearOneOfWidth() => clearField($_whichOneof(5));
FieldChangesetPayload_OneOfTypeOptionData whichOneOfTypeOptionData() => _FieldChangesetPayload_OneOfTypeOptionDataByTag[$_whichOneof(6)]!;
void clearOneOfTypeOptionData() => clearField($_whichOneof(6));
@$pb.TagNumber(1)
$core.String get fieldId => $_getSZ(0);
@$pb.TagNumber(1)
set fieldId($core.String v) { $_setString(0, v); }
@$pb.TagNumber(1)
$core.bool hasFieldId() => $_has(0);
@$pb.TagNumber(1)
void clearFieldId() => clearField(1);
@$pb.TagNumber(2)
$core.String get gridId => $_getSZ(1);
@$pb.TagNumber(2)
set gridId($core.String v) { $_setString(1, v); }
@$pb.TagNumber(2)
$core.bool hasGridId() => $_has(1);
@$pb.TagNumber(2)
void clearGridId() => clearField(2);
@$pb.TagNumber(3)
$core.String get name => $_getSZ(2);
@$pb.TagNumber(3)
set name($core.String v) { $_setString(2, v); }
@$pb.TagNumber(3)
$core.bool hasName() => $_has(2);
@$pb.TagNumber(3)
void clearName() => clearField(3);
@$pb.TagNumber(4)
$core.String get desc => $_getSZ(3);
@$pb.TagNumber(4)
set desc($core.String v) { $_setString(3, v); }
@$pb.TagNumber(4)
$core.bool hasDesc() => $_has(3);
@$pb.TagNumber(4)
void clearDesc() => clearField(4);
@$pb.TagNumber(5)
FieldType get fieldType => $_getN(4);
@$pb.TagNumber(5)
set fieldType(FieldType v) { setField(5, v); }
@$pb.TagNumber(5)
$core.bool hasFieldType() => $_has(4);
@$pb.TagNumber(5)
void clearFieldType() => clearField(5);
@$pb.TagNumber(6)
$core.bool get frozen => $_getBF(5);
@$pb.TagNumber(6)
set frozen($core.bool v) { $_setBool(5, v); }
@$pb.TagNumber(6)
$core.bool hasFrozen() => $_has(5);
@$pb.TagNumber(6)
void clearFrozen() => clearField(6);
@$pb.TagNumber(7)
$core.bool get visibility => $_getBF(6);
@$pb.TagNumber(7)
set visibility($core.bool v) { $_setBool(6, v); }
@$pb.TagNumber(7)
$core.bool hasVisibility() => $_has(6);
@$pb.TagNumber(7)
void clearVisibility() => clearField(7);
@$pb.TagNumber(8)
$core.int get width => $_getIZ(7);
@$pb.TagNumber(8)
set width($core.int v) { $_setSignedInt32(7, v); }
@$pb.TagNumber(8)
$core.bool hasWidth() => $_has(7);
@$pb.TagNumber(8)
void clearWidth() => clearField(8);
@$pb.TagNumber(9)
$core.List<$core.int> get typeOptionData => $_getN(8);
@$pb.TagNumber(9)
set typeOptionData($core.List<$core.int> v) { $_setBytes(8, v); }
@$pb.TagNumber(9)
$core.bool hasTypeOptionData() => $_has(8);
@$pb.TagNumber(9)
void clearTypeOptionData() => clearField(9);
}
enum CellChangeset_OneOfData {
data,
notSet
}
class CellChangeset extends $pb.GeneratedMessage {
static const $core.Map<$core.int, CellChangeset_OneOfData> _CellChangeset_OneOfDataByTag = {
4 : CellChangeset_OneOfData.data,
0 : CellChangeset_OneOfData.notSet
};
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CellChangeset', createEmptyInstance: create)
..oo(0, [4])
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId')
..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId')
..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId')
..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data')
..hasRequiredFields = false
;
CellChangeset._() : super();
factory CellChangeset({
$core.String? gridId,
$core.String? rowId,
$core.String? fieldId,
$core.String? data,
}) {
final _result = create();
if (gridId != null) {
_result.gridId = gridId;
}
if (rowId != null) {
_result.rowId = rowId;
}
if (fieldId != null) {
_result.fieldId = fieldId;
}
if (data != null) {
_result.data = data;
}
return _result;
}
factory CellChangeset.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory CellChangeset.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
CellChangeset clone() => CellChangeset()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
CellChangeset copyWith(void Function(CellChangeset) updates) => super.copyWith((message) => updates(message as CellChangeset)) as CellChangeset; // ignore: deprecated_member_use
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static CellChangeset create() => CellChangeset._();
CellChangeset createEmptyInstance() => create();
static $pb.PbList<CellChangeset> createRepeated() => $pb.PbList<CellChangeset>();
@$core.pragma('dart2js:noInline')
static CellChangeset getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<CellChangeset>(create);
static CellChangeset? _defaultInstance;
CellChangeset_OneOfData whichOneOfData() => _CellChangeset_OneOfDataByTag[$_whichOneof(0)]!;
void clearOneOfData() => clearField($_whichOneof(0));
@$pb.TagNumber(1)
$core.String get gridId => $_getSZ(0);
@$pb.TagNumber(1)
set gridId($core.String v) { $_setString(0, v); }
@$pb.TagNumber(1)
$core.bool hasGridId() => $_has(0);
@$pb.TagNumber(1)
void clearGridId() => clearField(1);
@$pb.TagNumber(2)
$core.String get rowId => $_getSZ(1);
@$pb.TagNumber(2)
set rowId($core.String v) { $_setString(1, v); }
@$pb.TagNumber(2)
$core.bool hasRowId() => $_has(1);
@$pb.TagNumber(2)
void clearRowId() => clearField(2);
@$pb.TagNumber(3)
$core.String get fieldId => $_getSZ(2);
@$pb.TagNumber(3)
set fieldId($core.String v) { $_setString(2, v); }
@$pb.TagNumber(3)
$core.bool hasFieldId() => $_has(2);
@$pb.TagNumber(3)
void clearFieldId() => clearField(3);
@$pb.TagNumber(4)
$core.String get data => $_getSZ(3);
@$pb.TagNumber(4)
set data($core.String v) { $_setString(3, v); }
@$pb.TagNumber(4)
$core.bool hasData() => $_has(3);
@$pb.TagNumber(4)
void clearData() => clearField(4);
}

View File

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

View File

@ -8,6 +8,21 @@
import 'dart:core' as $core;
import 'dart:convert' as $convert;
import 'dart:typed_data' as $typed_data;
@$core.Deprecated('Use fieldTypeDescriptor instead')
const FieldType$json = const {
'1': 'FieldType',
'2': const [
const {'1': 'RichText', '2': 0},
const {'1': 'Number', '2': 1},
const {'1': 'DateTime', '2': 2},
const {'1': 'SingleSelect', '2': 3},
const {'1': 'MultiSelect', '2': 4},
const {'1': 'Checkbox', '2': 5},
],
};
/// Descriptor for `FieldType`. Decode as a `google.protobuf.EnumDescriptorProto`.
final $typed_data.Uint8List fieldTypeDescriptor = $convert.base64Decode('CglGaWVsZFR5cGUSDAoIUmljaFRleHQQABIKCgZOdW1iZXIQARIMCghEYXRlVGltZRACEhAKDFNpbmdsZVNlbGVjdBADEg8KC011bHRpU2VsZWN0EAQSDAoIQ2hlY2tib3gQBQ==');
@$core.Deprecated('Use gridDescriptor instead')
const Grid$json = const {
'1': 'Grid',
@ -328,3 +343,46 @@ const QueryGridBlocksPayload$json = const {
/// Descriptor for `QueryGridBlocksPayload`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List queryGridBlocksPayloadDescriptor = $convert.base64Decode('ChZRdWVyeUdyaWRCbG9ja3NQYXlsb2FkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIyCgxibG9ja19vcmRlcnMYAiADKAsyDy5HcmlkQmxvY2tPcmRlclILYmxvY2tPcmRlcnM=');
@$core.Deprecated('Use fieldChangesetPayloadDescriptor instead')
const FieldChangesetPayload$json = const {
'1': 'FieldChangesetPayload',
'2': const [
const {'1': 'field_id', '3': 1, '4': 1, '5': 9, '10': 'fieldId'},
const {'1': 'grid_id', '3': 2, '4': 1, '5': 9, '10': 'gridId'},
const {'1': 'name', '3': 3, '4': 1, '5': 9, '9': 0, '10': 'name'},
const {'1': 'desc', '3': 4, '4': 1, '5': 9, '9': 1, '10': 'desc'},
const {'1': 'field_type', '3': 5, '4': 1, '5': 14, '6': '.FieldType', '9': 2, '10': 'fieldType'},
const {'1': 'frozen', '3': 6, '4': 1, '5': 8, '9': 3, '10': 'frozen'},
const {'1': 'visibility', '3': 7, '4': 1, '5': 8, '9': 4, '10': 'visibility'},
const {'1': 'width', '3': 8, '4': 1, '5': 5, '9': 5, '10': 'width'},
const {'1': 'type_option_data', '3': 9, '4': 1, '5': 12, '9': 6, '10': 'typeOptionData'},
],
'8': const [
const {'1': 'one_of_name'},
const {'1': 'one_of_desc'},
const {'1': 'one_of_field_type'},
const {'1': 'one_of_frozen'},
const {'1': 'one_of_visibility'},
const {'1': 'one_of_width'},
const {'1': 'one_of_type_option_data'},
],
};
/// Descriptor for `FieldChangesetPayload`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List fieldChangesetPayloadDescriptor = $convert.base64Decode('ChVGaWVsZENoYW5nZXNldFBheWxvYWQSGQoIZmllbGRfaWQYASABKAlSB2ZpZWxkSWQSFwoHZ3JpZF9pZBgCIAEoCVIGZ3JpZElkEhQKBG5hbWUYAyABKAlIAFIEbmFtZRIUCgRkZXNjGAQgASgJSAFSBGRlc2MSKwoKZmllbGRfdHlwZRgFIAEoDjIKLkZpZWxkVHlwZUgCUglmaWVsZFR5cGUSGAoGZnJvemVuGAYgASgISANSBmZyb3plbhIgCgp2aXNpYmlsaXR5GAcgASgISARSCnZpc2liaWxpdHkSFgoFd2lkdGgYCCABKAVIBVIFd2lkdGgSKgoQdHlwZV9vcHRpb25fZGF0YRgJIAEoDEgGUg50eXBlT3B0aW9uRGF0YUINCgtvbmVfb2ZfbmFtZUINCgtvbmVfb2ZfZGVzY0ITChFvbmVfb2ZfZmllbGRfdHlwZUIPCg1vbmVfb2ZfZnJvemVuQhMKEW9uZV9vZl92aXNpYmlsaXR5Qg4KDG9uZV9vZl93aWR0aEIZChdvbmVfb2ZfdHlwZV9vcHRpb25fZGF0YQ==');
@$core.Deprecated('Use cellChangesetDescriptor instead')
const CellChangeset$json = const {
'1': 'CellChangeset',
'2': const [
const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'},
const {'1': 'row_id', '3': 2, '4': 1, '5': 9, '10': 'rowId'},
const {'1': 'field_id', '3': 3, '4': 1, '5': 9, '10': 'fieldId'},
const {'1': 'data', '3': 4, '4': 1, '5': 9, '9': 0, '10': 'data'},
],
'8': const [
const {'1': 'one_of_data'},
],
};
/// Descriptor for `CellChangeset`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List cellChangesetDescriptor = $convert.base64Decode('Cg1DZWxsQ2hhbmdlc2V0EhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIVCgZyb3dfaWQYAiABKAlSBXJvd0lkEhkKCGZpZWxkX2lkGAMgASgJUgdmaWVsZElkEhQKBGRhdGEYBCABKAlIAFIEZGF0YUINCgtvbmVfb2ZfZGF0YQ==');

View File

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

View File

@ -1,217 +0,0 @@
///
// Generated code. Do not modify.
// source: meta.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package
import 'dart:core' as $core;
import 'dart:convert' as $convert;
import 'dart:typed_data' as $typed_data;
@$core.Deprecated('Use fieldTypeDescriptor instead')
const FieldType$json = const {
'1': 'FieldType',
'2': const [
const {'1': 'RichText', '2': 0},
const {'1': 'Number', '2': 1},
const {'1': 'DateTime', '2': 2},
const {'1': 'SingleSelect', '2': 3},
const {'1': 'MultiSelect', '2': 4},
const {'1': 'Checkbox', '2': 5},
],
};
/// Descriptor for `FieldType`. Decode as a `google.protobuf.EnumDescriptorProto`.
final $typed_data.Uint8List fieldTypeDescriptor = $convert.base64Decode('CglGaWVsZFR5cGUSDAoIUmljaFRleHQQABIKCgZOdW1iZXIQARIMCghEYXRlVGltZRACEhAKDFNpbmdsZVNlbGVjdBADEg8KC011bHRpU2VsZWN0EAQSDAoIQ2hlY2tib3gQBQ==');
@$core.Deprecated('Use gridMetaDescriptor instead')
const GridMeta$json = const {
'1': 'GridMeta',
'2': const [
const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'},
const {'1': 'fields', '3': 2, '4': 3, '5': 11, '6': '.FieldMeta', '10': 'fields'},
const {'1': 'blocks', '3': 3, '4': 3, '5': 11, '6': '.GridBlockMeta', '10': 'blocks'},
],
};
/// Descriptor for `GridMeta`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List gridMetaDescriptor = $convert.base64Decode('CghHcmlkTWV0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSIgoGZmllbGRzGAIgAygLMgouRmllbGRNZXRhUgZmaWVsZHMSJgoGYmxvY2tzGAMgAygLMg4uR3JpZEJsb2NrTWV0YVIGYmxvY2tz');
@$core.Deprecated('Use gridBlockMetaDescriptor instead')
const GridBlockMeta$json = const {
'1': 'GridBlockMeta',
'2': const [
const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'},
const {'1': 'start_row_index', '3': 2, '4': 1, '5': 5, '10': 'startRowIndex'},
const {'1': 'row_count', '3': 3, '4': 1, '5': 5, '10': 'rowCount'},
],
};
/// Descriptor for `GridBlockMeta`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List gridBlockMetaDescriptor = $convert.base64Decode('Cg1HcmlkQmxvY2tNZXRhEhkKCGJsb2NrX2lkGAEgASgJUgdibG9ja0lkEiYKD3N0YXJ0X3Jvd19pbmRleBgCIAEoBVINc3RhcnRSb3dJbmRleBIbCglyb3dfY291bnQYAyABKAVSCHJvd0NvdW50');
@$core.Deprecated('Use gridBlockMetaDataDescriptor instead')
const GridBlockMetaData$json = const {
'1': 'GridBlockMetaData',
'2': const [
const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'},
const {'1': 'rows', '3': 2, '4': 3, '5': 11, '6': '.RowMeta', '10': 'rows'},
],
};
/// Descriptor for `GridBlockMetaData`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List gridBlockMetaDataDescriptor = $convert.base64Decode('ChFHcmlkQmxvY2tNZXRhRGF0YRIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZBIcCgRyb3dzGAIgAygLMgguUm93TWV0YVIEcm93cw==');
@$core.Deprecated('Use fieldMetaDescriptor instead')
const FieldMeta$json = const {
'1': 'FieldMeta',
'2': const [
const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'},
const {'1': 'desc', '3': 3, '4': 1, '5': 9, '10': 'desc'},
const {'1': 'field_type', '3': 4, '4': 1, '5': 14, '6': '.FieldType', '10': 'fieldType'},
const {'1': 'frozen', '3': 5, '4': 1, '5': 8, '10': 'frozen'},
const {'1': 'visibility', '3': 6, '4': 1, '5': 8, '10': 'visibility'},
const {'1': 'width', '3': 7, '4': 1, '5': 5, '10': 'width'},
const {'1': 'type_options', '3': 8, '4': 3, '5': 11, '6': '.FieldMeta.TypeOptionsEntry', '10': 'typeOptions'},
],
'3': const [FieldMeta_TypeOptionsEntry$json],
};
@$core.Deprecated('Use fieldMetaDescriptor instead')
const FieldMeta_TypeOptionsEntry$json = const {
'1': 'TypeOptionsEntry',
'2': const [
const {'1': 'key', '3': 1, '4': 1, '5': 9, '10': 'key'},
const {'1': 'value', '3': 2, '4': 1, '5': 9, '10': 'value'},
],
'7': const {'7': true},
};
/// Descriptor for `FieldMeta`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List fieldMetaDescriptor = $convert.base64Decode('CglGaWVsZE1ldGESDgoCaWQYASABKAlSAmlkEhIKBG5hbWUYAiABKAlSBG5hbWUSEgoEZGVzYxgDIAEoCVIEZGVzYxIpCgpmaWVsZF90eXBlGAQgASgOMgouRmllbGRUeXBlUglmaWVsZFR5cGUSFgoGZnJvemVuGAUgASgIUgZmcm96ZW4SHgoKdmlzaWJpbGl0eRgGIAEoCFIKdmlzaWJpbGl0eRIUCgV3aWR0aBgHIAEoBVIFd2lkdGgSPgoMdHlwZV9vcHRpb25zGAggAygLMhsuRmllbGRNZXRhLlR5cGVPcHRpb25zRW50cnlSC3R5cGVPcHRpb25zGj4KEFR5cGVPcHRpb25zRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSFAoFdmFsdWUYAiABKAlSBXZhbHVlOgI4AQ==');
@$core.Deprecated('Use fieldChangesetPayloadDescriptor instead')
const FieldChangesetPayload$json = const {
'1': 'FieldChangesetPayload',
'2': const [
const {'1': 'field_id', '3': 1, '4': 1, '5': 9, '10': 'fieldId'},
const {'1': 'grid_id', '3': 2, '4': 1, '5': 9, '10': 'gridId'},
const {'1': 'name', '3': 3, '4': 1, '5': 9, '9': 0, '10': 'name'},
const {'1': 'desc', '3': 4, '4': 1, '5': 9, '9': 1, '10': 'desc'},
const {'1': 'field_type', '3': 5, '4': 1, '5': 14, '6': '.FieldType', '9': 2, '10': 'fieldType'},
const {'1': 'frozen', '3': 6, '4': 1, '5': 8, '9': 3, '10': 'frozen'},
const {'1': 'visibility', '3': 7, '4': 1, '5': 8, '9': 4, '10': 'visibility'},
const {'1': 'width', '3': 8, '4': 1, '5': 5, '9': 5, '10': 'width'},
const {'1': 'type_option_data', '3': 9, '4': 1, '5': 12, '9': 6, '10': 'typeOptionData'},
],
'8': const [
const {'1': 'one_of_name'},
const {'1': 'one_of_desc'},
const {'1': 'one_of_field_type'},
const {'1': 'one_of_frozen'},
const {'1': 'one_of_visibility'},
const {'1': 'one_of_width'},
const {'1': 'one_of_type_option_data'},
],
};
/// Descriptor for `FieldChangesetPayload`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List fieldChangesetPayloadDescriptor = $convert.base64Decode('ChVGaWVsZENoYW5nZXNldFBheWxvYWQSGQoIZmllbGRfaWQYASABKAlSB2ZpZWxkSWQSFwoHZ3JpZF9pZBgCIAEoCVIGZ3JpZElkEhQKBG5hbWUYAyABKAlIAFIEbmFtZRIUCgRkZXNjGAQgASgJSAFSBGRlc2MSKwoKZmllbGRfdHlwZRgFIAEoDjIKLkZpZWxkVHlwZUgCUglmaWVsZFR5cGUSGAoGZnJvemVuGAYgASgISANSBmZyb3plbhIgCgp2aXNpYmlsaXR5GAcgASgISARSCnZpc2liaWxpdHkSFgoFd2lkdGgYCCABKAVIBVIFd2lkdGgSKgoQdHlwZV9vcHRpb25fZGF0YRgJIAEoDEgGUg50eXBlT3B0aW9uRGF0YUINCgtvbmVfb2ZfbmFtZUINCgtvbmVfb2ZfZGVzY0ITChFvbmVfb2ZfZmllbGRfdHlwZUIPCg1vbmVfb2ZfZnJvemVuQhMKEW9uZV9vZl92aXNpYmlsaXR5Qg4KDG9uZV9vZl93aWR0aEIZChdvbmVfb2ZfdHlwZV9vcHRpb25fZGF0YQ==');
@$core.Deprecated('Use anyDataDescriptor instead')
const AnyData$json = const {
'1': 'AnyData',
'2': const [
const {'1': 'type_id', '3': 1, '4': 1, '5': 9, '10': 'typeId'},
const {'1': 'value', '3': 2, '4': 1, '5': 12, '10': 'value'},
],
};
/// Descriptor for `AnyData`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List anyDataDescriptor = $convert.base64Decode('CgdBbnlEYXRhEhcKB3R5cGVfaWQYASABKAlSBnR5cGVJZBIUCgV2YWx1ZRgCIAEoDFIFdmFsdWU=');
@$core.Deprecated('Use rowMetaDescriptor instead')
const RowMeta$json = const {
'1': 'RowMeta',
'2': const [
const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
const {'1': 'block_id', '3': 2, '4': 1, '5': 9, '10': 'blockId'},
const {'1': 'cells', '3': 3, '4': 3, '5': 11, '6': '.RowMeta.CellsEntry', '10': 'cells'},
const {'1': 'height', '3': 4, '4': 1, '5': 5, '10': 'height'},
const {'1': 'visibility', '3': 5, '4': 1, '5': 8, '10': 'visibility'},
],
'3': const [RowMeta_CellsEntry$json],
};
@$core.Deprecated('Use rowMetaDescriptor instead')
const RowMeta_CellsEntry$json = const {
'1': 'CellsEntry',
'2': const [
const {'1': 'key', '3': 1, '4': 1, '5': 9, '10': 'key'},
const {'1': 'value', '3': 2, '4': 1, '5': 11, '6': '.CellMeta', '10': 'value'},
],
'7': const {'7': true},
};
/// Descriptor for `RowMeta`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List rowMetaDescriptor = $convert.base64Decode('CgdSb3dNZXRhEg4KAmlkGAEgASgJUgJpZBIZCghibG9ja19pZBgCIAEoCVIHYmxvY2tJZBIpCgVjZWxscxgDIAMoCzITLlJvd01ldGEuQ2VsbHNFbnRyeVIFY2VsbHMSFgoGaGVpZ2h0GAQgASgFUgZoZWlnaHQSHgoKdmlzaWJpbGl0eRgFIAEoCFIKdmlzaWJpbGl0eRpDCgpDZWxsc0VudHJ5EhAKA2tleRgBIAEoCVIDa2V5Eh8KBXZhbHVlGAIgASgLMgkuQ2VsbE1ldGFSBXZhbHVlOgI4AQ==');
@$core.Deprecated('Use rowMetaChangesetDescriptor instead')
const RowMetaChangeset$json = const {
'1': 'RowMetaChangeset',
'2': const [
const {'1': 'row_id', '3': 1, '4': 1, '5': 9, '10': 'rowId'},
const {'1': 'height', '3': 2, '4': 1, '5': 5, '9': 0, '10': 'height'},
const {'1': 'visibility', '3': 3, '4': 1, '5': 8, '9': 1, '10': 'visibility'},
const {'1': 'cell_by_field_id', '3': 4, '4': 3, '5': 11, '6': '.RowMetaChangeset.CellByFieldIdEntry', '10': 'cellByFieldId'},
],
'3': const [RowMetaChangeset_CellByFieldIdEntry$json],
'8': const [
const {'1': 'one_of_height'},
const {'1': 'one_of_visibility'},
],
};
@$core.Deprecated('Use rowMetaChangesetDescriptor instead')
const RowMetaChangeset_CellByFieldIdEntry$json = const {
'1': 'CellByFieldIdEntry',
'2': const [
const {'1': 'key', '3': 1, '4': 1, '5': 9, '10': 'key'},
const {'1': 'value', '3': 2, '4': 1, '5': 11, '6': '.CellMeta', '10': 'value'},
],
'7': const {'7': true},
};
/// Descriptor for `RowMetaChangeset`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List rowMetaChangesetDescriptor = $convert.base64Decode('ChBSb3dNZXRhQ2hhbmdlc2V0EhUKBnJvd19pZBgBIAEoCVIFcm93SWQSGAoGaGVpZ2h0GAIgASgFSABSBmhlaWdodBIgCgp2aXNpYmlsaXR5GAMgASgISAFSCnZpc2liaWxpdHkSTQoQY2VsbF9ieV9maWVsZF9pZBgEIAMoCzIkLlJvd01ldGFDaGFuZ2VzZXQuQ2VsbEJ5RmllbGRJZEVudHJ5Ug1jZWxsQnlGaWVsZElkGksKEkNlbGxCeUZpZWxkSWRFbnRyeRIQCgNrZXkYASABKAlSA2tleRIfCgV2YWx1ZRgCIAEoCzIJLkNlbGxNZXRhUgV2YWx1ZToCOAFCDwoNb25lX29mX2hlaWdodEITChFvbmVfb2ZfdmlzaWJpbGl0eQ==');
@$core.Deprecated('Use cellMetaDescriptor instead')
const CellMeta$json = const {
'1': 'CellMeta',
'2': const [
const {'1': 'data', '3': 1, '4': 1, '5': 9, '10': 'data'},
],
};
/// Descriptor for `CellMeta`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List cellMetaDescriptor = $convert.base64Decode('CghDZWxsTWV0YRISCgRkYXRhGAEgASgJUgRkYXRh');
@$core.Deprecated('Use cellMetaChangesetDescriptor instead')
const CellMetaChangeset$json = const {
'1': 'CellMetaChangeset',
'2': const [
const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'},
const {'1': 'row_id', '3': 2, '4': 1, '5': 9, '10': 'rowId'},
const {'1': 'field_id', '3': 3, '4': 1, '5': 9, '10': 'fieldId'},
const {'1': 'data', '3': 4, '4': 1, '5': 9, '9': 0, '10': 'data'},
],
'8': const [
const {'1': 'one_of_data'},
],
};
/// Descriptor for `CellMetaChangeset`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List cellMetaChangesetDescriptor = $convert.base64Decode('ChFDZWxsTWV0YUNoYW5nZXNldBIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSFQoGcm93X2lkGAIgASgJUgVyb3dJZBIZCghmaWVsZF9pZBgDIAEoCVIHZmllbGRJZBIUCgRkYXRhGAQgASgJSABSBGRhdGFCDQoLb25lX29mX2RhdGE=');
@$core.Deprecated('Use buildGridContextDescriptor instead')
const BuildGridContext$json = const {
'1': 'BuildGridContext',
'2': const [
const {'1': 'field_metas', '3': 1, '4': 3, '5': 11, '6': '.FieldMeta', '10': 'fieldMetas'},
const {'1': 'block_meta', '3': 2, '4': 1, '5': 11, '6': '.GridBlockMeta', '10': 'blockMeta'},
const {'1': 'block_meta_data', '3': 3, '4': 1, '5': 11, '6': '.GridBlockMetaData', '10': 'blockMetaData'},
],
};
/// Descriptor for `BuildGridContext`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List buildGridContextDescriptor = $convert.base64Decode('ChBCdWlsZEdyaWRDb250ZXh0EisKC2ZpZWxkX21ldGFzGAEgAygLMgouRmllbGRNZXRhUgpmaWVsZE1ldGFzEi0KCmJsb2NrX21ldGEYAiABKAsyDi5HcmlkQmxvY2tNZXRhUglibG9ja01ldGESOgoPYmxvY2tfbWV0YV9kYXRhGAMgASgLMhIuR3JpZEJsb2NrTWV0YURhdGFSDWJsb2NrTWV0YURhdGE=');

View File

@ -1,9 +0,0 @@
///
// Generated code. Do not modify.
// source: meta.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package
export 'meta.pb.dart';

View File

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

View File

@ -919,6 +919,7 @@ dependencies = [
"flowy-error-code",
"lib-infra",
"log",
"nanoid",
"protobuf",
"serde",
"serde_json",
@ -926,7 +927,6 @@ dependencies = [
"strum",
"strum_macros",
"unicode-segmentation",
"uuid",
]
[[package]]
@ -946,10 +946,12 @@ dependencies = [
"flowy-revision",
"flowy-sync",
"flowy-test",
"indexmap",
"lazy_static",
"lib-dispatch",
"lib-infra",
"lib-ot",
"nanoid",
"protobuf",
"rayon",
"rust_decimal",
@ -961,7 +963,6 @@ dependencies = [
"strum_macros",
"tokio",
"tracing",
"uuid",
]
[[package]]
@ -971,14 +972,15 @@ dependencies = [
"bytes",
"flowy-derive",
"flowy-error-code",
"indexmap",
"lib-infra",
"nanoid",
"protobuf",
"serde",
"serde_json",
"serde_repr",
"strum",
"strum_macros",
"uuid",
]
[[package]]
@ -1006,6 +1008,7 @@ dependencies = [
"lib-infra",
"lib-ws",
"log",
"nanoid",
"parking_lot",
"protobuf",
"reqwest",
@ -1120,6 +1123,7 @@ dependencies = [
"lib-infra",
"lib-ot",
"log",
"nanoid",
"protobuf",
"quickcheck",
"quickcheck_macros",
@ -1188,6 +1192,7 @@ dependencies = [
"lib-dispatch",
"lib-infra",
"log",
"nanoid",
"once_cell",
"parking_lot",
"protobuf",
@ -1611,12 +1616,13 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
[[package]]
name = "indexmap"
version = "1.8.0"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223"
checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee"
dependencies = [
"autocfg",
"hashbrown",
"serde",
]
[[package]]
@ -1699,6 +1705,7 @@ dependencies = [
"futures-util",
"lazy_static",
"log",
"nanoid",
"paste",
"pin-project",
"protobuf",
@ -1708,7 +1715,6 @@ dependencies = [
"thread-id",
"tokio",
"tracing",
"uuid",
]
[[package]]
@ -1737,7 +1743,6 @@ dependencies = [
"tera",
"tokio",
"toml",
"uuid",
"walkdir",
]
@ -1962,6 +1967,15 @@ dependencies = [
"winapi",
]
[[package]]
name = "nanoid"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ffa00dec017b5b1a8b7cf5e2c008bfda1aa7e0697ac1508b491fdf2622fb4d8"
dependencies = [
"rand 0.8.4",
]
[[package]]
name = "native-tls"
version = "0.2.8"
@ -3584,7 +3598,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
dependencies = [
"getrandom 0.2.3",
"serde",
]
[[package]]

View File

@ -14,10 +14,9 @@ use crate::{
};
use bytes::Bytes;
use flowy_database::kv::KV;
use flowy_folder_data_model::entities::view::ViewDataType;
use flowy_folder_data_model::entities::view::{gen_view_id, ViewDataType};
use flowy_sync::entities::text_block_info::TextBlockId;
use futures::{FutureExt, StreamExt};
use lib_infra::uuid;
use std::{collections::HashSet, sync::Arc};
const LATEST_VIEW_ID: &str = "latest_view_id";
@ -151,7 +150,7 @@ impl ViewController {
}
}
let processor = self.get_data_processor_from_view_id(&params.value).await?;
let _ = processor.close_container(&params.value).await?;
let _ = processor.delete_container(&params.value).await?;
Ok(())
}
@ -171,7 +170,7 @@ impl ViewController {
thumbnail: view.thumbnail,
data_type: view.data_type,
data: delta_bytes.to_vec(),
view_id: uuid(),
view_id: gen_view_id(),
plugin_type: view.plugin_type,
};

View File

@ -25,7 +25,7 @@ rust_decimal = "1.8.1"
rusty-money = {version = "0.4.0", features = ["iso"]}
lazy_static = "1.4.0"
chrono = "0.4.19"
uuid = { version = "0.8", features = ["serde", "v4"] }
nanoid = "0.4.0"
bytes = { version = "1.0" }
diesel = {version = "1.4.8", features = ["sqlite"]}
dashmap = "4.0"
@ -34,6 +34,7 @@ rayon = "1.5"
serde = { version = "1.0", features = ["derive"] }
serde_json = {version = "1.0"}
serde_repr = "0.1"
indexmap = {version = "1.8.1", features = ["serde"]}
[dev-dependencies]
flowy-test = { path = "../flowy-test" }

View File

@ -227,10 +227,10 @@ pub(crate) async fn get_cell_handler(
#[tracing::instrument(level = "debug", skip_all, err)]
pub(crate) async fn update_cell_handler(
data: Data<CellMetaChangeset>,
data: Data<CellChangeset>,
manager: AppData<Arc<GridManager>>,
) -> Result<(), FlowyError> {
let changeset: CellMetaChangeset = data.into_inner();
let changeset: CellChangeset = data.into_inner();
let editor = manager.get_grid_editor(&changeset.grid_id)?;
let _ = editor.update_cell(changeset).await?;
Ok(())
@ -271,7 +271,7 @@ pub(crate) async fn select_option_changeset_handler(
field_meta.insert_type_option_entry(&*type_option);
let _ = editor.replace_field(field_meta).await?;
let changeset = CellMetaChangeset {
let changeset = CellChangeset {
grid_id: changeset.cell_identifier.grid_id,
row_id: changeset.cell_identifier.row_id,
field_id: changeset.cell_identifier.field_id,
@ -310,7 +310,7 @@ pub(crate) async fn select_option_cell_changeset_handler(
) -> Result<(), FlowyError> {
let params: SelectOptionCellChangesetParams = data.into_inner().try_into()?;
let editor = manager.get_grid_editor(&params.grid_id)?;
let changeset: CellMetaChangeset = params.into();
let changeset: CellChangeset = params.into();
let _ = editor.update_cell(changeset).await?;
Ok(())
}

View File

@ -92,7 +92,7 @@ pub enum GridEvent {
#[event(input = "CellIdentifierPayload", output = "Cell")]
GetCell = 70,
#[event(input = "CellMetaChangeset")]
#[event(input = "CellChangeset")]
UpdateCell = 71,
#[event(input = "SelectOptionCellChangesetPayload")]

View File

@ -30,7 +30,7 @@ macro_rules! impl_type_option {
($target: ident, $field_type:expr) => {
impl std::convert::From<&FieldMeta> for $target {
fn from(field_meta: &FieldMeta) -> $target {
match field_meta.get_type_option_entry::<$target>(Some($field_type)) {
match field_meta.get_type_option_entry::<$target>(&$field_type) {
None => $target::default(),
Some(target) => target,
}
@ -63,7 +63,7 @@ macro_rules! impl_type_option {
}
}
impl TypeOptionDataEntity for $target {
impl TypeOptionDataDeserializer for $target {
fn from_json_str(s: &str) -> $target {
match serde_json::from_str(s) {
Ok(obj) => obj,

View File

@ -73,7 +73,7 @@ impl GridManager {
self.get_or_create_grid_editor(grid_id).await
}
#[tracing::instrument(level = "trace", skip_all, fields(grid_id), err)]
#[tracing::instrument(level = "debug", skip_all, fields(grid_id), err)]
pub fn close_grid<T: AsRef<str>>(&self, grid_id: T) -> FlowyResult<()> {
let grid_id = grid_id.as_ref();
tracing::Span::current().record("grid_id", &grid_id);

View File

@ -8,7 +8,7 @@ use std::borrow::Cow;
use dashmap::DashMap;
use flowy_error::FlowyResult;
use flowy_grid_data_model::entities::{
CellMeta, CellMetaChangeset, CellNotificationData, FieldMeta, GridBlockMeta, GridBlockMetaChangeset,
CellChangeset, CellMeta, CellNotificationData, FieldMeta, GridBlockMeta, GridBlockMetaChangeset,
GridBlockOrderChangeset, IndexRowOrder, RowMeta, RowMetaChangeset, RowOrder,
};
use flowy_revision::disk::SQLiteGridBlockMetaRevisionPersistence;
@ -154,7 +154,7 @@ impl GridBlockMetaEditorManager {
Ok(changesets)
}
pub async fn update_cell(&self, changeset: CellMetaChangeset) -> FlowyResult<()> {
pub async fn update_cell(&self, changeset: CellChangeset) -> FlowyResult<()> {
let row_id = changeset.row_id.clone();
let editor = self.get_editor_from_row_id(&row_id).await?;
let row_changeset: RowMetaChangeset = changeset.clone().into();

View File

@ -1,6 +1,6 @@
use flowy_derive::ProtoBuf;
use flowy_error::ErrorCode;
use flowy_grid_data_model::parser::{NotEmptyStr, NotEmptyUuid};
use flowy_grid_data_model::parser::NotEmptyStr;
#[derive(ProtoBuf, Default)]
pub struct CreateSelectOptionPayload {
@ -51,9 +51,9 @@ impl TryInto<CellIdentifier> for CellIdentifierPayload {
type Error = ErrorCode;
fn try_into(self) -> Result<CellIdentifier, Self::Error> {
let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
let field_id = NotEmptyUuid::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
let row_id = NotEmptyUuid::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?;
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 row_id = NotEmptyStr::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?;
Ok(CellIdentifier {
grid_id: grid_id.0,
field_id: field_id.0,

View File

@ -1,7 +1,7 @@
use crate::services::field::type_options::*;
use bytes::Bytes;
use flowy_grid_data_model::entities::{Field, FieldMeta, FieldType, TypeOptionDataEntry};
use std::collections::HashMap;
use indexmap::IndexMap;
pub struct FieldBuilder {
field_meta: FieldMeta,
@ -34,7 +34,7 @@ impl FieldBuilder {
frozen: field.frozen,
visibility: field.visibility,
width: field.width,
type_options: HashMap::default(),
type_options: IndexMap::default(),
};
Self {
field_meta,

View File

@ -1,6 +1,6 @@
use flowy_derive::ProtoBuf;
use flowy_error::ErrorCode;
use flowy_grid_data_model::parser::NotEmptyUuid;
use flowy_grid_data_model::parser::NotEmptyStr;
#[derive(Debug, Clone, Default, ProtoBuf)]
pub struct FieldIdentifierPayload {
@ -20,8 +20,8 @@ impl TryInto<FieldIdentifier> for FieldIdentifierPayload {
type Error = ErrorCode;
fn try_into(self) -> Result<FieldIdentifier, Self::Error> {
let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
let field_id = NotEmptyUuid::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
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(FieldIdentifier {
grid_id: grid_id.0,
field_id: field_id.0,

View File

@ -4,7 +4,10 @@ use crate::services::row::{CellDataChangeset, CellDataOperation, TypeOptionCellD
use bytes::Bytes;
use flowy_derive::ProtoBuf;
use flowy_error::FlowyError;
use flowy_grid_data_model::entities::{CellMeta, FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry};
use flowy_grid_data_model::entities::{
CellMeta, FieldMeta, FieldType, TypeOptionDataDeserializer, TypeOptionDataEntry,
};
use serde::{Deserialize, Serialize};
use std::str::FromStr;

View File

@ -5,7 +5,10 @@ use chrono::format::strftime::StrftimeItems;
use chrono::NaiveDateTime;
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use flowy_error::FlowyError;
use flowy_grid_data_model::entities::{CellMeta, FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry};
use flowy_grid_data_model::entities::{
CellMeta, FieldMeta, FieldType, TypeOptionDataDeserializer, TypeOptionDataEntry,
};
use serde::{Deserialize, Serialize};
use std::str::FromStr;

View File

@ -2,7 +2,10 @@ use crate::impl_type_option;
use crate::services::row::{CellDataChangeset, CellDataOperation, TypeOptionCellData};
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use flowy_error::FlowyError;
use flowy_grid_data_model::entities::{CellMeta, FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry};
use flowy_grid_data_model::entities::{
CellMeta, FieldMeta, FieldType, TypeOptionDataDeserializer, TypeOptionDataEntry,
};
use lazy_static::lazy_static;
use rust_decimal::Decimal;

View File

@ -2,14 +2,14 @@ use crate::impl_type_option;
use crate::services::cell::{CellIdentifier, CellIdentifierPayload};
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
use crate::services::row::{CellDataChangeset, CellDataOperation, TypeOptionCellData};
use crate::services::util::*;
use bytes::Bytes;
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use flowy_error::{ErrorCode, FlowyError};
use flowy_grid_data_model::entities::{
CellMeta, CellMetaChangeset, FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry,
CellChangeset, CellMeta, FieldMeta, FieldType, TypeOptionDataDeserializer, TypeOptionDataEntry,
};
use flowy_grid_data_model::parser::NotEmptyUuid;
use flowy_grid_data_model::parser::NotEmptyStr;
use nanoid::nanoid;
use serde::{Deserialize, Serialize};
use std::str::FromStr;
@ -260,7 +260,7 @@ pub struct SelectOption {
impl SelectOption {
pub fn new(name: &str) -> Self {
SelectOption {
id: uuid(),
id: nanoid!(4),
name: name.to_owned(),
color: SelectOptionColor::default(),
}
@ -356,14 +356,14 @@ impl SelectOptionCellChangeset {
}
}
impl std::convert::From<SelectOptionCellChangesetParams> for CellMetaChangeset {
impl std::convert::From<SelectOptionCellChangesetParams> for CellChangeset {
fn from(params: SelectOptionCellChangesetParams) -> Self {
let changeset = SelectOptionCellChangeset {
insert_option_id: params.insert_option_id,
delete_option_id: params.delete_option_id,
};
let s = serde_json::to_string(&changeset).unwrap();
CellMetaChangeset {
CellChangeset {
grid_id: params.grid_id,
row_id: params.row_id,
field_id: params.field_id,
@ -376,13 +376,13 @@ impl TryInto<SelectOptionCellChangesetParams> for SelectOptionCellChangesetPaylo
type Error = ErrorCode;
fn try_into(self) -> Result<SelectOptionCellChangesetParams, Self::Error> {
let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
let row_id = NotEmptyUuid::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?;
let field_id = NotEmptyUuid::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
let row_id = NotEmptyStr::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?;
let field_id = NotEmptyStr::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
let insert_option_id = match self.insert_option_id {
None => None,
Some(insert_option_id) => Some(
NotEmptyUuid::parse(insert_option_id)
NotEmptyStr::parse(insert_option_id)
.map_err(|_| ErrorCode::OptionIdIsEmpty)?
.0,
),
@ -391,7 +391,7 @@ impl TryInto<SelectOptionCellChangesetParams> for SelectOptionCellChangesetPaylo
let delete_option_id = match self.delete_option_id {
None => None,
Some(delete_option_id) => Some(
NotEmptyUuid::parse(delete_option_id)
NotEmptyStr::parse(delete_option_id)
.map_err(|_| ErrorCode::OptionIdIsEmpty)?
.0,
),

View File

@ -4,7 +4,9 @@ use crate::services::row::{decode_cell_data, CellDataChangeset, CellDataOperatio
use bytes::Bytes;
use flowy_derive::ProtoBuf;
use flowy_error::FlowyError;
use flowy_grid_data_model::entities::{CellMeta, FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry};
use flowy_grid_data_model::entities::{
CellMeta, FieldMeta, FieldType, TypeOptionDataDeserializer, TypeOptionDataEntry,
};
use serde::{Deserialize, Serialize};
use std::str::FromStr;
@ -38,7 +40,7 @@ impl CellDataOperation for RichTextTypeOption {
|| type_option_cell_data.is_multi_select()
|| type_option_cell_data.is_number()
{
decode_cell_data(data, field_meta).unwrap_or_else(|_| "".to_owned())
decode_cell_data(data, field_meta, &type_option_cell_data.field_type).unwrap_or_else(|| "".to_owned())
} else {
type_option_cell_data.data
}

View File

@ -293,13 +293,15 @@ impl ClientGridEditor {
}
}
pub async fn update_cell(&self, mut changeset: CellMetaChangeset) -> FlowyResult<()> {
#[tracing::instrument(level = "trace", skip_all, err)]
pub async fn update_cell(&self, mut changeset: CellChangeset) -> FlowyResult<()> {
if changeset.data.as_ref().is_none() {
return Ok(());
}
let cell_data_changeset = changeset.data.unwrap();
let cell_meta = self.get_cell_meta(&changeset.row_id, &changeset.field_id).await?;
tracing::trace!("{}: {:?}", &changeset.field_id, cell_meta);
match self.pad.read().await.get_field(&changeset.field_id) {
None => {
let msg = format!("Field not found with id: {}", &changeset.field_id);
@ -431,7 +433,7 @@ impl ClientGridEditor {
if let Some(field_meta) = field_metas.pop() {
send_dart_notification(field_id, GridNotification::DidUpdateField)
.payload(field_meta)
.payload(Field::from(field_meta))
.send();
}

View File

@ -106,17 +106,43 @@ pub fn apply_cell_data_changeset<T: Into<CellDataChangeset>>(
FieldType::Checkbox => CheckboxTypeOption::from(field_meta).apply_changeset(changeset, cell_meta),
}
}
//
// #[tracing::instrument(level = "trace", skip(field_meta, data), fields(content), err)]
// pub fn decode_cell_data(data: String, field_meta: &FieldMeta, field_type: &FieldType) -> Result<String, FlowyError> {
// let s = match field_meta.field_type {
// FieldType::RichText => RichTextTypeOption::from(field_meta).decode_cell_data(data, field_meta),
// FieldType::Number => NumberTypeOption::from(field_meta).decode_cell_data(data, field_meta),
// FieldType::DateTime => DateTypeOption::from(field_meta).decode_cell_data(data, field_meta),
// FieldType::SingleSelect => SingleSelectTypeOption::from(field_meta).decode_cell_data(data, field_meta),
// FieldType::MultiSelect => MultiSelectTypeOption::from(field_meta).decode_cell_data(data, field_meta),
// FieldType::Checkbox => CheckboxTypeOption::from(field_meta).decode_cell_data(data, field_meta),
// };
// tracing::Span::current().record("content", &format!("{:?}: {}", field_meta.field_type, s).as_str());
// Ok(s)
// }
#[tracing::instrument(level = "trace", skip(field_meta, data), fields(content), err)]
pub fn decode_cell_data(data: String, field_meta: &FieldMeta) -> Result<String, FlowyError> {
let s = match field_meta.field_type {
FieldType::RichText => RichTextTypeOption::from(field_meta).decode_cell_data(data, field_meta),
FieldType::Number => NumberTypeOption::from(field_meta).decode_cell_data(data, field_meta),
FieldType::DateTime => DateTypeOption::from(field_meta).decode_cell_data(data, field_meta),
FieldType::SingleSelect => SingleSelectTypeOption::from(field_meta).decode_cell_data(data, field_meta),
FieldType::MultiSelect => MultiSelectTypeOption::from(field_meta).decode_cell_data(data, field_meta),
FieldType::Checkbox => CheckboxTypeOption::from(field_meta).decode_cell_data(data, field_meta),
#[tracing::instrument(level = "trace", skip(field_meta, data), fields(content))]
pub fn decode_cell_data(data: String, field_meta: &FieldMeta, field_type: &FieldType) -> Option<String> {
let s = match field_type {
FieldType::RichText => field_meta
.get_type_option_entry::<RichTextTypeOption>(field_type)?
.decode_cell_data(data, field_meta),
FieldType::Number => field_meta
.get_type_option_entry::<NumberTypeOption>(field_type)?
.decode_cell_data(data, field_meta),
FieldType::DateTime => field_meta
.get_type_option_entry::<DateTypeOption>(field_type)?
.decode_cell_data(data, field_meta),
FieldType::SingleSelect => field_meta
.get_type_option_entry::<SingleSelectTypeOption>(field_type)?
.decode_cell_data(data, field_meta),
FieldType::MultiSelect => field_meta
.get_type_option_entry::<MultiSelectTypeOption>(field_type)?
.decode_cell_data(data, field_meta),
FieldType::Checkbox => field_meta
.get_type_option_entry::<CheckboxTypeOption>(field_type)?
.decode_cell_data(data, field_meta),
};
tracing::Span::current().record("content", &format!("{:?}: {}", field_meta.field_type, s).as_str());
Ok(s)
Some(s)
}

View File

@ -1,8 +1,8 @@
use crate::services::row::apply_cell_data_changeset;
use crate::services::field::SelectOptionCellChangeset;
use crate::services::row::apply_cell_data_changeset;
use flowy_error::{FlowyError, FlowyResult};
use flowy_grid_data_model::entities::{CellMeta, FieldMeta, RowMeta, DEFAULT_ROW_HEIGHT};
use flowy_grid_data_model::entities::{gen_row_id, CellMeta, FieldMeta, RowMeta, DEFAULT_ROW_HEIGHT};
use indexmap::IndexMap;
use std::collections::HashMap;
pub struct CreateRowMetaBuilder<'a> {
@ -18,7 +18,7 @@ impl<'a> CreateRowMetaBuilder<'a> {
.collect::<HashMap<&String, &FieldMeta>>();
let payload = CreateRowMetaPayload {
row_id: uuid::Uuid::new_v4().to_string(),
row_id: gen_row_id(),
cell_by_field_id: Default::default(),
height: DEFAULT_ROW_HEIGHT,
visibility: true,
@ -90,7 +90,7 @@ pub fn make_row_meta_from_context(block_id: &str, payload: CreateRowMetaPayload)
pub struct CreateRowMetaPayload {
pub row_id: String,
pub cell_by_field_id: HashMap<String, CellMeta>,
pub cell_by_field_id: IndexMap<String, CellMeta>,
pub height: i32,
pub visibility: bool,
}

View File

@ -1,6 +1,6 @@
use flowy_derive::ProtoBuf;
use flowy_error::ErrorCode;
use flowy_grid_data_model::parser::NotEmptyUuid;
use flowy_grid_data_model::parser::NotEmptyStr;
#[derive(ProtoBuf, Default)]
pub struct RowIdentifierPayload {
@ -20,8 +20,8 @@ impl TryInto<RowIdentifier> for RowIdentifierPayload {
type Error = ErrorCode;
fn try_into(self) -> Result<RowIdentifier, Self::Error> {
let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
let row_id = NotEmptyUuid::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?;
let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
let row_id = NotEmptyStr::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?;
Ok(RowIdentifier {
grid_id: grid_id.0,

View File

@ -3,10 +3,7 @@ use flowy_error::FlowyResult;
use flowy_grid_data_model::entities::{
Cell, CellMeta, FieldMeta, GridBlock, GridBlockOrder, RepeatedGridBlock, Row, RowMeta, RowOrder,
};
use rayon::iter::{IntoParallelIterator, ParallelIterator};
use std::collections::HashMap;
use std::sync::Arc;
pub struct GridBlockSnapshot {
@ -34,28 +31,16 @@ pub fn make_cell_by_field_id(
cell_meta: CellMeta,
) -> Option<(String, Cell)> {
let field_meta = field_map.get(&field_id)?;
match decode_cell_data(cell_meta.data, field_meta) {
Ok(content) => {
let cell = Cell::new(&field_id, content);
Some((field_id, cell))
}
Err(e) => {
tracing::error!("{}", e);
None
}
}
let content = decode_cell_data(cell_meta.data, field_meta, &field_meta.field_type)?;
let cell = Cell::new(&field_id, content);
Some((field_id, cell))
}
#[allow(dead_code)]
pub fn make_cell(field_id: &str, field_meta: &FieldMeta, row_meta: &RowMeta) -> Option<Cell> {
let cell_meta = row_meta.cells.get(field_id)?.clone();
match decode_cell_data(cell_meta.data, field_meta) {
Ok(content) => Some(Cell::new(field_id, content)),
Err(e) => {
tracing::error!("{}", e);
None
}
}
let content = decode_cell_data(cell_meta.data, field_meta, &field_meta.field_type)?;
Some(Cell::new(field_id, content))
}
pub(crate) fn make_row_orders_from_row_metas(row_metas: &[Arc<RowMeta>]) -> Vec<RowOrder> {
@ -72,7 +57,7 @@ pub(crate) fn make_rows_from_row_metas(fields: &[FieldMeta], row_metas: &[Arc<Ro
let cell_by_field_id = row_meta
.cells
.clone()
.into_par_iter()
.into_iter()
.flat_map(|(field_id, cell_meta)| make_cell_by_field_id(&field_meta_map, field_id, cell_meta))
.collect::<HashMap<String, Cell>>();

View File

@ -1,3 +1 @@
pub fn uuid() -> String {
uuid::Uuid::new_v4().to_string()
}

View File

@ -6,7 +6,7 @@ use flowy_grid::services::field::{
};
use flowy_grid::services::row::{decode_cell_data, CreateRowMetaBuilder};
use flowy_grid_data_model::entities::{
CellMetaChangeset, FieldChangesetParams, FieldType, GridBlockMeta, GridBlockMetaChangeset, RowMetaChangeset,
CellChangeset, FieldChangesetParams, FieldType, GridBlockMeta, GridBlockMetaChangeset, RowMetaChangeset,
TypeOptionDataEntry,
};
@ -287,7 +287,7 @@ async fn grid_row_add_date_cell_test() {
let date_field = date_field.unwrap();
let cell_data = context.cell_by_field_id.get(&date_field.id).unwrap().clone();
assert_eq!(
decode_cell_data(cell_data.data.clone(), &date_field).unwrap(),
decode_cell_data(cell_data.data.clone(), &date_field, &date_field.field_type).unwrap(),
"2022/03/16 08:31",
);
let scripts = vec![CreateRow { context }];
@ -324,7 +324,7 @@ async fn grid_cell_update() {
};
scripts.push(UpdateCell {
changeset: CellMetaChangeset {
changeset: CellChangeset {
grid_id: block_id.to_string(),
row_id: row_meta.id.clone(),
field_id: field_meta.id.clone(),
@ -345,7 +345,7 @@ async fn grid_cell_update() {
};
scripts.push(UpdateCell {
changeset: CellMetaChangeset {
changeset: CellChangeset {
grid_id: block_id.to_string(),
row_id: row_meta.id.clone(),
field_id: field_meta.id.clone(),

View File

@ -3,8 +3,8 @@ use flowy_grid::services::field::*;
use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder};
use flowy_grid::services::row::CreateRowMetaPayload;
use flowy_grid_data_model::entities::{
BuildGridContext, CellMetaChangeset, CreateFieldParams, Field, FieldChangesetParams, FieldMeta, FieldOrder,
FieldType, GridBlockMeta, GridBlockMetaChangeset, RowMeta, RowMetaChangeset, RowOrder, TypeOptionDataEntry,
BuildGridContext, CellChangeset, CreateFieldParams, Field, FieldChangesetParams, FieldMeta, FieldOrder, FieldType,
GridBlockMeta, GridBlockMetaChangeset, RowMeta, RowMetaChangeset, RowOrder, TypeOptionDataEntry,
};
use flowy_revision::REVISION_WRITE_INTERVAL_IN_MILLIS;
use flowy_sync::client_grid::GridBuilder;
@ -61,7 +61,7 @@ pub enum EditorScript {
row_ids: Vec<String>,
},
UpdateCell {
changeset: CellMetaChangeset,
changeset: CellChangeset,
is_err: bool,
},
AssertRowCount(usize),
@ -86,7 +86,7 @@ impl GridEditorTest {
let sdk = FlowySDKTest::default();
let _ = sdk.init_user().await;
let build_context = make_template_1_grid();
let view_data: Bytes = build_context.try_into().unwrap();
let view_data: Bytes = build_context.into();
let test = ViewTest::new_grid_view(&sdk, view_data.to_vec()).await;
let editor = sdk.grid_manager.open_grid(&test.view.id).await.unwrap();
let field_metas = editor.get_field_metas::<FieldOrder>(None).await.unwrap();
@ -258,7 +258,7 @@ pub fn create_text_field(grid_id: &str) -> (CreateFieldParams, FieldMeta) {
let cloned_field_meta = field_meta.clone();
let type_option_data = field_meta
.get_type_option_entry::<RichTextTypeOption>(None)
.get_type_option_entry::<RichTextTypeOption>(&field_meta.field_type)
.unwrap()
.protobuf_bytes()
.to_vec();
@ -290,7 +290,7 @@ pub fn create_single_select_field(grid_id: &str) -> (CreateFieldParams, FieldMet
let field_meta = FieldBuilder::new(single_select).name("Name").visibility(true).build();
let cloned_field_meta = field_meta.clone();
let type_option_data = field_meta
.get_type_option_entry::<SingleSelectTypeOption>(None)
.get_type_option_entry::<SingleSelectTypeOption>(&field_meta.field_type)
.unwrap()
.protobuf_bytes()
.to_vec();

View File

@ -37,6 +37,7 @@ config = { version = "0.10.1", default-features = false, features = ["yaml"] }
log = "0.4.14"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
nanoid = "0.4.0"
[features]
http_server = []

View File

@ -17,6 +17,7 @@ use flowy_sync::{
};
use futures_util::stream::StreamExt;
use lib_ws::{WSChannel, WebSocketRawMessage};
use nanoid::nanoid;
use parking_lot::RwLock;
use std::{
convert::{TryFrom, TryInto},
@ -251,6 +252,8 @@ impl RevisionUser for LocalRevisionUser {
}
}
use flowy_folder_data_model::entities::app::gen_app_id;
use flowy_folder_data_model::entities::workspace::gen_workspace_id;
use flowy_folder_data_model::entities::{
app::{App, AppId, CreateAppParams, RepeatedApp, UpdateAppParams},
trash::{RepeatedTrash, RepeatedTrashId},
@ -262,7 +265,7 @@ use flowy_user::event_map::UserCloudService;
use flowy_user_data_model::entities::{
SignInParams, SignInResponse, SignUpParams, SignUpResponse, UpdateUserParams, UserProfile,
};
use lib_infra::{future::FutureResult, timestamp, uuid};
use lib_infra::{future::FutureResult, timestamp};
impl FolderCouldServiceV1 for LocalServer {
fn init(&self) {}
@ -270,7 +273,7 @@ impl FolderCouldServiceV1 for LocalServer {
fn create_workspace(&self, _token: &str, params: CreateWorkspaceParams) -> FutureResult<Workspace, FlowyError> {
let time = timestamp();
let workspace = Workspace {
id: uuid(),
id: gen_workspace_id(),
name: params.name,
desc: params.desc,
apps: RepeatedApp::default(),
@ -330,7 +333,7 @@ impl FolderCouldServiceV1 for LocalServer {
fn create_app(&self, _token: &str, params: CreateAppParams) -> FutureResult<App, FlowyError> {
let time = timestamp();
let app = App {
id: uuid(),
id: gen_app_id(),
workspace_id: params.workspace_id,
name: params.name,
desc: params.desc,
@ -372,7 +375,7 @@ impl FolderCouldServiceV1 for LocalServer {
impl UserCloudService for LocalServer {
fn sign_up(&self, params: SignUpParams) -> FutureResult<SignUpResponse, FlowyError> {
let uid = uuid();
let uid = nanoid!(10);
FutureResult::new(async move {
Ok(SignUpResponse {
user_id: uid.clone(),
@ -384,7 +387,7 @@ impl UserCloudService for LocalServer {
}
fn sign_in(&self, params: SignInParams) -> FutureResult<SignInResponse, FlowyError> {
let user_id = uuid();
let user_id = nanoid!(10);
FutureResult::new(async {
Ok(SignInResponse {
user_id: user_id.clone(),

View File

@ -14,7 +14,7 @@ use flowy_folder::{
};
use flowy_grid::manager::{make_grid_view_data, GridManager};
use flowy_grid::util::make_default_grid;
use flowy_grid_data_model::entities::BuildGridContext;
use flowy_net::ClientServerConfiguration;
use flowy_net::{
http_server::folder::FolderHttpCloudService, local_server::LocalServer, ws::connection::FlowyWebSocketConnect,
@ -25,6 +25,8 @@ use futures_core::future::BoxFuture;
use lib_infra::future::{BoxResultFuture, FutureResult};
use lib_ws::{WSChannel, WSMessageReceiver, WebSocketRawMessage};
use std::collections::HashMap;
use flowy_grid_data_model::entities::BuildGridContext;
use std::convert::TryFrom;
use std::{convert::TryInto, sync::Arc};

View File

@ -67,7 +67,7 @@ fn crate_log_filter(level: String) -> String {
filters.push(format!("flowy_sdk={}", level));
filters.push(format!("flowy_folder={}", level));
filters.push(format!("flowy_user={}", level));
filters.push(format!("flowy_block={}", level));
filters.push(format!("flowy_text_block={}", level));
filters.push(format!("flowy_grid={}", level));
filters.push(format!("flowy_collaboration={}", "debug"));
filters.push(format!("dart_notify={}", level));

View File

@ -26,6 +26,7 @@ futures-util = "0.3.15"
thread-id = "3.3.0"
log = "0.4"
bytes = "1.0"
nanoid = "0.4.0"
[dev-dependencies]
quickcheck = "0.9.2"

View File

@ -14,7 +14,6 @@ use flowy_user::{
event_map::UserEvent::{InitUser, SignIn, SignOut, SignUp},
};
use lib_dispatch::prelude::{EventDispatcher, ModuleRequest, ToBytes};
use lib_infra::uuid;
use std::{fs, path::PathBuf, sync::Arc};
pub struct ViewTest {
@ -127,7 +126,7 @@ pub fn root_dir() -> String {
}
pub fn random_email() -> String {
format!("{}@appflowy.io", uuid())
format!("{}@appflowy.io", nanoid!(10))
}
pub fn login_email() -> String {

View File

@ -5,7 +5,7 @@ use crate::helper::*;
use flowy_net::{get_client_server_configuration, ClientServerConfiguration};
use flowy_sdk::{FlowySDK, FlowySDKConfig};
use flowy_user::entities::UserProfile;
use lib_infra::uuid;
use nanoid::nanoid;
pub mod prelude {
pub use crate::{event_builder::*, helper::*, *};
@ -36,7 +36,7 @@ impl std::default::Default for FlowySDKTest {
impl FlowySDKTest {
pub fn new(server_config: ClientServerConfiguration) -> Self {
let config = FlowySDKConfig::new(&root_dir(), server_config, &uuid()).log_filter("trace");
let config = FlowySDKConfig::new(&root_dir(), server_config, &nanoid!(6)).log_filter("trace");
let sdk = std::thread::spawn(|| FlowySDK::new(config)).join().unwrap();
std::mem::forget(sdk.dispatcher());
Self { inner: sdk }

View File

@ -118,6 +118,7 @@ impl TextBlockManager {
}
}
#[tracing::instrument(level = "trace", skip(self, pool), err)]
async fn make_text_block_editor(
&self,
block_id: &str,

View File

@ -34,6 +34,7 @@ tokio = { version = "1", features = ["rt"] }
[dev-dependencies]
flowy-test = { path = "../flowy-test" }
futures = "0.3.15"
nanoid = "0.4.0"
[features]
http_server = []

View File

@ -2,7 +2,8 @@ use crate::helper::*;
use flowy_test::{event_builder::UserModuleEventBuilder, FlowySDKTest};
use flowy_user::{errors::ErrorCode, event_map::UserEvent::*};
use flowy_user_data_model::entities::{UpdateUserPayload, UserProfile};
use lib_infra::uuid;
use nanoid::nanoid;
// use serial_test::*;
#[tokio::test]
@ -51,7 +52,7 @@ async fn user_update_with_name() {
async fn user_update_with_email() {
let sdk = FlowySDKTest::default();
let user = sdk.init_user().await;
let new_email = format!("{}@gmail.com", uuid());
let new_email = format!("{}@gmail.com", nanoid!(6));
let request = UpdateUserPayload::new(&user.id).email(&new_email);
let _ = UserModuleEventBuilder::new(sdk.clone())
.event(UpdateUser)

View File

@ -14,7 +14,7 @@ futures = "0.3.15"
futures-util = "0.3.15"
bytes = {version = "1.0", features = ["serde"]}
tokio = { version = "1", features = ["full"] }
uuid = { version = "0.8", features = ["serde", "v4"] }
nanoid = "0.4.0"
log = "0.4.14"
env_logger = "0.8"
serde_with = "1.9.4"

View File

@ -22,6 +22,7 @@ use crate::{
},
};
use futures_core::future::BoxFuture;
use nanoid::nanoid;
use std::sync::Arc;
pub type ModuleMap = Arc<HashMap<Event, Arc<Module>>>;
@ -118,7 +119,7 @@ impl ModuleRequest {
E: Into<Event>,
{
Self {
id: uuid::Uuid::new_v4().to_string(),
id: nanoid!(6),
event: event.into(),
payload: Payload::None,
}

42
shared-lib/Cargo.lock generated
View File

@ -441,6 +441,7 @@ dependencies = [
"flowy-error-code",
"lib-infra",
"log",
"nanoid",
"protobuf",
"serde",
"serde_json",
@ -448,7 +449,6 @@ dependencies = [
"strum",
"strum_macros",
"unicode-segmentation",
"uuid",
]
[[package]]
@ -458,14 +458,15 @@ dependencies = [
"bytes",
"flowy-derive",
"flowy-error-code",
"indexmap",
"lib-infra",
"nanoid",
"protobuf",
"serde",
"serde_json",
"serde_repr",
"strum",
"strum_macros",
"uuid",
]
[[package]]
@ -701,6 +702,12 @@ dependencies = [
"walkdir",
]
[[package]]
name = "hashbrown"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
[[package]]
name = "heck"
version = "0.3.3"
@ -777,6 +784,17 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "indexmap"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee"
dependencies = [
"autocfg",
"hashbrown",
"serde",
]
[[package]]
name = "instant"
version = "0.1.12"
@ -833,7 +851,6 @@ dependencies = [
"tera",
"tokio",
"toml",
"uuid",
"walkdir",
]
@ -954,6 +971,15 @@ dependencies = [
"winapi",
]
[[package]]
name = "nanoid"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ffa00dec017b5b1a8b7cf5e2c008bfda1aa7e0697ac1508b491fdf2622fb4d8"
dependencies = [
"rand 0.8.4",
]
[[package]]
name = "ntapi"
version = "0.3.6"
@ -2079,16 +2105,6 @@ version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
[[package]]
name = "uuid"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
dependencies = [
"getrandom 0.2.3",
"serde",
]
[[package]]
name = "validator"
version = "0.12.0"

View File

@ -14,7 +14,7 @@ strum = "0.21"
strum_macros = "0.21"
derive_more = {version = "0.99", features = ["display"]}
log = "0.4.14"
uuid = { version = "0.8", features = ["serde", "v4"] }
nanoid = "0.4.0"
chrono = { version = "0.4" }
flowy-error-code = { path = "../flowy-error-code"}
serde = { version = "1.0", features = ["derive"] }

View File

@ -8,9 +8,13 @@ use crate::{
},
};
use flowy_derive::ProtoBuf;
use nanoid::nanoid;
use serde::{Deserialize, Serialize};
use std::convert::TryInto;
pub fn gen_app_id() -> String {
nanoid!(10)
}
#[derive(Eq, PartialEq, ProtoBuf, Default, Debug, Clone, Serialize, Deserialize)]
pub struct App {
#[pb(index = 1)]

View File

@ -8,10 +8,15 @@ use crate::{
},
};
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use nanoid::nanoid;
use serde::{Deserialize, Serialize};
use serde_repr::*;
use std::convert::TryInto;
pub fn gen_view_id() -> String {
nanoid!(10)
}
#[derive(Eq, PartialEq, ProtoBuf, Default, Debug, Clone, Serialize, Deserialize)]
pub struct View {
#[pb(index = 1)]
@ -163,7 +168,7 @@ impl TryInto<CreateViewParams> for CreateViewPayload {
fn try_into(self) -> Result<CreateViewParams, Self::Error> {
let name = ViewName::parse(self.name)?.0;
let belong_to_id = AppIdentify::parse(self.belong_to_id)?.0;
let view_id = uuid::Uuid::new_v4().to_string();
let view_id = gen_view_id();
let thumbnail = match self.thumbnail {
None => "".to_string(),
Some(thumbnail) => ViewThumbnail::parse(thumbnail)?.0,

View File

@ -5,9 +5,13 @@ use crate::{
parser::workspace::{WorkspaceDesc, WorkspaceIdentify, WorkspaceName},
};
use flowy_derive::ProtoBuf;
use nanoid::nanoid;
use serde::{Deserialize, Serialize};
use std::convert::TryInto;
pub fn gen_workspace_id() -> String {
nanoid!(10)
}
#[derive(Eq, PartialEq, ProtoBuf, Default, Debug, Clone, Serialize, Deserialize)]
pub struct Workspace {
#[pb(index = 1)]

View File

@ -1,3 +1,6 @@
use crate::entities::app::gen_app_id;
use crate::entities::view::gen_view_id;
use crate::entities::workspace::gen_workspace_id;
use crate::entities::{
app::{App, RepeatedApp},
view::{RepeatedView, View, ViewDataType},
@ -7,7 +10,7 @@ use chrono::Utc;
pub fn create_default_workspace() -> Workspace {
let time = Utc::now();
let workspace_id = uuid::Uuid::new_v4();
let workspace_id = gen_workspace_id();
let name = "Workspace".to_string();
let desc = "".to_string();
@ -26,7 +29,7 @@ pub fn create_default_workspace() -> Workspace {
}
fn create_default_app(workspace_id: String, time: chrono::DateTime<Utc>) -> App {
let app_id = uuid::Uuid::new_v4();
let app_id = gen_app_id();
let name = "⭐️ Getting started".to_string();
let desc = "".to_string();
@ -47,7 +50,7 @@ fn create_default_app(workspace_id: String, time: chrono::DateTime<Utc>) -> App
}
fn create_default_view(app_id: String, time: chrono::DateTime<Utc>) -> View {
let view_id = uuid::Uuid::new_v4();
let view_id = gen_view_id();
let name = "Read me".to_string();
let desc = "".to_string();
let data_type = ViewDataType::TextBlock;

View File

@ -14,9 +14,9 @@ strum_macros = "0.21"
serde = { version = "1.0", features = ["derive"] }
serde_json = {version = "1.0"}
serde_repr = "0.1"
uuid = { version = "0.8", features = ["serde", "v4"] }
nanoid = "0.4.0"
flowy-error-code = { path = "../flowy-error-code"}
indexmap = {version = "1.8.1", features = ["serde"]}
[build-dependencies]
lib-infra = { path = "../lib-infra", features = ["protobuf_file_gen"] }

View File

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

View File

@ -1,9 +1,12 @@
use crate::entities::{FieldMeta, FieldType, RowMeta};
use crate::parser::NotEmptyUuid;
use flowy_derive::ProtoBuf;
use crate::entities::{CellMeta, FieldMeta, RowMeta, RowMetaChangeset};
use crate::parser::NotEmptyStr;
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use flowy_error_code::ErrorCode;
use serde_repr::*;
use std::collections::HashMap;
use std::sync::Arc;
use strum_macros::{Display, EnumCount as EnumCountMacro, EnumIter, EnumString};
#[derive(Debug, Clone, Default, ProtoBuf)]
pub struct Grid {
@ -115,8 +118,8 @@ impl TryInto<EditFieldParams> for EditFieldPayload {
type Error = ErrorCode;
fn try_into(self) -> Result<EditFieldParams, Self::Error> {
let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
let field_id = NotEmptyUuid::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
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,
@ -471,7 +474,7 @@ impl TryInto<CreateRowParams> for CreateRowPayload {
type Error = ErrorCode;
fn try_into(self) -> Result<CreateRowParams, Self::Error> {
let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
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,
@ -506,12 +509,12 @@ impl TryInto<CreateFieldParams> for CreateFieldPayload {
type Error = ErrorCode;
fn try_into(self) -> Result<CreateFieldParams, Self::Error> {
let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
let _ = NotEmptyUuid::parse(self.field.id.clone()).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
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(NotEmptyUuid::parse(id).map_err(|_| ErrorCode::FieldIdIsEmpty)?.0),
Some(id) => Some(NotEmptyStr::parse(id).map_err(|_| ErrorCode::FieldIdIsEmpty)?.0),
};
Ok(CreateFieldParams {
@ -541,7 +544,7 @@ impl TryInto<QueryFieldParams> for QueryFieldPayload {
type Error = ErrorCode;
fn try_into(self) -> Result<QueryFieldParams, Self::Error> {
let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
Ok(QueryFieldParams {
grid_id: grid_id.0,
field_orders: self.field_orders,
@ -567,10 +570,176 @@ impl TryInto<QueryGridBlocksParams> for QueryGridBlocksPayload {
type Error = ErrorCode;
fn try_into(self) -> Result<QueryGridBlocksParams, Self::Error> {
let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
Ok(QueryGridBlocksParams {
grid_id: grid_id.0,
block_orders: self.block_orders,
})
}
}
#[derive(Debug, Clone, Default, ProtoBuf)]
pub struct FieldChangesetPayload {
#[pb(index = 1)]
pub field_id: String,
#[pb(index = 2)]
pub grid_id: String,
#[pb(index = 3, one_of)]
pub name: Option<String>,
#[pb(index = 4, one_of)]
pub desc: Option<String>,
#[pb(index = 5, one_of)]
pub field_type: Option<FieldType>,
#[pb(index = 6, one_of)]
pub frozen: Option<bool>,
#[pb(index = 7, one_of)]
pub visibility: Option<bool>,
#[pb(index = 8, one_of)]
pub width: Option<i32>,
#[pb(index = 9, one_of)]
pub type_option_data: Option<Vec<u8>>,
}
#[derive(Debug, Clone, Default)]
pub struct FieldChangesetParams {
pub field_id: String,
pub grid_id: String,
pub name: Option<String>,
pub desc: Option<String>,
pub field_type: Option<FieldType>,
pub frozen: Option<bool>,
pub visibility: Option<bool>,
pub width: Option<i32>,
pub type_option_data: Option<Vec<u8>>,
}
impl TryInto<FieldChangesetParams> for FieldChangesetPayload {
type Error = ErrorCode;
fn try_into(self) -> Result<FieldChangesetParams, Self::Error> {
let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
let field_id = NotEmptyStr::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
if let Some(type_option_data) = self.type_option_data.as_ref() {
if type_option_data.is_empty() {
return Err(ErrorCode::TypeOptionDataIsEmpty);
}
}
Ok(FieldChangesetParams {
field_id: field_id.0,
grid_id: grid_id.0,
name: self.name,
desc: self.desc,
field_type: self.field_type,
frozen: self.frozen,
visibility: self.visibility,
width: self.width,
type_option_data: self.type_option_data,
})
}
}
#[derive(
Debug,
Clone,
PartialEq,
Eq,
ProtoBuf_Enum,
EnumCountMacro,
EnumString,
EnumIter,
Display,
Serialize_repr,
Deserialize_repr,
)]
#[repr(u8)]
pub enum FieldType {
RichText = 0,
Number = 1,
DateTime = 2,
SingleSelect = 3,
MultiSelect = 4,
Checkbox = 5,
}
impl std::default::Default for FieldType {
fn default() -> Self {
FieldType::RichText
}
}
impl AsRef<FieldType> for FieldType {
fn as_ref(&self) -> &FieldType {
self
}
}
impl From<&FieldType> for FieldType {
fn from(field_type: &FieldType) -> Self {
field_type.clone()
}
}
impl FieldType {
pub fn type_id(&self) -> String {
let ty = self.clone();
format!("{}", ty as u8)
}
pub fn default_cell_width(&self) -> i32 {
match self {
FieldType::DateTime => 180,
_ => 150,
}
}
}
#[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 data: Option<String>,
}
impl std::convert::From<CellChangeset> for RowMetaChangeset {
fn from(changeset: CellChangeset) -> Self {
let mut cell_by_field_id = HashMap::with_capacity(1);
let field_id = changeset.field_id;
let cell_meta = CellMeta {
data: changeset.data.unwrap_or_else(|| "".to_owned()),
};
cell_by_field_id.insert(field_id, cell_meta);
RowMetaChangeset {
row_id: changeset.row_id,
height: None,
visibility: None,
cell_by_field_id,
}
}
}

View File

@ -1,35 +1,40 @@
use crate::parser::NotEmptyUuid;
use crate::entities::FieldType;
use bytes::Bytes;
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use flowy_error_code::ErrorCode;
use indexmap::IndexMap;
use nanoid::nanoid;
use serde::{Deserialize, Serialize};
use serde_repr::*;
use std::collections::HashMap;
use strum_macros::{Display, EnumCount as EnumCountMacro, EnumIter, EnumString};
pub const DEFAULT_ROW_HEIGHT: i32 = 42;
#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)]
pub fn gen_grid_id() -> String {
// nanoid calculator https://zelark.github.io/nano-id-cc/
nanoid!(10)
}
pub fn gen_block_id() -> String {
nanoid!(10)
}
pub fn gen_row_id() -> String {
nanoid!(6)
}
pub fn gen_field_id() -> String {
nanoid!(6)
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct GridMeta {
#[pb(index = 1)]
pub grid_id: String,
#[pb(index = 2)]
pub fields: Vec<FieldMeta>,
#[pb(index = 3)]
pub blocks: Vec<GridBlockMeta>,
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, ProtoBuf)]
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct GridBlockMeta {
#[pb(index = 1)]
pub block_id: String,
#[pb(index = 2)]
pub start_row_index: i32,
#[pb(index = 3)]
pub row_count: i32,
}
@ -46,7 +51,7 @@ impl GridBlockMeta {
impl GridBlockMeta {
pub fn new() -> Self {
GridBlockMeta {
block_id: uuid::Uuid::new_v4().to_string(),
block_id: gen_block_id(),
..Default::default()
}
}
@ -68,50 +73,41 @@ impl GridBlockMetaChangeset {
}
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)]
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct GridBlockMetaData {
#[pb(index = 1)]
pub block_id: String,
#[pb(index = 2)]
pub rows: Vec<RowMeta>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf, Eq, PartialEq)]
#[derive(Debug, Clone, Default, Serialize, Deserialize, Eq, PartialEq)]
pub struct FieldMeta {
#[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)]
// #[pb(index = 8)]
/// type_options contains key/value pairs
/// key: id of the FieldType
/// value: type option data string
pub type_options: HashMap<String, String>,
#[serde(with = "indexmap::serde_seq")]
pub type_options: IndexMap<String, String>,
}
impl FieldMeta {
pub fn new(name: &str, desc: &str, field_type: FieldType) -> Self {
let width = field_type.default_cell_width();
Self {
id: uuid::Uuid::new_v4().to_string(),
id: gen_field_id(),
name: name.to_string(),
desc: desc.to_string(),
field_type,
@ -122,12 +118,14 @@ impl FieldMeta {
}
}
pub fn insert_type_option_entry<T: TypeOptionDataEntry + ?Sized>(&mut self, entry: &T) {
pub fn insert_type_option_entry<T>(&mut self, entry: &T)
where
T: TypeOptionDataEntry + ?Sized,
{
self.type_options.insert(entry.field_type().type_id(), entry.json_str());
}
pub fn get_type_option_entry<T: TypeOptionDataEntity>(&self, field_type: Option<FieldType>) -> Option<T> {
let field_type = field_type.as_ref().unwrap_or(&self.field_type);
pub fn get_type_option_entry<T: TypeOptionDataDeserializer>(&self, field_type: &FieldType) -> Option<T> {
self.type_options
.get(&field_type.type_id())
.map(|s| T::from_json_str(s))
@ -149,192 +147,28 @@ pub trait TypeOptionDataEntry {
fn protobuf_bytes(&self) -> Bytes;
}
pub trait TypeOptionDataEntity {
pub trait TypeOptionDataDeserializer {
fn from_json_str(s: &str) -> Self;
fn from_protobuf_bytes(bytes: Bytes) -> Self;
}
#[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 = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
let field_id = NotEmptyUuid::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
if let Some(type_option_data) = self.type_option_data.as_ref() {
if type_option_data.is_empty() {
return Err(ErrorCode::TypeOptionDataIsEmpty);
}
}
Ok(FieldChangesetParams {
field_id: field_id.0,
grid_id: grid_id.0,
name: self.name,
desc: self.desc,
field_type: self.field_type,
frozen: self.frozen,
visibility: self.visibility,
width: self.width,
type_option_data: self.type_option_data,
})
}
}
#[derive(
Debug,
Clone,
PartialEq,
Eq,
ProtoBuf_Enum,
EnumCountMacro,
EnumString,
EnumIter,
Display,
Serialize_repr,
Deserialize_repr,
)]
#[repr(u8)]
pub enum FieldType {
RichText = 0,
Number = 1,
DateTime = 2,
SingleSelect = 3,
MultiSelect = 4,
Checkbox = 5,
}
impl std::default::Default for FieldType {
fn default() -> Self {
FieldType::RichText
}
}
impl AsRef<FieldType> for FieldType {
fn as_ref(&self) -> &FieldType {
self
}
}
impl From<&FieldType> for FieldType {
fn from(field_type: &FieldType) -> Self {
field_type.clone()
}
}
impl FieldType {
pub fn type_id(&self) -> String {
let ty = self.clone();
format!("{}", ty as u8)
}
pub fn default_cell_width(&self) -> i32 {
match self {
FieldType::DateTime => 180,
_ => 150,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, Default, ProtoBuf)]
pub struct AnyData {
#[pb(index = 1)]
pub type_id: String,
#[pb(index = 2)]
pub value: Vec<u8>,
}
impl AnyData {
pub fn from_str<F: Into<FieldType>>(field_type: F, s: &str) -> AnyData {
Self::from_bytes(field_type, s.as_bytes().to_vec())
}
pub fn from_bytes<T: AsRef<[u8]>, F: Into<FieldType>>(field_type: F, bytes: T) -> AnyData {
AnyData {
type_id: field_type.into().type_id(),
value: bytes.as_ref().to_vec(),
}
}
}
impl ToString for AnyData {
fn to_string(&self) -> String {
match String::from_utf8(self.value.clone()) {
Ok(s) => s,
Err(_) => "".to_owned(),
}
}
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, ProtoBuf)]
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct RowMeta {
#[pb(index = 1)]
pub id: String,
#[pb(index = 2)]
pub block_id: String,
#[pb(index = 3)]
/// cells contains key/value pairs.
/// key: field id,
/// value: CellMeta
pub cells: HashMap<String, CellMeta>,
#[pb(index = 4)]
#[serde(with = "indexmap::serde_seq")]
pub cells: IndexMap<String, CellMeta>,
pub height: i32,
#[pb(index = 5)]
pub visibility: bool,
}
impl RowMeta {
pub fn new(block_id: &str) -> Self {
Self {
id: uuid::Uuid::new_v4().to_string(),
id: gen_row_id(),
block_id: block_id.to_owned(),
cells: Default::default(),
height: DEFAULT_ROW_HEIGHT,
@ -343,24 +177,16 @@ impl RowMeta {
}
}
#[derive(Debug, Clone, Default, ProtoBuf)]
#[derive(Debug, Clone, Default)]
pub struct RowMetaChangeset {
#[pb(index = 1)]
pub row_id: String,
#[pb(index = 2, one_of)]
pub height: Option<i32>,
#[pb(index = 3, one_of)]
pub visibility: Option<bool>,
#[pb(index = 4)]
pub cell_by_field_id: HashMap<String, CellMeta>,
}
#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize, ProtoBuf)]
#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
pub struct CellMeta {
#[pb(index = 1)]
pub data: String,
}
@ -370,49 +196,27 @@ impl CellMeta {
}
}
#[derive(Debug, Clone, Default, ProtoBuf)]
pub struct CellMetaChangeset {
#[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 data: Option<String>,
#[derive(Clone, Deserialize, Serialize)]
pub struct BuildGridContext {
pub field_metas: Vec<FieldMeta>,
pub block_meta: GridBlockMeta,
pub block_meta_data: GridBlockMetaData,
}
impl std::convert::From<CellMetaChangeset> for RowMetaChangeset {
fn from(changeset: CellMetaChangeset) -> Self {
let mut cell_by_field_id = HashMap::with_capacity(1);
let field_id = changeset.field_id;
let cell_meta = CellMeta {
data: changeset.data.unwrap_or_else(|| "".to_owned()),
};
cell_by_field_id.insert(field_id, cell_meta);
RowMetaChangeset {
row_id: changeset.row_id,
height: None,
visibility: None,
cell_by_field_id,
}
impl std::convert::From<BuildGridContext> for Bytes {
fn from(ctx: BuildGridContext) -> Self {
let bytes = serde_json::to_vec(&ctx).unwrap_or_else(|_| vec![]);
Bytes::from(bytes)
}
}
#[derive(Clone, ProtoBuf)]
pub struct BuildGridContext {
#[pb(index = 1)]
pub field_metas: Vec<FieldMeta>,
impl std::convert::TryFrom<Bytes> for BuildGridContext {
type Error = serde_json::Error;
#[pb(index = 2)]
pub block_meta: GridBlockMeta,
#[pb(index = 3)]
pub block_meta_data: GridBlockMetaData,
fn try_from(bytes: Bytes) -> Result<Self, Self::Error> {
let ctx: BuildGridContext = serde_json::from_slice(&bytes)?;
Ok(ctx)
}
}
impl std::default::Default for BuildGridContext {

View File

@ -1,25 +1,3 @@
use uuid::Uuid;
#[derive(Debug)]
pub struct NotEmptyUuid(pub String);
impl NotEmptyUuid {
pub fn parse(s: String) -> Result<Self, String> {
if s.trim().is_empty() {
return Err("Input string is empty".to_owned());
}
debug_assert!(Uuid::parse_str(&s).is_ok());
Ok(Self(s))
}
}
impl AsRef<str> for NotEmptyUuid {
fn as_ref(&self) -> &str {
&self.0
}
}
#[derive(Debug)]
pub struct NotEmptyStr(pub String);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -1,5 +1,4 @@
syntax = "proto3";
import "meta.proto";
message Grid {
string id = 1;
@ -113,3 +112,28 @@ message QueryGridBlocksPayload {
string grid_id = 1;
repeated GridBlockOrder block_orders = 2;
}
message FieldChangesetPayload {
string field_id = 1;
string grid_id = 2;
oneof one_of_name { string name = 3; };
oneof one_of_desc { string desc = 4; };
oneof one_of_field_type { FieldType field_type = 5; };
oneof one_of_frozen { bool frozen = 6; };
oneof one_of_visibility { bool visibility = 7; };
oneof one_of_width { int32 width = 8; };
oneof one_of_type_option_data { bytes type_option_data = 9; };
}
message CellChangeset {
string grid_id = 1;
string row_id = 2;
string field_id = 3;
oneof one_of_data { string data = 4; };
}
enum FieldType {
RichText = 0;
Number = 1;
DateTime = 2;
SingleSelect = 3;
MultiSelect = 4;
Checkbox = 5;
}

View File

@ -1,76 +0,0 @@
syntax = "proto3";
message GridMeta {
string grid_id = 1;
repeated FieldMeta fields = 2;
repeated GridBlockMeta blocks = 3;
}
message GridBlockMeta {
string block_id = 1;
int32 start_row_index = 2;
int32 row_count = 3;
}
message GridBlockMetaData {
string block_id = 1;
repeated RowMeta rows = 2;
}
message FieldMeta {
string id = 1;
string name = 2;
string desc = 3;
FieldType field_type = 4;
bool frozen = 5;
bool visibility = 6;
int32 width = 7;
map<string, string> type_options = 8;
}
message FieldChangesetPayload {
string field_id = 1;
string grid_id = 2;
oneof one_of_name { string name = 3; };
oneof one_of_desc { string desc = 4; };
oneof one_of_field_type { FieldType field_type = 5; };
oneof one_of_frozen { bool frozen = 6; };
oneof one_of_visibility { bool visibility = 7; };
oneof one_of_width { int32 width = 8; };
oneof one_of_type_option_data { bytes type_option_data = 9; };
}
message AnyData {
string type_id = 1;
bytes value = 2;
}
message RowMeta {
string id = 1;
string block_id = 2;
map<string, CellMeta> cells = 3;
int32 height = 4;
bool visibility = 5;
}
message RowMetaChangeset {
string row_id = 1;
oneof one_of_height { int32 height = 2; };
oneof one_of_visibility { bool visibility = 3; };
map<string, CellMeta> cell_by_field_id = 4;
}
message CellMeta {
string data = 1;
}
message CellMetaChangeset {
string grid_id = 1;
string row_id = 2;
string field_id = 3;
oneof one_of_data { string data = 4; };
}
message BuildGridContext {
repeated FieldMeta field_metas = 1;
GridBlockMeta block_meta = 2;
GridBlockMetaData block_meta_data = 3;
}
enum FieldType {
RichText = 0;
Number = 1;
DateTime = 2;
SingleSelect = 3;
MultiSelect = 4;
Checkbox = 5;
}

View File

@ -1,8 +1,7 @@
use crate::entities::revision::{md5, RepeatedRevision, Revision};
use crate::errors::{CollaborateError, CollaborateResult};
use crate::util::{cal_diff, make_delta_from_revisions};
use flowy_grid_data_model::entities::{CellMeta, GridBlockMetaData, RowMeta, RowMetaChangeset};
use lib_infra::uuid;
use flowy_grid_data_model::entities::{gen_block_id, CellMeta, GridBlockMetaData, RowMeta, RowMetaChangeset};
use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder};
use serde::{Deserialize, Serialize};
use std::borrow::Cow;
@ -163,7 +162,11 @@ impl GridBlockMetaPad {
match cal_diff::<PlainTextAttributes>(old, new) {
None => Ok(None),
Some(delta) => {
tracing::debug!("[GridBlockMeta] Composing change {}", delta.to_delta_str());
tracing::debug!("[GridBlockMeta] Composing delta {}", delta.to_delta_str());
tracing::debug!(
"[GridBlockMeta] current delta: {}",
self.delta.to_str().unwrap_or_else(|_| "".to_string())
);
self.delta = self.delta.compose(&delta)?;
Ok(Some(GridBlockMetaChange { delta, md5: self.md5() }))
}
@ -221,7 +224,7 @@ pub fn make_block_meta_revisions(user_id: &str, grid_block_meta_data: &GridBlock
impl std::default::Default for GridBlockMetaPad {
fn default() -> Self {
let block_meta_data = GridBlockMetaData {
block_id: uuid(),
block_id: gen_block_id(),
rows: vec![],
};
@ -251,7 +254,8 @@ mod tests {
visibility: false,
};
let change = pad.add_row_meta(row, None).unwrap().unwrap();
let change = pad.add_row_meta(row.clone(), None).unwrap().unwrap();
assert_eq!(pad.rows.first().unwrap().as_ref(), &row);
assert_eq!(
change.delta.to_delta_str(),
r#"[{"retain":24},{"insert":"{\"id\":\"1\",\"block_id\":\"1\",\"cells\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"#
@ -380,7 +384,7 @@ mod tests {
assert_eq!(
pad.to_json().unwrap(),
r#"{"block_id":"1","rows":[{"id":"1","block_id":"1","cells":{},"height":100,"visibility":true}]}"#
r#"{"block_id":"1","rows":[{"id":"1","block_id":"1","cells":[],"height":100,"visibility":true}]}"#
);
}

View File

@ -3,10 +3,9 @@ use crate::errors::{internal_error, CollaborateError, CollaborateResult};
use crate::util::{cal_diff, make_delta_from_revisions};
use bytes::Bytes;
use flowy_grid_data_model::entities::{
FieldChangesetParams, FieldMeta, FieldOrder, FieldType, GridBlockMeta, GridBlockMetaChangeset, GridMeta,
gen_field_id, gen_grid_id, FieldChangesetParams, FieldMeta, FieldOrder, FieldType, GridBlockMeta,
GridBlockMetaChangeset, GridMeta,
};
use lib_infra::uuid;
use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder};
use std::collections::HashMap;
@ -89,7 +88,7 @@ impl GridMetaPad {
None => Ok(None),
Some(index) => {
let mut duplicate_field_meta = grid_meta.fields[index].clone();
duplicate_field_meta.id = uuid();
duplicate_field_meta.id = gen_field_id();
duplicate_field_meta.name = format!("{} (copy)", duplicate_field_meta.name);
grid_meta.fields.insert(index + 1, duplicate_field_meta);
Ok(Some(()))
@ -374,7 +373,7 @@ pub fn make_grid_revisions(user_id: &str, grid_meta: &GridMeta) -> RepeatedRevis
impl std::default::Default for GridMetaPad {
fn default() -> Self {
let grid = GridMeta {
grid_id: uuid(),
grid_id: gen_grid_id(),
fields: vec![],
blocks: vec![],
};

View File

@ -163,7 +163,6 @@ impl ServerDocumentManager {
}
}
#[tracing::instrument(level = "debug", skip(self, repeated_revision), err)]
async fn create_document(
&self,
doc_id: &str,
@ -182,6 +181,7 @@ impl ServerDocumentManager {
}
}
#[tracing::instrument(level = "debug", skip(self, doc), err)]
async fn create_document_handler(&self, doc: TextBlockInfo) -> Result<Arc<OpenDocumentHandler>, CollaborateError> {
let persistence = self.persistence.clone();
let handle = spawn_blocking(|| OpenDocumentHandler::new(doc, persistence))

View File

@ -6,7 +6,6 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
uuid = { version = "0.8", features = ["serde", "v4"] }
log = "0.4.14"
chrono = "0.4.19"
bytes = { version = "1.0" }

View File

@ -2,11 +2,6 @@ pub mod code_gen;
pub mod future;
pub mod retry;
#[allow(dead_code)]
pub fn uuid() -> String {
uuid::Uuid::new_v4().to_string()
}
#[allow(dead_code)]
pub fn timestamp() -> i64 {
chrono::Utc::now().timestamp()