chore: render rows

This commit is contained in:
appflowy 2022-03-18 17:14:46 +08:00
parent 9a40fc9974
commit 05bcd38534
61 changed files with 1884 additions and 778 deletions

View File

@ -17,8 +17,6 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart';
import 'package:get_it/get_it.dart';
import '../workspace/application/grid/grid_listener.dart';
class HomeDepsResolver {
static Future<void> resolve(GetIt getIt) async {
getIt.registerFactoryParam<UserListener, UserProfile, void>(
@ -93,13 +91,13 @@ class HomeDepsResolver {
// Grid
getIt.registerFactoryParam<GridBloc, View, void>(
(view, _) => GridBloc(view: view, service: GridService(), listener: GridListener(gridId: view.id)),
(view, _) => GridBloc(view: view, service: GridService()),
);
getIt.registerFactoryParam<RowBloc, GridRowData, void>(
(data, _) => RowBloc(
service: RowService(data),
listener: RowListener(rowId: data.row.id),
rowService: RowService(data),
listener: RowListener(rowId: data.rowId),
),
);
@ -110,31 +108,31 @@ class HomeDepsResolver {
),
);
getIt.registerFactoryParam<TextCellBloc, CellContext, void>(
getIt.registerFactoryParam<TextCellBloc, GridCellData, void>(
(context, _) => TextCellBloc(
service: CellService(context),
),
);
getIt.registerFactoryParam<SelectionCellBloc, CellContext, void>(
getIt.registerFactoryParam<SelectionCellBloc, GridCellData, void>(
(context, _) => SelectionCellBloc(
service: CellService(context),
),
);
getIt.registerFactoryParam<NumberCellBloc, CellContext, void>(
getIt.registerFactoryParam<NumberCellBloc, GridCellData, void>(
(context, _) => NumberCellBloc(
service: CellService(context),
),
);
getIt.registerFactoryParam<DateCellBloc, CellContext, void>(
getIt.registerFactoryParam<DateCellBloc, GridCellData, void>(
(context, _) => DateCellBloc(
service: CellService(context),
),
);
getIt.registerFactoryParam<CheckboxCellBloc, CellContext, void>(
getIt.registerFactoryParam<CheckboxCellBloc, GridCellData, void>(
(context, _) => CheckboxCellBloc(
service: CellService(context),
),

View File

@ -1,11 +1,11 @@
import 'package:app_flowy/workspace/application/grid/row_service.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:dartz/dartz.dart';
import 'package:flowy_sdk/dispatch/dispatch.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart';
class CellService {
final CellContext context;
final GridCellData context;
CellService(this.context);
@ -18,12 +18,3 @@ class CellService {
return GridEventUpdateCell(payload).send();
}
}
class CellContext {
final String gridId;
final String rowId;
final Field field;
final Cell? cell;
CellContext({required this.rowId, required this.gridId, required this.field, required this.cell});
}

View File

@ -1,47 +1,4 @@
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
import 'package:equatable/equatable.dart';
class GridInfo {
final String gridId;
List<GridBlock> gridBlocks;
List<Field> fields;
GridInfo({
required this.gridId,
required this.gridBlocks,
required this.fields,
});
GridRowData rowAtIndex(int index) {
final row = rows[index];
return GridRowData(
gridId: gridId,
row: row,
fields: fields,
cellMap: row.cellByFieldId,
);
}
int numberOfRows() {
return rows.length;
}
}
class GridRowData extends Equatable {
final String gridId;
final Row row;
final List<Field> fields;
final Map<String, Cell> cellMap;
const GridRowData({
required this.gridId,
required this.row,
required this.fields,
required this.cellMap,
});
@override
List<Object> get props => [row.hashCode, cellMap];
}
class GridColumnData {
final List<Field> fields;

View File

@ -1,14 +1,12 @@
import 'dart:async';
import 'package:dartz/dartz.dart';
import 'package:flowy_sdk/log.dart';
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/protobuf.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'data.dart';
import 'grid_listener.dart';
import 'grid_block_service.dart';
import 'grid_listenr.dart';
import 'grid_service.dart';
part 'grid_bloc.freezed.dart';
@ -16,14 +14,16 @@ part 'grid_bloc.freezed.dart';
class GridBloc extends Bloc<GridEvent, GridState> {
final View view;
final GridService service;
final GridListener listener;
late GridListener _gridListener;
late GridBlockService _blockService;
GridBloc({required this.view, required this.service}) : super(GridState.initial()) {
_gridListener = GridListener();
GridBloc({required this.view, required this.service, required this.listener}) : super(GridState.initial()) {
on<GridEvent>(
(event, emit) async {
await event.map(
initial: (InitialGrid value) async {
await _startGridListening();
await _loadGrid(emit);
},
createRow: (_CreateRow value) {
@ -32,6 +32,9 @@ class GridBloc extends Bloc<GridEvent, GridState> {
delete: (_Delete value) {},
rename: (_Rename value) {},
updateDesc: (_Desc value) {},
didLoadRows: (_DidLoadRows value) {
emit(state.copyWith(rows: value.rows));
},
);
},
);
@ -39,61 +42,63 @@ class GridBloc extends Bloc<GridEvent, GridState> {
@override
Future<void> close() async {
await listener.close();
await _gridListener.stop();
await _blockService.stop();
return super.close();
}
Future<void> _startGridListening() async {
listener.blockUpdateNotifier.addPublishListener((result) {
result.fold((blockId) {
//
Log.info("$blockId");
}, (err) => null);
});
_blockService.didLoadRowscallback = (rows) {
add(GridEvent.didLoadRows(rows));
};
listener.start();
_gridListener.start();
}
Future<void> _loadGrid(Emitter<GridState> emit) async {
final result = await service.openGrid(gridId: view.id);
result.fold(
(grid) {
_loadFields(grid, emit);
emit(state.copyWith(grid: Some(grid)));
},
(err) => emit(state.copyWith(loadingState: GridLoadingState.finish(right(err)))),
return Future(
() => result.fold(
(grid) async => await _loadFields(grid, emit),
(err) => emit(state.copyWith(loadingState: GridLoadingState.finish(right(err)))),
),
);
}
Future<void> _loadFields(Grid grid, Emitter<GridState> emit) async {
final result = await service.getFields(gridId: grid.id, fieldOrders: grid.fieldOrders);
result.fold(
(fields) {
_loadGridBlocks(grid, emit);
emit(state.copyWith(fields: fields.items));
},
(err) => emit(state.copyWith(loadingState: GridLoadingState.finish(right(err)))),
return Future(
() => result.fold(
(fields) => _loadGridBlocks(grid, fields.items, emit),
(err) => emit(state.copyWith(loadingState: GridLoadingState.finish(right(err)))),
),
);
}
Future<void> _loadGridBlocks(Grid grid, Emitter<GridState> emit) async {
final result = await service.getGridBlocks(gridId: grid.id, blocks: grid.blocks);
Future<void> _loadGridBlocks(Grid grid, List<Field> fields, Emitter<GridState> emit) async {
final result = await service.getGridBlocks(gridId: grid.id, blockOrders: grid.blockOrders);
result.fold(
(repeatedGridBlock) {
final gridBlocks = repeatedGridBlock.items;
final gridId = view.id;
_blockService = GridBlockService(
gridId: gridId,
fields: fields,
gridBlocks: gridBlocks,
);
final rows = _blockService.rows();
result.fold((repeatedGridBlock) {
final blocks = repeatedGridBlock.items;
final gridInfo = GridInfo(
gridId: grid.id,
blocks: blocks,
fields: _fields!,
);
emit(
state.copyWith(loadingState: GridLoadingState.finish(left(unit)), gridInfo: some(left(gridInfo))),
);
}, (err) {
emit(
state.copyWith(loadingState: GridLoadingState.finish(right(err)), gridInfo: none()),
);
});
_startGridListening();
emit(state.copyWith(
grid: Some(grid),
fields: Some(fields),
rows: rows,
loadingState: GridLoadingState.finish(left(unit)),
));
},
(err) => emit(state.copyWith(loadingState: GridLoadingState.finish(right(err)), rows: [])),
);
}
}
@ -104,20 +109,21 @@ abstract class GridEvent with _$GridEvent {
const factory GridEvent.updateDesc(String gridId, String desc) = _Desc;
const factory GridEvent.delete(String gridId) = _Delete;
const factory GridEvent.createRow() = _CreateRow;
const factory GridEvent.didLoadRows(List<GridRowData> rows) = _DidLoadRows;
}
@freezed
abstract class GridState with _$GridState {
const factory GridState({
required GridLoadingState loadingState,
required List<Field> fields,
required List<Row> rows,
required Option<List<Field>> fields,
required List<GridRowData> rows,
required Option<Grid> grid,
}) = _GridState;
factory GridState.initial() => GridState(
loadingState: const _Loading(),
fields: [],
fields: none(),
rows: [],
grid: none(),
);

View File

@ -1,23 +1,67 @@
import 'dart:collection';
import 'package:dartz/dartz.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
import 'package:flowy_sdk/protobuf/dart-notify/subject.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
import 'package:flowy_sdk/rust_stream.dart';
import 'package:flowy_infra/notifier.dart';
import 'dart:async';
import 'dart:typed_data';
import 'package:app_flowy/core/notification_helper.dart';
import 'package:dartz/dartz.dart';
import 'grid_service.dart';
typedef DidLoadRowsCallback = void Function(List<GridRowData>);
typedef GridBlockUpdateNotifiedValue = Either<GridBlockId, FlowyError>;
class GridListener {
class GridBlockService {
String gridId;
List<Field> fields;
LinkedHashMap<String, GridBlock> blockMap = LinkedHashMap();
late GridBlockListener _blockListener;
DidLoadRowsCallback? didLoadRowscallback;
GridBlockService({required this.gridId, required this.fields, required List<GridBlock> gridBlocks}) {
for (final gridBlock in gridBlocks) {
blockMap[gridBlock.blockId] = gridBlock;
}
_blockListener = GridBlockListener(gridId: gridId);
_blockListener.blockUpdateNotifier.addPublishListener((result) {
result.fold((blockId) {
//
}, (err) => null);
});
}
List<GridRowData> rows() {
List<GridRowData> rows = [];
blockMap.forEach((_, gridBlock) {
rows.addAll(gridBlock.rowIds.map(
(rowId) => GridRowData(
gridId: gridId,
fields: fields,
blockId: gridBlock.blockId,
rowId: rowId,
),
));
});
return rows;
}
Future<void> stop() async {
await _blockListener.stop();
}
}
class GridBlockListener {
final String gridId;
PublishNotifier<GridBlockUpdateNotifiedValue> blockUpdateNotifier = PublishNotifier<GridBlockUpdateNotifiedValue>();
StreamSubscription<SubscribeObject>? _subscription;
late GridNotificationParser _parser;
GridListener({required this.gridId});
GridBlockListener({required this.gridId});
void start() {
_parser = GridNotificationParser(
@ -44,7 +88,7 @@ class GridListener {
}
}
Future<void> close() async {
Future<void> stop() async {
await _subscription?.cancel();
blockUpdateNotifier.dispose();
}

View File

@ -0,0 +1,4 @@
class GridListener {
void start() {}
Future<void> stop() async {}
}

View File

@ -3,7 +3,7 @@ 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';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart';
import 'package:equatable/equatable.dart';
class GridService {
Future<Either<Grid, FlowyError>> openGrid({required String gridId}) async {
@ -15,15 +15,15 @@ class GridService {
Future<Either<Row, FlowyError>> createRow({required String gridId, Option<String>? upperRowId}) {
CreateRowPayload payload = CreateRowPayload.create()..gridId = gridId;
upperRowId?.fold(() => null, (id) => payload.upperRowId = id);
upperRowId?.fold(() => null, (id) => payload.startRowId = id);
return GridEventCreateRow(payload).send();
}
Future<Either<RepeatedGridBlock, FlowyError>> getGridBlocks(
{required String gridId, required List<GridBlockMeta> blocks}) {
{required String gridId, required List<GridBlockOrder> blockOrders}) {
final payload = QueryGridBlocksPayload.create()
..gridId = gridId
..blocks.addAll(blocks);
..blockOrders.addAll(blockOrders);
return GridEventGetGridBlocks(payload).send();
}
@ -34,3 +34,19 @@ class GridService {
return GridEventGetFields(payload).send();
}
}
class GridRowData extends Equatable {
final String gridId;
final String rowId;
final String blockId;
final List<Field> fields;
const GridRowData({
required this.gridId,
required this.rowId,
required this.blockId,
required this.fields,
});
@override
List<Object> get props => [rowId];
}

View File

@ -2,25 +2,26 @@ import 'package:flowy_sdk/log.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'dart:async';
import 'data.dart';
import 'grid_service.dart';
import 'row_listener.dart';
import 'row_service.dart';
part 'row_bloc.freezed.dart';
class RowBloc extends Bloc<RowEvent, RowState> {
final RowService service;
final RowService rowService;
final RowListener listener;
RowBloc({required this.service, required this.listener}) : super(RowState.initial(service.rowData)) {
RowBloc({required this.rowService, required this.listener}) : super(RowState.initial(rowService.rowData)) {
on<RowEvent>(
(event, emit) async {
await event.map(
initial: (_InitialRow value) async {
_startRowListening();
await _loadCellDatas(emit);
},
createRow: (_CreateRow value) {
service.createRow();
rowService.createRow();
},
activeRow: (_ActiveRow value) {
emit(state.copyWith(active: true));
@ -55,6 +56,25 @@ class RowBloc extends Bloc<RowEvent, RowState> {
listener.start();
}
Future<void> _loadCellDatas(Emitter<RowState> emit) async {
final result = await rowService.getRow();
result.fold(
(row) {
final cellDatas = rowService.rowData.fields.map((field) {
final cell = row.cellByFieldId[field.id];
return GridCellData(
rowId: row.id,
gridId: rowService.rowData.gridId,
cell: cell,
field: field,
);
}).toList();
emit(state.copyWith(cellDatas: cellDatas, rowHeight: row.height.toDouble()));
},
(e) => Log.error(e),
);
}
}
@freezed
@ -68,9 +88,16 @@ abstract class RowEvent with _$RowEvent {
@freezed
abstract class RowState with _$RowState {
const factory RowState({
required GridRowData data,
required String rowId,
required double rowHeight,
required List<GridCellData> cellDatas,
required bool active,
}) = _RowState;
factory RowState.initial(GridRowData data) => RowState(data: data, active: false);
factory RowState.initial(GridRowData data) => RowState(
rowId: data.rowId,
active: false,
rowHeight: 0,
cellDatas: [],
);
}

View File

@ -1,9 +1,10 @@
import 'package:app_flowy/workspace/application/grid/data.dart';
import 'package:dartz/dartz.dart';
import 'package:flowy_sdk/dispatch/dispatch.dart';
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
import 'grid_service.dart';
class RowService {
final GridRowData rowData;
@ -12,8 +13,31 @@ class RowService {
Future<Either<Row, FlowyError>> createRow() {
CreateRowPayload payload = CreateRowPayload.create()
..gridId = rowData.gridId
..upperRowId = rowData.row.id;
..startRowId = rowData.rowId;
return GridEventCreateRow(payload).send();
}
Future<Either<Row, FlowyError>> getRow() {
QueryRowPayload payload = QueryRowPayload.create()
..gridId = rowData.gridId
..blockId = rowData.blockId
..rowId = rowData.rowId;
return GridEventGetRow(payload).send();
}
}
class GridCellData {
final String gridId;
final String rowId;
final Field field;
final Cell? cell;
GridCellData({
required this.rowId,
required this.gridId,
required this.field,
required this.cell,
});
}

View File

@ -1,5 +1,4 @@
import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/application/grid/data.dart';
import 'package:app_flowy/workspace/application/grid/grid_bloc.dart';
import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
import 'package:flowy_infra_ui/style_widget/scrolling/styled_scroll_bar.dart';
@ -41,7 +40,7 @@ class _GridPageState extends State<GridPage> {
return state.loadingState.map(
loading: (_) => const Center(child: CircularProgressIndicator.adaptive()),
finish: (result) => result.successOrFail.fold(
(_) => const GridBody(),
(_) => const FlowyGrid(),
(err) => FlowyErrorPage(err.toString()),
),
);
@ -66,14 +65,14 @@ class _GridPageState extends State<GridPage> {
}
}
class GridBody extends StatefulWidget {
const GridBody({Key? key}) : super(key: key);
class FlowyGrid extends StatefulWidget {
const FlowyGrid({Key? key}) : super(key: key);
@override
_GridBodyState createState() => _GridBodyState();
_FlowyGridState createState() => _FlowyGridState();
}
class _GridBodyState extends State<GridBody> {
class _FlowyGridState extends State<FlowyGrid> {
final _scrollController = GridScrollController();
@override
@ -86,31 +85,28 @@ class _GridBodyState extends State<GridBody> {
Widget build(BuildContext context) {
return BlocBuilder<GridBloc, GridState>(
builder: (context, state) {
return state.gridInfo.fold(
return state.fields.fold(
() => const Center(child: CircularProgressIndicator.adaptive()),
(some) => some.fold(
(gridInfo) => _renderGrid(context, gridInfo),
(err) => FlowyErrorPage(err.toString()),
),
(fields) => _renderGrid(context, fields),
);
},
);
}
Widget _renderGrid(BuildContext context, GridInfo gridInfo) {
Widget _renderGrid(BuildContext context, List<Field> fields) {
return Stack(
children: [
StyledSingleChildScrollView(
controller: _scrollController.horizontalController,
axis: Axis.horizontal,
child: SizedBox(
width: GridLayout.headerWidth(gridInfo.fields),
width: GridLayout.headerWidth(fields),
child: CustomScrollView(
physics: StyledScrollPhysics(),
controller: _scrollController.verticalController,
slivers: <Widget>[
_buildHeader(gridInfo.fields),
_buildRows(gridInfo),
_buildHeader(fields),
_buildRows(context),
const GridFooter(),
],
),
@ -134,14 +130,14 @@ class _GridBodyState extends State<GridBody> {
);
}
Widget _buildRows(GridInfo gridInfo) {
Widget _buildRows(BuildContext context) {
return SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
final data = gridInfo.rowAtIndex(index);
return GridRowWidget(data: data);
final rowData = context.read<GridBloc>().state.rows[index];
return GridRowWidget(data: rowData);
},
childCount: gridInfo.numberOfRows(),
childCount: context.read<GridBloc>().state.rows.length,
addRepaintBoundaries: true,
),
);

View File

@ -1,4 +1,5 @@
import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_service.dart';
import 'package:app_flowy/workspace/application/grid/row_service.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart';
import 'package:flutter/widgets.dart';
import 'checkbox_cell.dart';
@ -7,20 +8,20 @@ import 'number_cell.dart';
import 'selection_cell.dart';
import 'text_cell.dart';
Widget buildGridCell(CellContext cellContext) {
switch (cellContext.field.fieldType) {
Widget buildGridCell(GridCellData cellData) {
switch (cellData.field.fieldType) {
case FieldType.Checkbox:
return CheckboxCell(cellContext: cellContext);
return CheckboxCell(cellData: cellData);
case FieldType.DateTime:
return DateCell(cellContext: cellContext);
return DateCell(cellData: cellData);
case FieldType.MultiSelect:
return MultiSelectCell(cellContext: cellContext);
return MultiSelectCell(cellContext: cellData);
case FieldType.Number:
return NumberCell(cellContext: cellContext);
return NumberCell(cellData: cellData);
case FieldType.RichText:
return GridTextCell(cellContext: cellContext);
return GridTextCell(cellData: cellData);
case FieldType.SingleSelect:
return SingleSelectCell(cellContext: cellContext);
return SingleSelectCell(cellContext: cellData);
default:
return const BlankCell();
}

View File

@ -1,14 +1,14 @@
import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_service.dart';
import 'package:app_flowy/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart';
import 'package:app_flowy/workspace/application/grid/row_service.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class CheckboxCell extends StatefulWidget {
final CellContext cellContext;
final GridCellData cellData;
const CheckboxCell({
required this.cellContext,
required this.cellData,
Key? key,
}) : super(key: key);
@ -21,7 +21,7 @@ class _CheckboxCellState extends State<CheckboxCell> {
@override
void initState() {
_cellBloc = getIt<CheckboxCellBloc>(param1: widget.cellContext);
_cellBloc = getIt<CheckboxCellBloc>(param1: widget.cellData);
super.initState();
}

View File

@ -1,14 +1,14 @@
import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_service.dart';
import 'package:app_flowy/workspace/application/grid/cell_bloc/date_cell_bloc.dart';
import 'package:app_flowy/workspace/application/grid/row_service.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class DateCell extends StatefulWidget {
final CellContext cellContext;
final GridCellData cellData;
const DateCell({
required this.cellContext,
required this.cellData,
Key? key,
}) : super(key: key);
@ -21,7 +21,7 @@ class _DateCellState extends State<DateCell> {
@override
void initState() {
_cellBloc = getIt<DateCellBloc>(param1: widget.cellContext);
_cellBloc = getIt<DateCellBloc>(param1: widget.cellData);
super.initState();
}

View File

@ -11,7 +11,7 @@ import 'cell_container.dart';
class GridRowWidget extends StatefulWidget {
final GridRowData data;
GridRowWidget({required this.data, Key? key}) : super(key: ObjectKey(data.row.id));
GridRowWidget({required this.data, Key? key}) : super(key: ObjectKey(data.rowId));
@override
State<GridRowWidget> createState() => _GridRowWidgetState();
@ -37,7 +37,7 @@ class _GridRowWidgetState extends State<GridRowWidget> {
onEnter: (p) => _rowBloc.add(const RowEvent.activeRow()),
onExit: (p) => _rowBloc.add(const RowEvent.disactiveRow()),
child: SizedBox(
height: _rowBloc.state.data.row.height.toDouble(),
height: _rowBloc.state.rowHeight,
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
@ -60,26 +60,17 @@ class _GridRowWidgetState extends State<GridRowWidget> {
Widget _buildCells() {
return BlocBuilder<RowBloc, RowState>(
buildWhen: (p, c) => p.data != c.data,
buildWhen: (p, c) => p.cellDatas != c.cellDatas,
builder: (context, state) {
return Row(
key: ValueKey(state.data.row.id),
children: state.data.fields.map(
(field) {
final cell = state.data.cellMap[field.id];
return CellContainer(
width: field.width.toDouble(),
child: buildGridCell(
CellContext(
gridId: state.data.gridId,
rowId: state.data.row.id,
field: field,
cell: cell,
),
children: state.cellDatas
.map(
(cellData) => CellContainer(
width: cellData.field.width.toDouble(),
child: buildGridCell(cellData),
),
);
},
).toList(),
)
.toList(),
);
},
);

View File

@ -1,14 +1,14 @@
import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_service.dart';
import 'package:app_flowy/workspace/application/grid/cell_bloc/number_cell_bloc.dart';
import 'package:app_flowy/workspace/application/grid/row_service.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class NumberCell extends StatefulWidget {
final CellContext cellContext;
final GridCellData cellData;
const NumberCell({
required this.cellContext,
required this.cellData,
Key? key,
}) : super(key: key);
@ -21,7 +21,7 @@ class _NumberCellState extends State<NumberCell> {
@override
void initState() {
_cellBloc = getIt<NumberCellBloc>(param1: widget.cellContext);
_cellBloc = getIt<NumberCellBloc>(param1: widget.cellData);
super.initState();
}

View File

@ -3,7 +3,7 @@ import 'package:app_flowy/workspace/application/grid/prelude.dart';
import 'package:flutter/material.dart';
class SingleSelectCell extends StatefulWidget {
final CellContext cellContext;
final GridCellData cellContext;
const SingleSelectCell({
required this.cellContext,
@ -37,7 +37,7 @@ class _SingleSelectCellState extends State<SingleSelectCell> {
//----------------------------------------------------------------
class MultiSelectCell extends StatefulWidget {
final CellContext cellContext;
final GridCellData cellContext;
const MultiSelectCell({
required this.cellContext,

View File

@ -1,15 +1,15 @@
import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_service.dart';
import 'package:app_flowy/workspace/application/grid/cell_bloc/text_cell_bloc.dart';
import 'package:app_flowy/workspace/application/grid/row_service.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
/// The interface of base cell.
class GridTextCell extends StatefulWidget {
final CellContext cellContext;
final GridCellData cellData;
const GridTextCell({
required this.cellContext,
required this.cellData,
Key? key,
}) : super(key: key);
@ -24,7 +24,7 @@ class _GridTextCellState extends State<GridTextCell> {
@override
void initState() {
_cellBloc = getIt<TextCellBloc>(param1: widget.cellContext);
_cellBloc = getIt<TextCellBloc>(param1: widget.cellData);
_controller = TextEditingController(text: _cellBloc.state.content);
_focusNode.addListener(_focusChanged);
super.initState();

View File

@ -69,6 +69,23 @@ class GridEventCreateRow {
}
}
class GridEventGetRow {
QueryRowPayload request;
GridEventGetRow(this.request);
Future<Either<Row, FlowyError>> send() {
final request = FFIRequest.create()
..event = GridEvent.GetRow.toString()
..payload = requestToBytes(this.request);
return Dispatch.asyncRequest(request)
.then((bytesResult) => bytesResult.fold(
(okBytes) => left(Row.fromBuffer(okBytes)),
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
));
}
}
class GridEventUpdateCell {
CellMetaChangeset request;
GridEventUpdateCell(this.request);

View File

@ -41,7 +41,10 @@ class ErrorCode extends $pb.ProtobufEnum {
static const ErrorCode UserIdInvalid = ErrorCode._(311, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserIdInvalid');
static const ErrorCode UserNotExist = ErrorCode._(312, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNotExist');
static const ErrorCode TextTooLong = ErrorCode._(400, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'TextTooLong');
static const ErrorCode InvalidData = ErrorCode._(401, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'InvalidData');
static const ErrorCode BlockIdIsEmpty = ErrorCode._(401, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'BlockIdIsEmpty');
static const ErrorCode RowIdIsEmpty = ErrorCode._(402, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'RowIdIsEmpty');
static const ErrorCode GridIdIsEmpty = ErrorCode._(403, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridIdIsEmpty');
static const ErrorCode InvalidData = ErrorCode._(404, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'InvalidData');
static const $core.List<ErrorCode> values = <ErrorCode> [
Internal,
@ -75,6 +78,9 @@ class ErrorCode extends $pb.ProtobufEnum {
UserIdInvalid,
UserNotExist,
TextTooLong,
BlockIdIsEmpty,
RowIdIsEmpty,
GridIdIsEmpty,
InvalidData,
];

View File

@ -43,9 +43,12 @@ const ErrorCode$json = const {
const {'1': 'UserIdInvalid', '2': 311},
const {'1': 'UserNotExist', '2': 312},
const {'1': 'TextTooLong', '2': 400},
const {'1': 'InvalidData', '2': 401},
const {'1': 'BlockIdIsEmpty', '2': 401},
const {'1': 'RowIdIsEmpty', '2': 402},
const {'1': 'GridIdIsEmpty', '2': 403},
const {'1': 'InvalidData', '2': 404},
],
};
/// Descriptor for `ErrorCode`. Decode as a `google.protobuf.EnumDescriptorProto`.
final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSDAoISW50ZXJuYWwQABIUChBVc2VyVW5hdXRob3JpemVkEAISEgoOUmVjb3JkTm90Rm91bmQQAxIYChRXb3Jrc3BhY2VOYW1lSW52YWxpZBBkEhYKEldvcmtzcGFjZUlkSW52YWxpZBBlEhgKFEFwcENvbG9yU3R5bGVJbnZhbGlkEGYSGAoUV29ya3NwYWNlRGVzY1Rvb0xvbmcQZxIYChRXb3Jrc3BhY2VOYW1lVG9vTG9uZxBoEhAKDEFwcElkSW52YWxpZBBuEhIKDkFwcE5hbWVJbnZhbGlkEG8SEwoPVmlld05hbWVJbnZhbGlkEHgSGAoUVmlld1RodW1ibmFpbEludmFsaWQQeRIRCg1WaWV3SWRJbnZhbGlkEHoSEwoPVmlld0Rlc2NUb29Mb25nEHsSEwoPVmlld0RhdGFJbnZhbGlkEHwSEwoPVmlld05hbWVUb29Mb25nEH0SEQoMQ29ubmVjdEVycm9yEMgBEhEKDEVtYWlsSXNFbXB0eRCsAhIXChJFbWFpbEZvcm1hdEludmFsaWQQrQISFwoSRW1haWxBbHJlYWR5RXhpc3RzEK4CEhQKD1Bhc3N3b3JkSXNFbXB0eRCvAhIUCg9QYXNzd29yZFRvb0xvbmcQsAISJQogUGFzc3dvcmRDb250YWluc0ZvcmJpZENoYXJhY3RlcnMQsQISGgoVUGFzc3dvcmRGb3JtYXRJbnZhbGlkELICEhUKEFBhc3N3b3JkTm90TWF0Y2gQswISFAoPVXNlck5hbWVUb29Mb25nELQCEicKIlVzZXJOYW1lQ29udGFpbkZvcmJpZGRlbkNoYXJhY3RlcnMQtQISFAoPVXNlck5hbWVJc0VtcHR5ELYCEhIKDVVzZXJJZEludmFsaWQQtwISEQoMVXNlck5vdEV4aXN0ELgCEhAKC1RleHRUb29Mb25nEJADEhAKC0ludmFsaWREYXRhEJED');
final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSDAoISW50ZXJuYWwQABIUChBVc2VyVW5hdXRob3JpemVkEAISEgoOUmVjb3JkTm90Rm91bmQQAxIYChRXb3Jrc3BhY2VOYW1lSW52YWxpZBBkEhYKEldvcmtzcGFjZUlkSW52YWxpZBBlEhgKFEFwcENvbG9yU3R5bGVJbnZhbGlkEGYSGAoUV29ya3NwYWNlRGVzY1Rvb0xvbmcQZxIYChRXb3Jrc3BhY2VOYW1lVG9vTG9uZxBoEhAKDEFwcElkSW52YWxpZBBuEhIKDkFwcE5hbWVJbnZhbGlkEG8SEwoPVmlld05hbWVJbnZhbGlkEHgSGAoUVmlld1RodW1ibmFpbEludmFsaWQQeRIRCg1WaWV3SWRJbnZhbGlkEHoSEwoPVmlld0Rlc2NUb29Mb25nEHsSEwoPVmlld0RhdGFJbnZhbGlkEHwSEwoPVmlld05hbWVUb29Mb25nEH0SEQoMQ29ubmVjdEVycm9yEMgBEhEKDEVtYWlsSXNFbXB0eRCsAhIXChJFbWFpbEZvcm1hdEludmFsaWQQrQISFwoSRW1haWxBbHJlYWR5RXhpc3RzEK4CEhQKD1Bhc3N3b3JkSXNFbXB0eRCvAhIUCg9QYXNzd29yZFRvb0xvbmcQsAISJQogUGFzc3dvcmRDb250YWluc0ZvcmJpZENoYXJhY3RlcnMQsQISGgoVUGFzc3dvcmRGb3JtYXRJbnZhbGlkELICEhUKEFBhc3N3b3JkTm90TWF0Y2gQswISFAoPVXNlck5hbWVUb29Mb25nELQCEicKIlVzZXJOYW1lQ29udGFpbkZvcmJpZGRlbkNoYXJhY3RlcnMQtQISFAoPVXNlck5hbWVJc0VtcHR5ELYCEhIKDVVzZXJJZEludmFsaWQQtwISEQoMVXNlck5vdEV4aXN0ELgCEhAKC1RleHRUb29Mb25nEJADEhMKDkJsb2NrSWRJc0VtcHR5EJEDEhEKDFJvd0lkSXNFbXB0eRCSAxISCg1HcmlkSWRJc0VtcHR5EJMDEhAKC0ludmFsaWREYXRhEJQD');

View File

@ -9,15 +9,13 @@ import 'dart:core' as $core;
import 'package:protobuf/protobuf.dart' as $pb;
import 'meta.pb.dart' as $0;
import 'meta.pbenum.dart' as $0;
class Grid extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Grid', createEmptyInstance: create)
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id')
..pc<FieldOrder>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldOrders', $pb.PbFieldType.PM, subBuilder: FieldOrder.create)
..pc<$0.GridBlockMeta>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blocks', $pb.PbFieldType.PM, subBuilder: $0.GridBlockMeta.create)
..pc<GridBlockOrder>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockOrders', $pb.PbFieldType.PM, subBuilder: GridBlockOrder.create)
..hasRequiredFields = false
;
@ -25,7 +23,7 @@ class Grid extends $pb.GeneratedMessage {
factory Grid({
$core.String? id,
$core.Iterable<FieldOrder>? fieldOrders,
$core.Iterable<$0.GridBlockMeta>? blocks,
$core.Iterable<GridBlockOrder>? blockOrders,
}) {
final _result = create();
if (id != null) {
@ -34,8 +32,8 @@ class Grid extends $pb.GeneratedMessage {
if (fieldOrders != null) {
_result.fieldOrders.addAll(fieldOrders);
}
if (blocks != null) {
_result.blocks.addAll(blocks);
if (blockOrders != null) {
_result.blockOrders.addAll(blockOrders);
}
return _result;
}
@ -73,7 +71,7 @@ class Grid extends $pb.GeneratedMessage {
$core.List<FieldOrder> get fieldOrders => $_getList(1);
@$pb.TagNumber(3)
$core.List<$0.GridBlockMeta> get blocks => $_getList(2);
$core.List<GridBlockOrder> get blockOrders => $_getList(2);
}
class Field extends $pb.GeneratedMessage {
@ -507,6 +505,47 @@ class Row extends $pb.GeneratedMessage {
void clearHeight() => clearField(3);
}
class RepeatedRow extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedRow', createEmptyInstance: create)
..pc<Row>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: Row.create)
..hasRequiredFields = false
;
RepeatedRow._() : super();
factory RepeatedRow({
$core.Iterable<Row>? items,
}) {
final _result = create();
if (items != null) {
_result.items.addAll(items);
}
return _result;
}
factory RepeatedRow.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory RepeatedRow.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')
RepeatedRow clone() => RepeatedRow()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
RepeatedRow copyWith(void Function(RepeatedRow) updates) => super.copyWith((message) => updates(message as RepeatedRow)) as RepeatedRow; // ignore: deprecated_member_use
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static RepeatedRow create() => RepeatedRow._();
RepeatedRow createEmptyInstance() => create();
static $pb.PbList<RepeatedRow> createRepeated() => $pb.PbList<RepeatedRow>();
@$core.pragma('dart2js:noInline')
static RepeatedRow getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<RepeatedRow>(create);
static RepeatedRow? _defaultInstance;
@$pb.TagNumber(1)
$core.List<Row> get items => $_getList(0);
}
class RepeatedGridBlock extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedGridBlock', createEmptyInstance: create)
..pc<GridBlock>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: GridBlock.create)
@ -548,24 +587,71 @@ class RepeatedGridBlock extends $pb.GeneratedMessage {
$core.List<GridBlock> get items => $_getList(0);
}
class GridBlockOrder extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlockOrder', createEmptyInstance: create)
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId')
..hasRequiredFields = false
;
GridBlockOrder._() : super();
factory GridBlockOrder({
$core.String? blockId,
}) {
final _result = create();
if (blockId != null) {
_result.blockId = blockId;
}
return _result;
}
factory GridBlockOrder.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory GridBlockOrder.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')
GridBlockOrder clone() => GridBlockOrder()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
GridBlockOrder copyWith(void Function(GridBlockOrder) updates) => super.copyWith((message) => updates(message as GridBlockOrder)) as GridBlockOrder; // ignore: deprecated_member_use
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static GridBlockOrder create() => GridBlockOrder._();
GridBlockOrder createEmptyInstance() => create();
static $pb.PbList<GridBlockOrder> createRepeated() => $pb.PbList<GridBlockOrder>();
@$core.pragma('dart2js:noInline')
static GridBlockOrder getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<GridBlockOrder>(create);
static GridBlockOrder? _defaultInstance;
@$pb.TagNumber(1)
$core.String get blockId => $_getSZ(0);
@$pb.TagNumber(1)
set blockId($core.String v) { $_setString(0, v); }
@$pb.TagNumber(1)
$core.bool hasBlockId() => $_has(0);
@$pb.TagNumber(1)
void clearBlockId() => clearField(1);
}
class GridBlock extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlock', createEmptyInstance: create)
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId')
..pc<Row>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rows', $pb.PbFieldType.PM, subBuilder: Row.create)
..pPS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowIds')
..hasRequiredFields = false
;
GridBlock._() : super();
factory GridBlock({
$core.String? blockId,
$core.Iterable<Row>? rows,
$core.Iterable<$core.String>? rowIds,
}) {
final _result = create();
if (blockId != null) {
_result.blockId = blockId;
}
if (rows != null) {
_result.rows.addAll(rows);
if (rowIds != null) {
_result.rowIds.addAll(rowIds);
}
return _result;
}
@ -600,7 +686,7 @@ class GridBlock extends $pb.GeneratedMessage {
void clearBlockId() => clearField(1);
@$pb.TagNumber(2)
$core.List<Row> get rows => $_getList(1);
$core.List<$core.String> get rowIds => $_getList(1);
}
class Cell extends $pb.GeneratedMessage {
@ -846,34 +932,34 @@ class GridBlockId extends $pb.GeneratedMessage {
void clearValue() => clearField(1);
}
enum CreateRowPayload_OneOfUpperRowId {
upperRowId,
enum CreateRowPayload_OneOfStartRowId {
startRowId,
notSet
}
class CreateRowPayload extends $pb.GeneratedMessage {
static const $core.Map<$core.int, CreateRowPayload_OneOfUpperRowId> _CreateRowPayload_OneOfUpperRowIdByTag = {
2 : CreateRowPayload_OneOfUpperRowId.upperRowId,
0 : CreateRowPayload_OneOfUpperRowId.notSet
static const $core.Map<$core.int, CreateRowPayload_OneOfStartRowId> _CreateRowPayload_OneOfStartRowIdByTag = {
2 : CreateRowPayload_OneOfStartRowId.startRowId,
0 : CreateRowPayload_OneOfStartRowId.notSet
};
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CreateRowPayload', createEmptyInstance: create)
..oo(0, [2])
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId')
..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'upperRowId')
..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'startRowId')
..hasRequiredFields = false
;
CreateRowPayload._() : super();
factory CreateRowPayload({
$core.String? gridId,
$core.String? upperRowId,
$core.String? startRowId,
}) {
final _result = create();
if (gridId != null) {
_result.gridId = gridId;
}
if (upperRowId != null) {
_result.upperRowId = upperRowId;
if (startRowId != null) {
_result.startRowId = startRowId;
}
return _result;
}
@ -898,8 +984,8 @@ class CreateRowPayload extends $pb.GeneratedMessage {
static CreateRowPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<CreateRowPayload>(create);
static CreateRowPayload? _defaultInstance;
CreateRowPayload_OneOfUpperRowId whichOneOfUpperRowId() => _CreateRowPayload_OneOfUpperRowIdByTag[$_whichOneof(0)]!;
void clearOneOfUpperRowId() => clearField($_whichOneof(0));
CreateRowPayload_OneOfStartRowId whichOneOfStartRowId() => _CreateRowPayload_OneOfStartRowIdByTag[$_whichOneof(0)]!;
void clearOneOfStartRowId() => clearField($_whichOneof(0));
@$pb.TagNumber(1)
$core.String get gridId => $_getSZ(0);
@ -911,13 +997,13 @@ class CreateRowPayload extends $pb.GeneratedMessage {
void clearGridId() => clearField(1);
@$pb.TagNumber(2)
$core.String get upperRowId => $_getSZ(1);
$core.String get startRowId => $_getSZ(1);
@$pb.TagNumber(2)
set upperRowId($core.String v) { $_setString(1, v); }
set startRowId($core.String v) { $_setString(1, v); }
@$pb.TagNumber(2)
$core.bool hasUpperRowId() => $_has(1);
$core.bool hasStartRowId() => $_has(1);
@$pb.TagNumber(2)
void clearUpperRowId() => clearField(2);
void clearStartRowId() => clearField(2);
}
class QueryFieldPayload extends $pb.GeneratedMessage {
@ -986,21 +1072,21 @@ class QueryFieldPayload extends $pb.GeneratedMessage {
class QueryGridBlocksPayload extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'QueryGridBlocksPayload', createEmptyInstance: create)
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId')
..pc<$0.GridBlockMeta>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blocks', $pb.PbFieldType.PM, subBuilder: $0.GridBlockMeta.create)
..pc<GridBlockOrder>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockOrders', $pb.PbFieldType.PM, subBuilder: GridBlockOrder.create)
..hasRequiredFields = false
;
QueryGridBlocksPayload._() : super();
factory QueryGridBlocksPayload({
$core.String? gridId,
$core.Iterable<$0.GridBlockMeta>? blocks,
$core.Iterable<GridBlockOrder>? blockOrders,
}) {
final _result = create();
if (gridId != null) {
_result.gridId = gridId;
}
if (blocks != null) {
_result.blocks.addAll(blocks);
if (blockOrders != null) {
_result.blockOrders.addAll(blockOrders);
}
return _result;
}
@ -1035,6 +1121,81 @@ class QueryGridBlocksPayload extends $pb.GeneratedMessage {
void clearGridId() => clearField(1);
@$pb.TagNumber(2)
$core.List<$0.GridBlockMeta> get blocks => $_getList(1);
$core.List<GridBlockOrder> get blockOrders => $_getList(1);
}
class QueryRowPayload extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'QueryRowPayload', createEmptyInstance: create)
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId')
..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId')
..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowId')
..hasRequiredFields = false
;
QueryRowPayload._() : super();
factory QueryRowPayload({
$core.String? gridId,
$core.String? blockId,
$core.String? rowId,
}) {
final _result = create();
if (gridId != null) {
_result.gridId = gridId;
}
if (blockId != null) {
_result.blockId = blockId;
}
if (rowId != null) {
_result.rowId = rowId;
}
return _result;
}
factory QueryRowPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory QueryRowPayload.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')
QueryRowPayload clone() => QueryRowPayload()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
QueryRowPayload copyWith(void Function(QueryRowPayload) updates) => super.copyWith((message) => updates(message as QueryRowPayload)) as QueryRowPayload; // ignore: deprecated_member_use
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static QueryRowPayload create() => QueryRowPayload._();
QueryRowPayload createEmptyInstance() => create();
static $pb.PbList<QueryRowPayload> createRepeated() => $pb.PbList<QueryRowPayload>();
@$core.pragma('dart2js:noInline')
static QueryRowPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<QueryRowPayload>(create);
static QueryRowPayload? _defaultInstance;
@$pb.TagNumber(1)
$core.String get gridId => $_getSZ(0);
@$pb.TagNumber(1)
set gridId($core.String v) { $_setString(0, v); }
@$pb.TagNumber(1)
$core.bool hasGridId() => $_has(0);
@$pb.TagNumber(1)
void clearGridId() => clearField(1);
@$pb.TagNumber(2)
$core.String get blockId => $_getSZ(1);
@$pb.TagNumber(2)
set blockId($core.String v) { $_setString(1, v); }
@$pb.TagNumber(2)
$core.bool hasBlockId() => $_has(1);
@$pb.TagNumber(2)
void clearBlockId() => clearField(2);
@$pb.TagNumber(3)
$core.String get rowId => $_getSZ(2);
@$pb.TagNumber(3)
set rowId($core.String v) { $_setString(2, v); }
@$pb.TagNumber(3)
$core.bool hasRowId() => $_has(2);
@$pb.TagNumber(3)
void clearRowId() => clearField(3);
}

View File

@ -14,12 +14,12 @@ const Grid$json = const {
'2': const [
const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
const {'1': 'field_orders', '3': 2, '4': 3, '5': 11, '6': '.FieldOrder', '10': 'fieldOrders'},
const {'1': 'blocks', '3': 3, '4': 3, '5': 11, '6': '.GridBlockMeta', '10': 'blocks'},
const {'1': 'block_orders', '3': 3, '4': 3, '5': 11, '6': '.GridBlockOrder', '10': 'blockOrders'},
],
};
/// Descriptor for `Grid`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List gridDescriptor = $convert.base64Decode('CgRHcmlkEg4KAmlkGAEgASgJUgJpZBIuCgxmaWVsZF9vcmRlcnMYAiADKAsyCy5GaWVsZE9yZGVyUgtmaWVsZE9yZGVycxImCgZibG9ja3MYAyADKAsyDi5HcmlkQmxvY2tNZXRhUgZibG9ja3M=');
final $typed_data.Uint8List gridDescriptor = $convert.base64Decode('CgRHcmlkEg4KAmlkGAEgASgJUgJpZBIuCgxmaWVsZF9vcmRlcnMYAiADKAsyCy5GaWVsZE9yZGVyUgtmaWVsZE9yZGVycxIyCgxibG9ja19vcmRlcnMYAyADKAsyDy5HcmlkQmxvY2tPcmRlclILYmxvY2tPcmRlcnM=');
@$core.Deprecated('Use fieldDescriptor instead')
const Field$json = const {
'1': 'Field',
@ -110,6 +110,16 @@ const Row_CellByFieldIdEntry$json = const {
/// Descriptor for `Row`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List rowDescriptor = $convert.base64Decode('CgNSb3cSDgoCaWQYASABKAlSAmlkEkAKEGNlbGxfYnlfZmllbGRfaWQYAiADKAsyFy5Sb3cuQ2VsbEJ5RmllbGRJZEVudHJ5Ug1jZWxsQnlGaWVsZElkEhYKBmhlaWdodBgDIAEoBVIGaGVpZ2h0GkcKEkNlbGxCeUZpZWxkSWRFbnRyeRIQCgNrZXkYASABKAlSA2tleRIbCgV2YWx1ZRgCIAEoCzIFLkNlbGxSBXZhbHVlOgI4AQ==');
@$core.Deprecated('Use repeatedRowDescriptor instead')
const RepeatedRow$json = const {
'1': 'RepeatedRow',
'2': const [
const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.Row', '10': 'items'},
],
};
/// Descriptor for `RepeatedRow`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List repeatedRowDescriptor = $convert.base64Decode('CgtSZXBlYXRlZFJvdxIaCgVpdGVtcxgBIAMoCzIELlJvd1IFaXRlbXM=');
@$core.Deprecated('Use repeatedGridBlockDescriptor instead')
const RepeatedGridBlock$json = const {
'1': 'RepeatedGridBlock',
@ -120,17 +130,27 @@ const RepeatedGridBlock$json = const {
/// Descriptor for `RepeatedGridBlock`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List repeatedGridBlockDescriptor = $convert.base64Decode('ChFSZXBlYXRlZEdyaWRCbG9jaxIgCgVpdGVtcxgBIAMoCzIKLkdyaWRCbG9ja1IFaXRlbXM=');
@$core.Deprecated('Use gridBlockOrderDescriptor instead')
const GridBlockOrder$json = const {
'1': 'GridBlockOrder',
'2': const [
const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'},
],
};
/// Descriptor for `GridBlockOrder`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List gridBlockOrderDescriptor = $convert.base64Decode('Cg5HcmlkQmxvY2tPcmRlchIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZA==');
@$core.Deprecated('Use gridBlockDescriptor instead')
const GridBlock$json = const {
'1': 'GridBlock',
'2': const [
const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'},
const {'1': 'rows', '3': 2, '4': 3, '5': 11, '6': '.Row', '10': 'rows'},
const {'1': 'row_ids', '3': 2, '4': 3, '5': 9, '10': 'rowIds'},
],
};
/// Descriptor for `GridBlock`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List gridBlockDescriptor = $convert.base64Decode('CglHcmlkQmxvY2sSGQoIYmxvY2tfaWQYASABKAlSB2Jsb2NrSWQSGAoEcm93cxgCIAMoCzIELlJvd1IEcm93cw==');
final $typed_data.Uint8List gridBlockDescriptor = $convert.base64Decode('CglHcmlkQmxvY2sSGQoIYmxvY2tfaWQYASABKAlSB2Jsb2NrSWQSFwoHcm93X2lkcxgCIAMoCVIGcm93SWRz');
@$core.Deprecated('Use cellDescriptor instead')
const Cell$json = const {
'1': 'Cell',
@ -187,15 +207,15 @@ const CreateRowPayload$json = const {
'1': 'CreateRowPayload',
'2': const [
const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'},
const {'1': 'upper_row_id', '3': 2, '4': 1, '5': 9, '9': 0, '10': 'upperRowId'},
const {'1': 'start_row_id', '3': 2, '4': 1, '5': 9, '9': 0, '10': 'startRowId'},
],
'8': const [
const {'1': 'one_of_upper_row_id'},
const {'1': 'one_of_start_row_id'},
],
};
/// Descriptor for `CreateRowPayload`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List createRowPayloadDescriptor = $convert.base64Decode('ChBDcmVhdGVSb3dQYXlsb2FkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIiCgx1cHBlcl9yb3dfaWQYAiABKAlIAFIKdXBwZXJSb3dJZEIVChNvbmVfb2ZfdXBwZXJfcm93X2lk');
final $typed_data.Uint8List createRowPayloadDescriptor = $convert.base64Decode('ChBDcmVhdGVSb3dQYXlsb2FkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIiCgxzdGFydF9yb3dfaWQYAiABKAlIAFIKc3RhcnRSb3dJZEIVChNvbmVfb2Zfc3RhcnRfcm93X2lk');
@$core.Deprecated('Use queryFieldPayloadDescriptor instead')
const QueryFieldPayload$json = const {
'1': 'QueryFieldPayload',
@ -212,9 +232,21 @@ const QueryGridBlocksPayload$json = const {
'1': 'QueryGridBlocksPayload',
'2': const [
const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'},
const {'1': 'blocks', '3': 2, '4': 3, '5': 11, '6': '.GridBlockMeta', '10': 'blocks'},
const {'1': 'block_orders', '3': 2, '4': 3, '5': 11, '6': '.GridBlockOrder', '10': 'blockOrders'},
],
};
/// Descriptor for `QueryGridBlocksPayload`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List queryGridBlocksPayloadDescriptor = $convert.base64Decode('ChZRdWVyeUdyaWRCbG9ja3NQYXlsb2FkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBImCgZibG9ja3MYAiADKAsyDi5HcmlkQmxvY2tNZXRhUgZibG9ja3M=');
final $typed_data.Uint8List queryGridBlocksPayloadDescriptor = $convert.base64Decode('ChZRdWVyeUdyaWRCbG9ja3NQYXlsb2FkEhcKB2dyaWRfaWQYASABKAlSBmdyaWRJZBIyCgxibG9ja19vcmRlcnMYAiADKAsyDy5HcmlkQmxvY2tPcmRlclILYmxvY2tPcmRlcnM=');
@$core.Deprecated('Use queryRowPayloadDescriptor instead')
const QueryRowPayload$json = const {
'1': 'QueryRowPayload',
'2': const [
const {'1': 'grid_id', '3': 1, '4': 1, '5': 9, '10': 'gridId'},
const {'1': 'block_id', '3': 2, '4': 1, '5': 9, '10': 'blockId'},
const {'1': 'row_id', '3': 3, '4': 1, '5': 9, '10': 'rowId'},
],
};
/// Descriptor for `QueryRowPayload`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List queryRowPayloadDescriptor = $convert.base64Decode('Cg9RdWVyeVJvd1BheWxvYWQSFwoHZ3JpZF9pZBgBIAEoCVIGZ3JpZElkEhkKCGJsb2NrX2lkGAIgASgJUgdibG9ja0lkEhUKBnJvd19pZBgDIAEoCVIFcm93SWQ=');

View File

@ -17,7 +17,7 @@ class GridMeta extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridMeta', createEmptyInstance: create)
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridId')
..pc<FieldMeta>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fields', $pb.PbFieldType.PM, subBuilder: FieldMeta.create)
..pc<GridBlockMeta>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blocks', $pb.PbFieldType.PM, subBuilder: GridBlockMeta.create)
..pc<GridBlockMeta>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockMetas', $pb.PbFieldType.PM, subBuilder: GridBlockMeta.create)
..hasRequiredFields = false
;
@ -25,7 +25,7 @@ class GridMeta extends $pb.GeneratedMessage {
factory GridMeta({
$core.String? gridId,
$core.Iterable<FieldMeta>? fields,
$core.Iterable<GridBlockMeta>? blocks,
$core.Iterable<GridBlockMeta>? blockMetas,
}) {
final _result = create();
if (gridId != null) {
@ -34,8 +34,8 @@ class GridMeta extends $pb.GeneratedMessage {
if (fields != null) {
_result.fields.addAll(fields);
}
if (blocks != null) {
_result.blocks.addAll(blocks);
if (blockMetas != null) {
_result.blockMetas.addAll(blockMetas);
}
return _result;
}
@ -73,7 +73,7 @@ class GridMeta extends $pb.GeneratedMessage {
$core.List<FieldMeta> get fields => $_getList(1);
@$pb.TagNumber(3)
$core.List<GridBlockMeta> get blocks => $_getList(2);
$core.List<GridBlockMeta> get blockMetas => $_getList(2);
}
class GridBlockMeta extends $pb.GeneratedMessage {
@ -151,15 +151,15 @@ class GridBlockMeta extends $pb.GeneratedMessage {
void clearRowCount() => clearField(3);
}
class GridBlockMetaData extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlockMetaData', createEmptyInstance: create)
class GridBlockMetaSerde extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlockMetaSerde', createEmptyInstance: create)
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId')
..pc<RowMeta>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowMetas', $pb.PbFieldType.PM, subBuilder: RowMeta.create)
..hasRequiredFields = false
;
GridBlockMetaData._() : super();
factory GridBlockMetaData({
GridBlockMetaSerde._() : super();
factory GridBlockMetaSerde({
$core.String? blockId,
$core.Iterable<RowMeta>? rowMetas,
}) {
@ -172,26 +172,26 @@ class GridBlockMetaData extends $pb.GeneratedMessage {
}
return _result;
}
factory GridBlockMetaData.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory GridBlockMetaData.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
factory GridBlockMetaSerde.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory GridBlockMetaSerde.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')
GridBlockMetaData clone() => GridBlockMetaData()..mergeFromMessage(this);
GridBlockMetaSerde clone() => GridBlockMetaSerde()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
GridBlockMetaData copyWith(void Function(GridBlockMetaData) updates) => super.copyWith((message) => updates(message as GridBlockMetaData)) as GridBlockMetaData; // ignore: deprecated_member_use
GridBlockMetaSerde copyWith(void Function(GridBlockMetaSerde) updates) => super.copyWith((message) => updates(message as GridBlockMetaSerde)) as GridBlockMetaSerde; // ignore: deprecated_member_use
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static GridBlockMetaData create() => GridBlockMetaData._();
GridBlockMetaData createEmptyInstance() => create();
static $pb.PbList<GridBlockMetaData> createRepeated() => $pb.PbList<GridBlockMetaData>();
static GridBlockMetaSerde create() => GridBlockMetaSerde._();
GridBlockMetaSerde createEmptyInstance() => create();
static $pb.PbList<GridBlockMetaSerde> createRepeated() => $pb.PbList<GridBlockMetaSerde>();
@$core.pragma('dart2js:noInline')
static GridBlockMetaData getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<GridBlockMetaData>(create);
static GridBlockMetaData? _defaultInstance;
static GridBlockMetaSerde getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<GridBlockMetaSerde>(create);
static GridBlockMetaSerde? _defaultInstance;
@$pb.TagNumber(1)
$core.String get blockId => $_getSZ(0);
@ -1020,26 +1020,26 @@ class CellMetaChangeset extends $pb.GeneratedMessage {
class BuildGridContext extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'BuildGridContext', createEmptyInstance: create)
..pc<FieldMeta>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldMetas', $pb.PbFieldType.PM, subBuilder: FieldMeta.create)
..aOM<GridBlockMeta>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridBlock', subBuilder: GridBlockMeta.create)
..aOM<GridBlockMetaData>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridBlockMetaData', subBuilder: GridBlockMetaData.create)
..aOM<GridBlockMeta>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockMetas', subBuilder: GridBlockMeta.create)
..aOM<GridBlockMetaSerde>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockMetaData', subBuilder: GridBlockMetaSerde.create)
..hasRequiredFields = false
;
BuildGridContext._() : super();
factory BuildGridContext({
$core.Iterable<FieldMeta>? fieldMetas,
GridBlockMeta? gridBlock,
GridBlockMetaData? gridBlockMetaData,
GridBlockMeta? blockMetas,
GridBlockMetaSerde? blockMetaData,
}) {
final _result = create();
if (fieldMetas != null) {
_result.fieldMetas.addAll(fieldMetas);
}
if (gridBlock != null) {
_result.gridBlock = gridBlock;
if (blockMetas != null) {
_result.blockMetas = blockMetas;
}
if (gridBlockMetaData != null) {
_result.gridBlockMetaData = gridBlockMetaData;
if (blockMetaData != null) {
_result.blockMetaData = blockMetaData;
}
return _result;
}
@ -1068,25 +1068,25 @@ class BuildGridContext extends $pb.GeneratedMessage {
$core.List<FieldMeta> get fieldMetas => $_getList(0);
@$pb.TagNumber(2)
GridBlockMeta get gridBlock => $_getN(1);
GridBlockMeta get blockMetas => $_getN(1);
@$pb.TagNumber(2)
set gridBlock(GridBlockMeta v) { setField(2, v); }
set blockMetas(GridBlockMeta v) { setField(2, v); }
@$pb.TagNumber(2)
$core.bool hasGridBlock() => $_has(1);
$core.bool hasBlockMetas() => $_has(1);
@$pb.TagNumber(2)
void clearGridBlock() => clearField(2);
void clearBlockMetas() => clearField(2);
@$pb.TagNumber(2)
GridBlockMeta ensureGridBlock() => $_ensure(1);
GridBlockMeta ensureBlockMetas() => $_ensure(1);
@$pb.TagNumber(3)
GridBlockMetaData get gridBlockMetaData => $_getN(2);
GridBlockMetaSerde get blockMetaData => $_getN(2);
@$pb.TagNumber(3)
set gridBlockMetaData(GridBlockMetaData v) { setField(3, v); }
set blockMetaData(GridBlockMetaSerde v) { setField(3, v); }
@$pb.TagNumber(3)
$core.bool hasGridBlockMetaData() => $_has(2);
$core.bool hasBlockMetaData() => $_has(2);
@$pb.TagNumber(3)
void clearGridBlockMetaData() => clearField(3);
void clearBlockMetaData() => clearField(3);
@$pb.TagNumber(3)
GridBlockMetaData ensureGridBlockMetaData() => $_ensure(2);
GridBlockMetaSerde ensureBlockMetaData() => $_ensure(2);
}

View File

@ -29,12 +29,12 @@ const GridMeta$json = const {
'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'},
const {'1': 'block_metas', '3': 3, '4': 3, '5': 11, '6': '.GridBlockMeta', '10': 'blockMetas'},
],
};
/// Descriptor for `GridMeta`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List gridMetaDescriptor = $convert.base64Decode('CghHcmlkTWV0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSIgoGZmllbGRzGAIgAygLMgouRmllbGRNZXRhUgZmaWVsZHMSJgoGYmxvY2tzGAMgAygLMg4uR3JpZEJsb2NrTWV0YVIGYmxvY2tz');
final $typed_data.Uint8List gridMetaDescriptor = $convert.base64Decode('CghHcmlkTWV0YRIXCgdncmlkX2lkGAEgASgJUgZncmlkSWQSIgoGZmllbGRzGAIgAygLMgouRmllbGRNZXRhUgZmaWVsZHMSLwoLYmxvY2tfbWV0YXMYAyADKAsyDi5HcmlkQmxvY2tNZXRhUgpibG9ja01ldGFz');
@$core.Deprecated('Use gridBlockMetaDescriptor instead')
const GridBlockMeta$json = const {
'1': 'GridBlockMeta',
@ -47,17 +47,17 @@ const GridBlockMeta$json = const {
/// 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',
@$core.Deprecated('Use gridBlockMetaSerdeDescriptor instead')
const GridBlockMetaSerde$json = const {
'1': 'GridBlockMetaSerde',
'2': const [
const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'},
const {'1': 'row_metas', '3': 2, '4': 3, '5': 11, '6': '.RowMeta', '10': 'rowMetas'},
],
};
/// Descriptor for `GridBlockMetaData`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List gridBlockMetaDataDescriptor = $convert.base64Decode('ChFHcmlkQmxvY2tNZXRhRGF0YRIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZBIlCglyb3dfbWV0YXMYAiADKAsyCC5Sb3dNZXRhUghyb3dNZXRhcw==');
/// Descriptor for `GridBlockMetaSerde`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List gridBlockMetaSerdeDescriptor = $convert.base64Decode('ChJHcmlkQmxvY2tNZXRhU2VyZGUSGQoIYmxvY2tfaWQYASABKAlSB2Jsb2NrSWQSJQoJcm93X21ldGFzGAIgAygLMgguUm93TWV0YVIIcm93TWV0YXM=');
@$core.Deprecated('Use fieldMetaDescriptor instead')
const FieldMeta$json = const {
'1': 'FieldMeta',
@ -197,10 +197,10 @@ const BuildGridContext$json = const {
'1': 'BuildGridContext',
'2': const [
const {'1': 'field_metas', '3': 1, '4': 3, '5': 11, '6': '.FieldMeta', '10': 'fieldMetas'},
const {'1': 'grid_block', '3': 2, '4': 1, '5': 11, '6': '.GridBlockMeta', '10': 'gridBlock'},
const {'1': 'grid_block_meta_data', '3': 3, '4': 1, '5': 11, '6': '.GridBlockMetaData', '10': 'gridBlockMetaData'},
const {'1': 'block_metas', '3': 2, '4': 1, '5': 11, '6': '.GridBlockMeta', '10': 'blockMetas'},
const {'1': 'block_meta_data', '3': 3, '4': 1, '5': 11, '6': '.GridBlockMetaSerde', '10': 'blockMetaData'},
],
};
/// Descriptor for `BuildGridContext`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List buildGridContextDescriptor = $convert.base64Decode('ChBCdWlsZEdyaWRDb250ZXh0EisKC2ZpZWxkX21ldGFzGAEgAygLMgouRmllbGRNZXRhUgpmaWVsZE1ldGFzEi0KCmdyaWRfYmxvY2sYAiABKAsyDi5HcmlkQmxvY2tNZXRhUglncmlkQmxvY2sSQwoUZ3JpZF9ibG9ja19tZXRhX2RhdGEYAyABKAsyEi5HcmlkQmxvY2tNZXRhRGF0YVIRZ3JpZEJsb2NrTWV0YURhdGE=');
final $typed_data.Uint8List buildGridContextDescriptor = $convert.base64Decode('ChBCdWlsZEdyaWRDb250ZXh0EisKC2ZpZWxkX21ldGFzGAEgAygLMgouRmllbGRNZXRhUgpmaWVsZE1ldGFzEi8KC2Jsb2NrX21ldGFzGAIgASgLMg4uR3JpZEJsb2NrTWV0YVIKYmxvY2tNZXRhcxI7Cg9ibG9ja19tZXRhX2RhdGEYAyABKAsyEy5HcmlkQmxvY2tNZXRhU2VyZGVSDWJsb2NrTWV0YURhdGE=');

View File

@ -12,12 +12,14 @@ import 'package:protobuf/protobuf.dart' as $pb;
class GridNotification extends $pb.ProtobufEnum {
static const GridNotification Unknown = GridNotification._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Unknown');
static const GridNotification GridDidUpdateBlock = GridNotification._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidUpdateBlock');
static const GridNotification GridDidCreateBlock = GridNotification._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidCreateBlock');
static const GridNotification GridDidUpdateCells = GridNotification._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidUpdateCells');
static const GridNotification GridDidUpdateFields = GridNotification._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GridDidUpdateFields');
static const $core.List<GridNotification> values = <GridNotification> [
Unknown,
GridDidUpdateBlock,
GridDidCreateBlock,
GridDidUpdateCells,
GridDidUpdateFields,
];

View File

@ -14,10 +14,11 @@ const GridNotification$json = const {
'2': const [
const {'1': 'Unknown', '2': 0},
const {'1': 'GridDidUpdateBlock', '2': 10},
const {'1': 'GridDidCreateBlock', '2': 11},
const {'1': 'GridDidUpdateCells', '2': 20},
const {'1': 'GridDidUpdateFields', '2': 30},
],
};
/// Descriptor for `GridNotification`. Decode as a `google.protobuf.EnumDescriptorProto`.
final $typed_data.Uint8List gridNotificationDescriptor = $convert.base64Decode('ChBHcmlkTm90aWZpY2F0aW9uEgsKB1Vua25vd24QABIWChJHcmlkRGlkVXBkYXRlQmxvY2sQChIWChJHcmlkRGlkVXBkYXRlQ2VsbHMQFBIXChNHcmlkRGlkVXBkYXRlRmllbGRzEB4=');
final $typed_data.Uint8List gridNotificationDescriptor = $convert.base64Decode('ChBHcmlkTm90aWZpY2F0aW9uEgsKB1Vua25vd24QABIWChJHcmlkRGlkVXBkYXRlQmxvY2sQChIWChJHcmlkRGlkQ3JlYXRlQmxvY2sQCxIWChJHcmlkRGlkVXBkYXRlQ2VsbHMQFBIXChNHcmlkRGlkVXBkYXRlRmllbGRzEB4=');

View File

@ -12,15 +12,17 @@ import 'package:protobuf/protobuf.dart' as $pb;
class GridEvent extends $pb.ProtobufEnum {
static const GridEvent GetGridData = GridEvent._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetGridData');
static const GridEvent GetGridBlocks = GridEvent._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetGridBlocks');
static const GridEvent GetFields = GridEvent._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetFields');
static const GridEvent CreateRow = GridEvent._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateRow');
static const GridEvent UpdateCell = GridEvent._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateCell');
static const GridEvent GetFields = GridEvent._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetFields');
static const GridEvent CreateRow = GridEvent._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateRow');
static const GridEvent GetRow = GridEvent._(12, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetRow');
static const GridEvent UpdateCell = GridEvent._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateCell');
static const $core.List<GridEvent> values = <GridEvent> [
GetGridData,
GetGridBlocks,
GetFields,
CreateRow,
GetRow,
UpdateCell,
];

View File

@ -14,11 +14,12 @@ const GridEvent$json = const {
'2': const [
const {'1': 'GetGridData', '2': 0},
const {'1': 'GetGridBlocks', '2': 1},
const {'1': 'GetFields', '2': 2},
const {'1': 'CreateRow', '2': 3},
const {'1': 'UpdateCell', '2': 4},
const {'1': 'GetFields', '2': 10},
const {'1': 'CreateRow', '2': 11},
const {'1': 'GetRow', '2': 12},
const {'1': 'UpdateCell', '2': 20},
],
};
/// Descriptor for `GridEvent`. Decode as a `google.protobuf.EnumDescriptorProto`.
final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAISDQoJQ3JlYXRlUm93EAMSDgoKVXBkYXRlQ2VsbBAE');
final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDQoJQ3JlYXRlUm93EAsSCgoGR2V0Um93EAwSDgoKVXBkYXRlQ2VsbBAU');

View File

@ -1088,6 +1088,7 @@ version = "0.1.0"
dependencies = [
"bytes",
"flowy-derive",
"flowy-error-code",
"lib-infra",
"protobuf",
"serde",

View File

@ -7,8 +7,8 @@ edition = "2018"
[lib]
name = "dart_ffi"
# this value will change depending on the target os
# default staticlib
crate-type = ["staticlib"]
# default cdylib
crate-type = ["cdylib"]
[dependencies]

View File

@ -1,9 +1,10 @@
use crate::manager::GridManager;
use flowy_error::FlowyError;
use flowy_grid_data_model::entities::{
CellMetaChangeset, CreateRowPayload, Field, Grid, GridId, QueryFieldPayload, QueryGridBlocksPayload, RepeatedField,
RepeatedGridBlock, Row,
CellMetaChangeset, CreateRowPayload, Field, Grid, GridId, QueryFieldPayload, QueryGridBlocksPayload,
QueryRowPayload, RepeatedField, RepeatedGridBlock, RepeatedRow, Row,
};
use flowy_grid_data_model::parser::{CreateRowParams, QueryFieldParams, QueryGridBlocksParams, QueryRowParams};
use lib_dispatch::prelude::{data_result, AppData, Data, DataResult};
use std::sync::Arc;
@ -23,20 +24,38 @@ pub(crate) async fn get_grid_blocks_handler(
data: Data<QueryGridBlocksPayload>,
manager: AppData<Arc<GridManager>>,
) -> DataResult<RepeatedGridBlock, FlowyError> {
let payload: QueryGridBlocksPayload = data.into_inner();
let editor = manager.get_grid_editor(&payload.grid_id)?;
let repeated_grid_block = editor.get_grid_blocks(Some(payload.blocks)).await?;
let params: QueryGridBlocksParams = data.into_inner().try_into()?;
let editor = manager.get_grid_editor(&params.grid_id)?;
let block_ids = params
.block_orders
.into_iter()
.map(|block| block.block_id)
.collect::<Vec<String>>();
let repeated_grid_block = editor.get_blocks(Some(block_ids)).await?;
data_result(repeated_grid_block)
}
#[tracing::instrument(level = "debug", skip(data, manager), err)]
pub(crate) async fn get_row_handler(
data: Data<QueryRowPayload>,
manager: AppData<Arc<GridManager>>,
) -> DataResult<Row, FlowyError> {
let params: QueryRowParams = data.into_inner().try_into()?;
let editor = manager.get_grid_editor(&params.grid_id)?;
match editor.get_row(&params.block_id, &params.row_id).await? {
None => Err(FlowyError::record_not_found().context("Can not find the row")),
Some(row) => data_result(row),
}
}
#[tracing::instrument(level = "debug", skip(data, manager), err)]
pub(crate) async fn get_fields_handler(
data: Data<QueryFieldPayload>,
manager: AppData<Arc<GridManager>>,
) -> DataResult<RepeatedField, FlowyError> {
let payload: QueryFieldPayload = data.into_inner();
let editor = manager.get_grid_editor(&payload.grid_id)?;
let field_metas = editor.get_field_metas(Some(payload.field_orders)).await?;
let params: QueryFieldParams = data.into_inner().try_into()?;
let editor = manager.get_grid_editor(&params.grid_id)?;
let field_metas = editor.get_field_metas(Some(params.field_orders)).await?;
let repeated_field: RepeatedField = field_metas.into_iter().map(Field::from).collect::<Vec<_>>().into();
data_result(repeated_field)
}
@ -46,9 +65,9 @@ pub(crate) async fn create_row_handler(
data: Data<CreateRowPayload>,
manager: AppData<Arc<GridManager>>,
) -> Result<(), FlowyError> {
let payload: CreateRowPayload = data.into_inner();
let editor = manager.get_grid_editor(payload.grid_id.as_ref())?;
let _ = editor.create_row(payload.upper_row_id).await?;
let params: CreateRowParams = data.into_inner().try_into()?;
let editor = manager.get_grid_editor(params.grid_id.as_ref())?;
let _ = editor.create_row(params.start_row_id).await?;
Ok(())
}

View File

@ -12,6 +12,7 @@ pub fn create(grid_manager: Arc<GridManager>) -> Module {
.event(GridEvent::GetGridBlocks, get_grid_blocks_handler)
.event(GridEvent::GetFields, get_fields_handler)
.event(GridEvent::CreateRow, create_row_handler)
.event(GridEvent::GetRow, get_row_handler)
.event(GridEvent::UpdateCell, update_cell_handler);
module
@ -27,11 +28,14 @@ pub enum GridEvent {
GetGridBlocks = 1,
#[event(input = "QueryFieldPayload", output = "RepeatedField")]
GetFields = 2,
GetFields = 10,
#[event(input = "CreateRowPayload", output = "Row")]
CreateRow = 3,
CreateRow = 11,
#[event(input = "QueryRowPayload", output = "Row")]
GetRow = 12,
#[event(input = "CellMetaChangeset")]
UpdateCell = 4,
UpdateCell = 20,
}

View File

@ -182,11 +182,11 @@ pub async fn make_grid_view_data(
grid_manager: Arc<GridManager>,
build_context: BuildGridContext,
) -> FlowyResult<Bytes> {
let block_id = build_context.grid_block.block_id.clone();
let block_id = build_context.block_metas.block_id.clone();
let grid_meta = GridMeta {
grid_id: view_id.to_string(),
fields: build_context.field_metas,
blocks: vec![build_context.grid_block],
block_metas: vec![build_context.block_metas],
};
let grid_meta_delta = make_grid_delta(&grid_meta);
@ -195,7 +195,7 @@ pub async fn make_grid_view_data(
Revision::initial_revision(user_id, view_id, grid_delta_data.clone()).into();
let _ = grid_manager.create_grid(view_id, repeated_revision).await?;
let grid_block_meta_delta = make_block_meta_delta(&build_context.grid_block_meta_data);
let grid_block_meta_delta = make_block_meta_delta(&build_context.block_meta_data);
let block_meta_delta_data = grid_block_meta_delta.to_delta_bytes();
let repeated_revision: RepeatedRevision =
Revision::initial_revision(user_id, &block_id, block_meta_delta_data).into();

View File

@ -27,6 +27,7 @@
pub enum GridNotification {
Unknown = 0,
GridDidUpdateBlock = 10,
GridDidCreateBlock = 11,
GridDidUpdateCells = 20,
GridDidUpdateFields = 30,
}
@ -40,6 +41,7 @@ impl ::protobuf::ProtobufEnum for GridNotification {
match value {
0 => ::std::option::Option::Some(GridNotification::Unknown),
10 => ::std::option::Option::Some(GridNotification::GridDidUpdateBlock),
11 => ::std::option::Option::Some(GridNotification::GridDidCreateBlock),
20 => ::std::option::Option::Some(GridNotification::GridDidUpdateCells),
30 => ::std::option::Option::Some(GridNotification::GridDidUpdateFields),
_ => ::std::option::Option::None
@ -50,6 +52,7 @@ impl ::protobuf::ProtobufEnum for GridNotification {
static values: &'static [GridNotification] = &[
GridNotification::Unknown,
GridNotification::GridDidUpdateBlock,
GridNotification::GridDidCreateBlock,
GridNotification::GridDidUpdateCells,
GridNotification::GridDidUpdateFields,
];
@ -80,9 +83,10 @@ impl ::protobuf::reflect::ProtobufValue for GridNotification {
}
static file_descriptor_proto_data: &'static [u8] = b"\
\n\x17dart_notification.proto*h\n\x10GridNotification\x12\x0b\n\x07Unkno\
wn\x10\0\x12\x16\n\x12GridDidUpdateBlock\x10\n\x12\x16\n\x12GridDidUpdat\
eCells\x10\x14\x12\x17\n\x13GridDidUpdateFields\x10\x1eb\x06proto3\
\n\x17dart_notification.proto*\x80\x01\n\x10GridNotification\x12\x0b\n\
\x07Unknown\x10\0\x12\x16\n\x12GridDidUpdateBlock\x10\n\x12\x16\n\x12Gri\
dDidCreateBlock\x10\x0b\x12\x16\n\x12GridDidUpdateCells\x10\x14\x12\x17\
\n\x13GridDidUpdateFields\x10\x1eb\x06proto3\
";
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

View File

@ -27,9 +27,10 @@
pub enum GridEvent {
GetGridData = 0,
GetGridBlocks = 1,
GetFields = 2,
CreateRow = 3,
UpdateCell = 4,
GetFields = 10,
CreateRow = 11,
GetRow = 12,
UpdateCell = 20,
}
impl ::protobuf::ProtobufEnum for GridEvent {
@ -41,9 +42,10 @@ impl ::protobuf::ProtobufEnum for GridEvent {
match value {
0 => ::std::option::Option::Some(GridEvent::GetGridData),
1 => ::std::option::Option::Some(GridEvent::GetGridBlocks),
2 => ::std::option::Option::Some(GridEvent::GetFields),
3 => ::std::option::Option::Some(GridEvent::CreateRow),
4 => ::std::option::Option::Some(GridEvent::UpdateCell),
10 => ::std::option::Option::Some(GridEvent::GetFields),
11 => ::std::option::Option::Some(GridEvent::CreateRow),
12 => ::std::option::Option::Some(GridEvent::GetRow),
20 => ::std::option::Option::Some(GridEvent::UpdateCell),
_ => ::std::option::Option::None
}
}
@ -54,6 +56,7 @@ impl ::protobuf::ProtobufEnum for GridEvent {
GridEvent::GetGridBlocks,
GridEvent::GetFields,
GridEvent::CreateRow,
GridEvent::GetRow,
GridEvent::UpdateCell,
];
values
@ -83,9 +86,10 @@ impl ::protobuf::reflect::ProtobufValue for GridEvent {
}
static file_descriptor_proto_data: &'static [u8] = b"\
\n\x0fevent_map.proto*]\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\0\x12\
\x11\n\rGetGridBlocks\x10\x01\x12\r\n\tGetFields\x10\x02\x12\r\n\tCreate\
Row\x10\x03\x12\x0e\n\nUpdateCell\x10\x04b\x06proto3\
\n\x0fevent_map.proto*i\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\0\x12\
\x11\n\rGetGridBlocks\x10\x01\x12\r\n\tGetFields\x10\n\x12\r\n\tCreateRo\
w\x10\x0b\x12\n\n\x06GetRow\x10\x0c\x12\x0e\n\nUpdateCell\x10\x14b\x06pr\
oto3\
";
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

View File

@ -3,6 +3,7 @@ syntax = "proto3";
enum GridNotification {
Unknown = 0;
GridDidUpdateBlock = 10;
GridDidCreateBlock = 11;
GridDidUpdateCells = 20;
GridDidUpdateFields = 30;
}

View File

@ -3,7 +3,8 @@ syntax = "proto3";
enum GridEvent {
GetGridData = 0;
GetGridBlocks = 1;
GetFields = 2;
CreateRow = 3;
UpdateCell = 4;
GetFields = 10;
CreateRow = 11;
GetRow = 12;
UpdateCell = 20;
}

View File

@ -1,14 +1,15 @@
use crate::manager::GridUser;
use crate::services::row::{make_cell, make_grid_blocks, make_row_ids_per_block, GridBlockMetaDataSnapshot};
use crate::services::row::{make_cell, make_row_ids_per_block, GridBlockMetaData};
use bytes::Bytes;
use crate::dart_notification::{send_dart_notification, GridNotification};
use dashmap::DashMap;
use flowy_collaboration::client_grid::{GridBlockMetaDataChange, GridBlockMetaDataPad};
use flowy_collaboration::client_grid::{GridBlockMetaChange, GridBlockMetaPad};
use flowy_collaboration::entities::revision::Revision;
use flowy_collaboration::util::make_delta_from_revisions;
use flowy_error::{FlowyError, FlowyResult};
use flowy_grid_data_model::entities::{
Cell, FieldMeta, GridBlockId, GridBlockMeta, GridBlockMetaChangeset, RepeatedCell, RepeatedRowOrder, RowMeta,
FieldMeta, GridBlockId, GridBlockMeta, GridBlockMetaChangeset, RepeatedCell, RepeatedRowOrder, RowMeta,
RowMetaChangeset, RowOrder,
};
use flowy_sync::disk::SQLiteGridBlockMetaRevisionPersistence;
@ -17,10 +18,7 @@ use flowy_sync::{
};
use lib_infra::future::FutureResult;
use lib_ot::core::PlainTextAttributes;
use std::collections::HashMap;
use crate::dart_notification::{send_dart_notification, GridNotification};
use std::sync::Arc;
use tokio::sync::RwLock;
@ -30,7 +28,7 @@ type BlockId = String;
pub(crate) struct GridBlockMetaEditorManager {
grid_id: String,
user: Arc<dyn GridUser>,
editor_map: DashMap<String, Arc<ClientGridBlockMetaDataEditor>>,
editor_map: DashMap<String, Arc<ClientGridBlockMetaEditor>>,
block_id_by_row_id: DashMap<BlockId, RowId>,
}
@ -49,7 +47,7 @@ impl GridBlockMetaEditorManager {
Ok(manager)
}
pub(crate) async fn get_editor(&self, block_id: &str) -> FlowyResult<Arc<ClientGridBlockMetaDataEditor>> {
pub(crate) async fn get_editor(&self, block_id: &str) -> FlowyResult<Arc<ClientGridBlockMetaEditor>> {
match self.editor_map.get(block_id) {
None => {
tracing::error!("The is a fatal error, block is not exist");
@ -124,6 +122,16 @@ impl GridBlockMetaEditorManager {
Ok(())
}
pub async fn get_row(&self, block_id: &str, row_id: &str) -> FlowyResult<Option<Arc<RowMeta>>> {
let editor = self.get_editor(block_id).await?;
let mut row_metas = editor.get_row_metas(Some(vec![row_id.to_owned()])).await?;
if row_metas.is_empty() {
Ok(None)
} else {
Ok(row_metas.pop())
}
}
pub async fn update_cells(&self, field_metas: &[FieldMeta], changeset: RowMetaChangeset) -> FlowyResult<()> {
let editor = self.get_editor_from_row_id(&changeset.row_id).await?;
let _ = editor.update_row(changeset.clone()).await?;
@ -131,10 +139,10 @@ impl GridBlockMetaEditorManager {
Ok(())
}
pub(crate) async fn get_block_meta_snapshot_from_blocks(
pub(crate) async fn get_block_meta_data_from_blocks(
&self,
grid_blocks: Vec<GridBlockMeta>,
) -> FlowyResult<Vec<GridBlockMetaDataSnapshot>> {
) -> FlowyResult<Vec<GridBlockMetaData>> {
let mut snapshots = vec![];
for grid_block in grid_blocks {
let editor = self.get_editor(&grid_block.block_id).await?;
@ -144,7 +152,7 @@ impl GridBlockMetaEditorManager {
.insert(row_meta.id.clone(), row_meta.block_id.clone());
});
snapshots.push(GridBlockMetaDataSnapshot {
snapshots.push(GridBlockMetaData {
block_id: grid_block.block_id,
row_metas,
});
@ -152,20 +160,17 @@ impl GridBlockMetaEditorManager {
Ok(snapshots)
}
pub(crate) async fn get_block_meta_snapshot_from_row_orders(
&self,
grid_block_metas: &Vec<GridBlockMeta>,
) -> FlowyResult<Vec<GridBlockMetaDataSnapshot>> {
pub(crate) async fn get_block_meta_data(&self, block_ids: &[String]) -> FlowyResult<Vec<GridBlockMetaData>> {
let mut snapshots = vec![];
for grid_block_meta in grid_block_metas {
let editor = self.get_editor(&grid_block_meta.block_id).await?;
for block_id in block_ids {
let editor = self.get_editor(&block_id).await?;
let row_metas = editor.get_row_metas(None).await?;
row_metas.iter().for_each(|row_meta| {
self.block_id_by_row_id
.insert(row_meta.id.clone(), row_meta.block_id.clone());
});
snapshots.push(GridBlockMetaDataSnapshot {
block_id: grid_block_meta.block_id.clone(),
snapshots.push(GridBlockMetaData {
block_id: block_id.clone(),
row_metas,
});
}
@ -182,7 +187,7 @@ impl GridBlockMetaEditorManager {
Ok(row_orders)
}
async fn get_editor_from_row_id(&self, row_id: &str) -> FlowyResult<Arc<ClientGridBlockMetaDataEditor>> {
async fn get_editor_from_row_id(&self, row_id: &str) -> FlowyResult<Arc<ClientGridBlockMetaEditor>> {
match self.block_id_by_row_id.get(row_id) {
None => {
let msg = format!(
@ -237,7 +242,7 @@ impl GridBlockMetaEditorManager {
async fn make_block_meta_editor_map(
user: &Arc<dyn GridUser>,
blocks: Vec<GridBlockMeta>,
) -> FlowyResult<DashMap<String, Arc<ClientGridBlockMetaDataEditor>>> {
) -> FlowyResult<DashMap<String, Arc<ClientGridBlockMetaEditor>>> {
let editor_map = DashMap::new();
for block in blocks {
let editor = make_block_meta_editor(user, &block.block_id).await?;
@ -247,10 +252,7 @@ async fn make_block_meta_editor_map(
Ok(editor_map)
}
async fn make_block_meta_editor(
user: &Arc<dyn GridUser>,
block_id: &str,
) -> FlowyResult<ClientGridBlockMetaDataEditor> {
async fn make_block_meta_editor(user: &Arc<dyn GridUser>, block_id: &str) -> FlowyResult<ClientGridBlockMetaEditor> {
let token = user.token()?;
let user_id = user.user_id()?;
let pool = user.db_pool()?;
@ -258,17 +260,17 @@ async fn make_block_meta_editor(
let disk_cache = Arc::new(SQLiteGridBlockMetaRevisionPersistence::new(&user_id, pool));
let rev_persistence = Arc::new(RevisionPersistence::new(&user_id, block_id, disk_cache));
let rev_manager = RevisionManager::new(&user_id, block_id, rev_persistence);
ClientGridBlockMetaDataEditor::new(&user_id, &token, block_id, rev_manager).await
ClientGridBlockMetaEditor::new(&user_id, &token, block_id, rev_manager).await
}
pub struct ClientGridBlockMetaDataEditor {
pub struct ClientGridBlockMetaEditor {
user_id: String,
pub block_id: String,
pad: Arc<RwLock<GridBlockMetaDataPad>>,
pad: Arc<RwLock<GridBlockMetaPad>>,
rev_manager: Arc<RevisionManager>,
}
impl ClientGridBlockMetaDataEditor {
impl ClientGridBlockMetaEditor {
pub async fn new(
user_id: &str,
token: &str,
@ -340,7 +342,7 @@ impl ClientGridBlockMetaDataEditor {
async fn modify<F>(&self, f: F) -> FlowyResult<()>
where
F: for<'a> FnOnce(&'a mut GridBlockMetaDataPad) -> FlowyResult<Option<GridBlockMetaDataChange>>,
F: for<'a> FnOnce(&'a mut GridBlockMetaPad) -> FlowyResult<Option<GridBlockMetaChange>>,
{
let mut write_guard = self.pad.write().await;
match f(&mut *write_guard)? {
@ -352,8 +354,8 @@ impl ClientGridBlockMetaDataEditor {
Ok(())
}
async fn apply_change(&self, change: GridBlockMetaDataChange) -> FlowyResult<()> {
let GridBlockMetaDataChange { delta, md5 } = change;
async fn apply_change(&self, change: GridBlockMetaChange) -> FlowyResult<()> {
let GridBlockMetaChange { delta, md5 } = change;
let user_id = self.user_id.clone();
let (base_rev_id, rev_id) = self.rev_manager.next_rev_id_pair();
let delta_data = delta.to_delta_bytes();
@ -387,10 +389,10 @@ impl RevisionCloudService for GridBlockMetaRevisionCloudService {
struct GridBlockMetaPadBuilder();
impl RevisionObjectBuilder for GridBlockMetaPadBuilder {
type Output = GridBlockMetaDataPad;
type Output = GridBlockMetaPad;
fn build_object(object_id: &str, revisions: Vec<Revision>) -> FlowyResult<Self::Output> {
let pad = GridBlockMetaDataPad::from_revisions(object_id, revisions)?;
let pad = GridBlockMetaPad::from_revisions(object_id, revisions)?;
Ok(pad)
}
}

View File

@ -7,14 +7,15 @@ use flowy_collaboration::util::make_delta_from_revisions;
use flowy_error::{FlowyError, FlowyResult};
use flowy_grid_data_model::entities::{
Cell, CellMetaChangeset, Field, FieldChangeset, FieldMeta, Grid, GridBlockMeta, GridBlockMetaChangeset,
RepeatedField, RepeatedFieldOrder, RepeatedGridBlock, RepeatedRowOrder, Row, RowMeta, RowMetaChangeset,
GridBlockOrder, RepeatedField, RepeatedFieldOrder, RepeatedGridBlock, RepeatedRow, RepeatedRowOrder, Row, RowMeta,
RowMetaChangeset,
};
use std::collections::HashMap;
use crate::dart_notification::{send_dart_notification, GridNotification};
use crate::services::row::{
make_grid_block_from_block_metas, make_grid_blocks, make_row_ids_per_block, row_meta_from_context,
serialize_cell_data, GridBlockMetaDataSnapshot, RowMetaContext, RowMetaContextBuilder,
make_grid_block_from_block_metas, make_grid_blocks, make_row_ids_per_block, make_rows_from_row_metas,
row_meta_from_context, serialize_cell_data, GridBlockMetaData, RowMetaContext, RowMetaContextBuilder,
};
use flowy_sync::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder};
use lib_infra::future::FutureResult;
@ -125,6 +126,33 @@ impl ClientGridEditor {
self.block_meta_manager.update_row(changeset).await
}
pub async fn get_rows(&self, block_id: &str) -> FlowyResult<RepeatedRow> {
let block_ids = vec![block_id.to_owned()];
let mut block_meta_data_vec = self.get_block_meta_data_vec(Some(&block_ids)).await?;
debug_assert_eq!(block_meta_data_vec.len(), 1);
if block_meta_data_vec.len() == 1 {
let block_meta_data = block_meta_data_vec.pop().unwrap();
let field_metas = self.get_field_metas(None).await?;
let rows = make_rows_from_row_metas(&field_metas, &block_meta_data.row_metas);
Ok(rows.into())
} else {
Ok(vec![].into())
}
}
pub async fn get_row(&self, block_id: &str, row_id: &str) -> FlowyResult<Option<Row>> {
match self.block_meta_manager.get_row(block_id, row_id).await? {
None => Ok(None),
Some(row) => {
let field_metas = self.get_field_metas(None).await?;
let row_metas = vec![row];
let mut rows = make_rows_from_row_metas(&field_metas, &row_metas);
debug_assert!(rows.len() == 1);
Ok(rows.pop())
}
}
}
pub async fn update_cell(&self, changeset: CellMetaChangeset) -> FlowyResult<()> {
if let Some(cell_data) = changeset.data.as_ref() {
match self.pad.read().await.get_field(&changeset.field_id) {
@ -147,41 +175,17 @@ impl ClientGridEditor {
Ok(())
}
pub async fn get_grid_blocks(
&self,
grid_block_metas: Option<Vec<GridBlockMeta>>,
) -> FlowyResult<RepeatedGridBlock> {
let grid_block_meta_snapshots = self.get_grid_block_meta_snapshots(grid_block_metas.as_ref()).await?;
let field_meta = self.pad.read().await.get_field_metas(None)?;
match grid_block_metas {
None => make_grid_blocks(&field_meta, grid_block_meta_snapshots),
Some(grid_block_metas) => {
make_grid_block_from_block_metas(&field_meta, grid_block_metas, grid_block_meta_snapshots)
}
pub async fn get_blocks(&self, block_ids: Option<Vec<String>>) -> FlowyResult<RepeatedGridBlock> {
let block_meta_data_vec = self.get_block_meta_data_vec(block_ids.as_ref()).await?;
match block_ids {
None => make_grid_blocks(block_meta_data_vec),
Some(block_ids) => make_grid_block_from_block_metas(&block_ids, block_meta_data_vec),
}
}
pub(crate) async fn get_grid_block_meta_snapshots(
&self,
grid_block_infos: Option<&Vec<GridBlockMeta>>,
) -> FlowyResult<Vec<GridBlockMetaDataSnapshot>> {
match grid_block_infos {
None => {
let grid_blocks = self.pad.read().await.get_blocks();
let row_metas_per_block = self
.block_meta_manager
.get_block_meta_snapshot_from_blocks(grid_blocks)
.await?;
Ok(row_metas_per_block)
}
Some(grid_block_infos) => {
let row_metas_per_block = self
.block_meta_manager
.get_block_meta_snapshot_from_row_orders(grid_block_infos)
.await?;
Ok(row_metas_per_block)
}
}
pub async fn get_block_metas(&self) -> FlowyResult<Vec<GridBlockMeta>> {
let grid_blocks = self.pad.read().await.get_blocks();
Ok(grid_blocks)
}
pub async fn delete_rows(&self, row_ids: Vec<String>) -> FlowyResult<()> {
@ -194,11 +198,20 @@ impl ClientGridEditor {
pub async fn grid_data(&self) -> FlowyResult<Grid> {
let field_orders = self.pad.read().await.get_field_orders();
let block_orders = self.pad.read().await.get_blocks();
let block_orders = self
.pad
.read()
.await
.get_blocks()
.into_iter()
.map(|grid_block_meta| GridBlockOrder {
block_id: grid_block_meta.block_id,
})
.collect::<Vec<_>>();
Ok(Grid {
id: self.grid_id.clone(),
field_orders,
blocks: block_orders,
block_orders,
})
}
@ -207,9 +220,27 @@ impl ClientGridEditor {
Ok(field_meta)
}
pub async fn get_blocks(&self) -> FlowyResult<Vec<GridBlockMeta>> {
let grid_blocks = self.pad.read().await.get_blocks();
Ok(grid_blocks)
pub async fn get_block_meta_data_vec(
&self,
block_ids: Option<&Vec<String>>,
) -> FlowyResult<Vec<GridBlockMetaData>> {
match block_ids {
None => {
let grid_blocks = self.pad.read().await.get_blocks();
let row_metas_per_block = self
.block_meta_manager
.get_block_meta_data_from_blocks(grid_blocks)
.await?;
Ok(row_metas_per_block)
}
Some(block_ids) => {
let row_metas_per_block = self
.block_meta_manager
.get_block_meta_data(block_ids.as_slice())
.await?;
Ok(row_metas_per_block)
}
}
}
pub async fn delta_bytes(&self) -> Bytes {

View File

@ -1,11 +1,11 @@
use crate::services::row::deserialize_cell_data;
use flowy_error::FlowyResult;
use flowy_grid_data_model::entities::{
Cell, CellMeta, FieldMeta, GridBlock, GridBlockMeta, RepeatedGridBlock, RepeatedRowOrder, Row, RowMeta, RowOrder,
Cell, CellMeta, FieldMeta, GridBlock, RepeatedGridBlock, RepeatedRowOrder, Row, RowMeta, RowOrder,
};
use rayon::iter::{IntoParallelIterator, ParallelIterator};
use std::collections::HashMap;
use std::ops::Deref;
use std::sync::Arc;
pub(crate) struct RowIdsPerBlock {
@ -22,9 +22,9 @@ impl RowIdsPerBlock {
}
}
pub(crate) struct GridBlockMetaDataSnapshot {
pub struct GridBlockMetaData {
pub(crate) block_id: String,
pub(crate) row_metas: Vec<Arc<RowMeta>>,
pub row_metas: Vec<Arc<RowMeta>>,
}
pub(crate) fn make_row_ids_per_block(row_orders: &[RowOrder]) -> Vec<RowIdsPerBlock> {
@ -40,17 +40,14 @@ pub(crate) fn make_row_ids_per_block(row_orders: &[RowOrder]) -> Vec<RowIdsPerBl
map.into_values().collect::<Vec<_>>()
}
pub(crate) fn make_grid_blocks(
field_metas: &[FieldMeta],
grid_block_meta_snapshots: Vec<GridBlockMetaDataSnapshot>,
) -> FlowyResult<RepeatedGridBlock> {
Ok(grid_block_meta_snapshots
pub(crate) fn make_grid_blocks(block_meta_snapshots: Vec<GridBlockMetaData>) -> FlowyResult<RepeatedGridBlock> {
Ok(block_meta_snapshots
.into_iter()
.map(|row_metas_per_block| {
let rows = make_rows_from_row_metas(field_metas, &row_metas_per_block.row_metas);
let row_ids = make_row_ids_from_row_metas(&row_metas_per_block.row_metas);
GridBlock {
block_id: row_metas_per_block.block_id,
rows,
row_ids,
}
})
.collect::<Vec<GridBlock>>()
@ -76,6 +73,10 @@ pub fn make_cell(
}
}
pub(crate) fn make_row_ids_from_row_metas(row_metas: &Vec<Arc<RowMeta>>) -> Vec<String> {
row_metas.iter().map(|row_meta| row_meta.id.clone()).collect::<Vec<_>>()
}
pub(crate) fn make_rows_from_row_metas(fields: &[FieldMeta], row_metas: &Vec<Arc<RowMeta>>) -> Vec<Row> {
let field_meta_map = fields
.iter()
@ -101,22 +102,21 @@ pub(crate) fn make_rows_from_row_metas(fields: &[FieldMeta], row_metas: &Vec<Arc
}
pub(crate) fn make_grid_block_from_block_metas(
field_metas: &[FieldMeta],
grid_block_metas: Vec<GridBlockMeta>,
grid_block_meta_snapshots: Vec<GridBlockMetaDataSnapshot>,
block_ids: &[String],
block_meta_data_vec: Vec<GridBlockMetaData>,
) -> FlowyResult<RepeatedGridBlock> {
let block_meta_snapshot_map: HashMap<&String, &Vec<Arc<RowMeta>>> = grid_block_meta_snapshots
let block_meta_data_map: HashMap<&String, &Vec<Arc<RowMeta>>> = block_meta_data_vec
.iter()
.map(|snapshot| (&snapshot.block_id, &snapshot.row_metas))
.map(|data| (&data.block_id, &data.row_metas))
.collect();
let mut grid_blocks = vec![];
for grid_block_meta in grid_block_metas {
match block_meta_snapshot_map.get(&grid_block_meta.block_id) {
for block_id in block_ids {
match block_meta_data_map.get(&block_id) {
None => {}
Some(row_metas) => {
let rows = make_rows_from_row_metas(&field_metas, row_metas);
grid_blocks.push(GridBlock::new(&grid_block_meta.block_id, rows));
let row_ids = make_row_ids_from_row_metas(row_metas);
grid_blocks.push(GridBlock::new(block_id, row_ids));
}
}
}

View File

@ -89,8 +89,8 @@ impl GridEditorTest {
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(None).await.unwrap();
let grid_blocks = editor.get_blocks().await.unwrap();
let row_metas = editor.get_grid_block_meta_snapshots(None).await.unwrap();
let grid_blocks = editor.get_block_metas().await.unwrap();
let row_metas = get_row_metas(&editor).await;
let grid_id = test.view.id;
Self {
@ -150,13 +150,13 @@ impl GridEditorTest {
}
EditorScript::CreateBlock { block } => {
self.editor.create_block(block).await.unwrap();
self.grid_blocks = self.editor.get_blocks().await.unwrap();
self.grid_blocks = self.editor.get_block_metas().await.unwrap();
}
EditorScript::UpdateBlock { changeset: change } => {
self.editor.update_block(change).await.unwrap();
}
EditorScript::AssertBlockCount(count) => {
assert_eq!(self.editor.get_blocks().await.unwrap().len(), count);
assert_eq!(self.editor.get_block_metas().await.unwrap().len(), count);
}
EditorScript::AssertBlock {
block_index,
@ -167,25 +167,25 @@ impl GridEditorTest {
assert_eq!(self.grid_blocks[block_index].start_row_index, start_row_index);
}
EditorScript::AssertBlockEqual { block_index, block } => {
let blocks = self.editor.get_blocks().await.unwrap();
let blocks = self.editor.get_block_metas().await.unwrap();
let compared_block = blocks[block_index].clone();
assert_eq!(compared_block, block);
}
EditorScript::CreateEmptyRow => {
self.editor.create_row(None).await.unwrap();
self.row_metas = self.editor.get_grid_block_meta_snapshots(None).await.unwrap();
self.grid_blocks = self.editor.get_blocks().await.unwrap();
self.row_metas = self.get_row_metas().await;
self.grid_blocks = self.editor.get_block_metas().await.unwrap();
}
EditorScript::CreateRow { context } => {
self.editor.insert_rows(vec![context]).await.unwrap();
self.row_metas = self.editor.get_grid_block_meta_snapshots(None).await.unwrap();
self.grid_blocks = self.editor.get_blocks().await.unwrap();
self.row_metas = self.get_row_metas().await;
self.grid_blocks = self.editor.get_block_metas().await.unwrap();
}
EditorScript::UpdateRow { changeset: change } => self.editor.update_row(change).await.unwrap(),
EditorScript::DeleteRow { row_ids } => {
self.editor.delete_rows(row_ids).await.unwrap();
self.row_metas = self.editor.get_grid_block_meta_snapshots(None).await.unwrap();
self.grid_blocks = self.editor.get_blocks().await.unwrap();
self.row_metas = self.get_row_metas().await;
self.grid_blocks = self.editor.get_block_metas().await.unwrap();
}
EditorScript::AssertRow { changeset } => {
let row = self.row_metas.iter().find(|row| row.id == changeset.row_id).unwrap();
@ -204,11 +204,11 @@ impl GridEditorTest {
assert!(result.is_err())
} else {
let _ = result.unwrap();
self.row_metas = self.editor.get_grid_block_meta_snapshots(None).await.unwrap();
self.row_metas = self.get_row_metas().await;
}
}
EditorScript::AssertRowCount(count) => {
assert_eq!(self.editor.get_grid_blocks(None).await.unwrap().len(), count);
assert_eq!(self.row_metas.len(), count);
}
EditorScript::AssertGridMetaPad => {
sleep(Duration::from_millis(2 * REVISION_WRITE_INTERVAL_IN_MILLIS)).await;
@ -218,6 +218,20 @@ impl GridEditorTest {
}
}
}
async fn get_row_metas(&self) -> Vec<Arc<RowMeta>> {
get_row_metas(&self.editor).await
}
}
async fn get_row_metas(editor: &Arc<ClientGridEditor>) -> Vec<Arc<RowMeta>> {
editor
.get_block_meta_data_vec(None)
.await
.unwrap()
.pop()
.unwrap()
.row_metas
}
pub fn create_text_field() -> FieldMeta {

1
shared-lib/Cargo.lock generated
View File

@ -485,6 +485,7 @@ version = "0.1.0"
dependencies = [
"bytes",
"flowy-derive",
"flowy-error-code",
"lib-infra",
"protobuf",
"serde",

View File

@ -1,7 +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::{GridBlockMetaData, RowMeta, RowMetaChangeset};
use flowy_grid_data_model::entities::{GridBlockMetaSerde, RowMeta, RowMetaChangeset};
use lib_infra::uuid;
use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder};
use serde::{Deserialize, Serialize};
@ -12,19 +12,22 @@ pub type GridBlockMetaDelta = PlainTextDelta;
pub type GridBlockMetaDeltaBuilder = PlainTextDeltaBuilder;
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct GridBlockMetaDataPad {
pub struct GridBlockMetaPad {
block_id: String,
rows: Vec<Arc<RowMeta>>,
row_metas: Vec<Arc<RowMeta>>,
#[serde(skip)]
pub(crate) delta: GridBlockMetaDelta,
}
impl GridBlockMetaDataPad {
impl GridBlockMetaPad {
pub fn from_delta(delta: GridBlockMetaDelta) -> CollaborateResult<Self> {
let s = delta.to_str()?;
let block_meta: GridBlockMetaData = serde_json::from_str(&s).map_err(|e| {
CollaborateError::internal().context(format!("Deserialize delta to block meta failed: {}", e))
tracing::info!("delta: {}", delta);
tracing::info!("{}", s);
let block_meta: GridBlockMetaSerde = serde_json::from_str(&s).map_err(|e| {
let msg = format!("Deserialize delta to block meta failed: {}", e);
CollaborateError::internal().context(msg)
})?;
let block_id = block_meta.block_id;
let rows = block_meta
@ -32,7 +35,11 @@ impl GridBlockMetaDataPad {
.into_iter()
.map(Arc::new)
.collect::<Vec<Arc<RowMeta>>>();
Ok(Self { block_id, rows, delta })
Ok(Self {
block_id,
row_metas: rows,
delta,
})
}
pub fn from_revisions(_grid_id: &str, revisions: Vec<Revision>) -> CollaborateResult<Self> {
@ -44,7 +51,7 @@ impl GridBlockMetaDataPad {
&mut self,
row: RowMeta,
start_row_id: Option<String>,
) -> CollaborateResult<Option<GridBlockMetaDataChange>> {
) -> CollaborateResult<Option<GridBlockMetaChange>> {
self.modify(|rows| {
if let Some(upper_row_id) = start_row_id {
if upper_row_id.is_empty() {
@ -63,7 +70,7 @@ impl GridBlockMetaDataPad {
})
}
pub fn delete_rows(&mut self, row_ids: &[String]) -> CollaborateResult<Option<GridBlockMetaDataChange>> {
pub fn delete_rows(&mut self, row_ids: &[String]) -> CollaborateResult<Option<GridBlockMetaChange>> {
self.modify(|rows| {
rows.retain(|row| !row_ids.contains(&row.id));
Ok(Some(()))
@ -72,10 +79,10 @@ impl GridBlockMetaDataPad {
pub fn get_rows(&self, row_ids: Option<Vec<String>>) -> CollaborateResult<Vec<Arc<RowMeta>>> {
match row_ids {
None => Ok(self.rows.to_vec()),
None => Ok(self.row_metas.to_vec()),
Some(row_ids) => {
let row_map = self
.rows
.row_metas
.iter()
.map(|row| (&row.id, row.clone()))
.collect::<HashMap<&String, Arc<RowMeta>>>();
@ -95,10 +102,10 @@ impl GridBlockMetaDataPad {
}
pub fn number_of_rows(&self) -> i32 {
self.rows.len() as i32
self.row_metas.len() as i32
}
pub fn update_row(&mut self, changeset: RowMetaChangeset) -> CollaborateResult<Option<GridBlockMetaDataChange>> {
pub fn update_row(&mut self, changeset: RowMetaChangeset) -> CollaborateResult<Option<GridBlockMetaChange>> {
let row_id = changeset.row_id.clone();
self.modify_row(&row_id, |row| {
let mut is_changed = None;
@ -123,12 +130,12 @@ impl GridBlockMetaDataPad {
})
}
pub fn modify<F>(&mut self, f: F) -> CollaborateResult<Option<GridBlockMetaDataChange>>
pub fn modify<F>(&mut self, f: F) -> CollaborateResult<Option<GridBlockMetaChange>>
where
F: for<'a> FnOnce(&'a mut Vec<Arc<RowMeta>>) -> CollaborateResult<Option<()>>,
{
let cloned_self = self.clone();
match f(&mut self.rows)? {
match f(&mut self.row_metas)? {
None => Ok(None),
Some(_) => {
let old = cloned_self.to_json()?;
@ -137,14 +144,14 @@ impl GridBlockMetaDataPad {
None => Ok(None),
Some(delta) => {
self.delta = self.delta.compose(&delta)?;
Ok(Some(GridBlockMetaDataChange { delta, md5: self.md5() }))
Ok(Some(GridBlockMetaChange { delta, md5: self.md5() }))
}
}
}
}
}
fn modify_row<F>(&mut self, row_id: &str, f: F) -> CollaborateResult<Option<GridBlockMetaDataChange>>
fn modify_row<F>(&mut self, row_id: &str, f: F) -> CollaborateResult<Option<GridBlockMetaChange>>
where
F: FnOnce(&mut RowMeta) -> CollaborateResult<Option<()>>,
{
@ -172,35 +179,35 @@ impl GridBlockMetaDataPad {
}
}
pub struct GridBlockMetaDataChange {
pub struct GridBlockMetaChange {
pub delta: GridBlockMetaDelta,
/// md5: the md5 of the grid after applying the change.
pub md5: String,
}
pub fn make_block_meta_delta(grid_block_meta_data: &GridBlockMetaData) -> GridBlockMetaDelta {
pub fn make_block_meta_delta(grid_block_meta_data: &GridBlockMetaSerde) -> GridBlockMetaDelta {
let json = serde_json::to_string(&grid_block_meta_data).unwrap();
PlainTextDeltaBuilder::new().insert(&json).build()
}
pub fn make_block_meta_revisions(user_id: &str, grid_block_meta_data: &GridBlockMetaData) -> RepeatedRevision {
pub fn make_block_meta_revisions(user_id: &str, grid_block_meta_data: &GridBlockMetaSerde) -> RepeatedRevision {
let delta = make_block_meta_delta(grid_block_meta_data);
let bytes = delta.to_delta_bytes();
let revision = Revision::initial_revision(user_id, &grid_block_meta_data.block_id, bytes);
revision.into()
}
impl std::default::Default for GridBlockMetaDataPad {
impl std::default::Default for GridBlockMetaPad {
fn default() -> Self {
let block_meta_data = GridBlockMetaData {
let block_meta_data = GridBlockMetaSerde {
block_id: uuid(),
row_metas: vec![],
};
let delta = make_block_meta_delta(&block_meta_data);
GridBlockMetaDataPad {
GridBlockMetaPad {
block_id: block_meta_data.block_id,
rows: block_meta_data.row_metas.into_iter().map(Arc::new).collect::<Vec<_>>(),
row_metas: block_meta_data.row_metas.into_iter().map(Arc::new).collect::<Vec<_>>(),
delta,
}
}
@ -208,7 +215,7 @@ impl std::default::Default for GridBlockMetaDataPad {
#[cfg(test)]
mod tests {
use crate::client_grid::{GridBlockMetaDataPad, GridBlockMetaDelta};
use crate::client_grid::{GridBlockMetaDelta, GridBlockMetaPad};
use flowy_grid_data_model::entities::{RowMeta, RowMetaChangeset};
#[test]
@ -225,7 +232,7 @@ mod tests {
let change = pad.add_row(row, None).unwrap().unwrap();
assert_eq!(
change.delta.to_delta_str(),
r#"[{"retain":24},{"insert":"{\"id\":\"1\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"#
r#"[{"retain":29},{"insert":"{\"id\":\"1\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"#
);
}
@ -239,27 +246,27 @@ mod tests {
let change = pad.add_row(row_1.clone(), None).unwrap().unwrap();
assert_eq!(
change.delta.to_delta_str(),
r#"[{"retain":24},{"insert":"{\"id\":\"1\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"#
r#"[{"retain":29},{"insert":"{\"id\":\"1\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"#
);
let change = pad.add_row(row_2.clone(), None).unwrap().unwrap();
assert_eq!(
change.delta.to_delta_str(),
r#"[{"retain":101},{"insert":",{\"id\":\"2\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"#
r#"[{"retain":106},{"insert":",{\"id\":\"2\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false}"},{"retain":2}]"#
);
let change = pad.add_row(row_3.clone(), Some("2".to_string())).unwrap().unwrap();
assert_eq!(
change.delta.to_delta_str(),
r#"[{"retain":109},{"insert":"3\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false},{\"id\":\""},{"retain":72}]"#
r#"[{"retain":114},{"insert":"3\",\"block_id\":\"1\",\"cell_by_field_id\":{},\"height\":0,\"visibility\":false},{\"id\":\""},{"retain":72}]"#
);
assert_eq!(*pad.rows[0], row_1);
assert_eq!(*pad.rows[1], row_3);
assert_eq!(*pad.rows[2], row_2);
assert_eq!(*pad.row_metas[0], row_1);
assert_eq!(*pad.row_metas[1], row_3);
assert_eq!(*pad.row_metas[2], row_2);
}
fn test_row_meta(id: &str, pad: &GridBlockMetaDataPad) -> RowMeta {
fn test_row_meta(id: &str, pad: &GridBlockMetaPad) -> RowMeta {
RowMeta {
id: id.to_string(),
block_id: pad.block_id.clone(),
@ -280,9 +287,9 @@ mod tests {
let _ = pad.add_row(row_2.clone(), None).unwrap().unwrap();
let _ = pad.add_row(row_3.clone(), Some("1".to_string())).unwrap().unwrap();
assert_eq!(*pad.rows[0], row_3);
assert_eq!(*pad.rows[1], row_1);
assert_eq!(*pad.rows[2], row_2);
assert_eq!(*pad.row_metas[0], row_3);
assert_eq!(*pad.row_metas[1], row_1);
assert_eq!(*pad.row_metas[2], row_2);
}
#[test]
@ -296,9 +303,9 @@ mod tests {
let _ = pad.add_row(row_2.clone(), None).unwrap().unwrap();
let _ = pad.add_row(row_3.clone(), Some("".to_string())).unwrap().unwrap();
assert_eq!(*pad.rows[0], row_3);
assert_eq!(*pad.rows[1], row_1);
assert_eq!(*pad.rows[2], row_2);
assert_eq!(*pad.row_metas[0], row_3);
assert_eq!(*pad.row_metas[1], row_1);
assert_eq!(*pad.row_metas[2], row_2);
}
#[test]
@ -317,7 +324,7 @@ mod tests {
let change = pad.delete_rows(&[row.id]).unwrap().unwrap();
assert_eq!(
change.delta.to_delta_str(),
r#"[{"retain":24},{"delete":77},{"retain":2}]"#
r#"[{"retain":29},{"delete":77},{"retain":2}]"#
);
assert_eq!(pad.delta_str(), pre_delta_str);
@ -346,17 +353,18 @@ mod tests {
assert_eq!(
change.delta.to_delta_str(),
r#"[{"retain":80},{"insert":"10"},{"retain":15},{"insert":"tru"},{"delete":4},{"retain":4}]"#
r#"[{"retain":85},{"insert":"10"},{"retain":15},{"insert":"tru"},{"delete":4},{"retain":4}]"#
);
assert_eq!(
pad.to_json().unwrap(),
r#"{"block_id":"1","rows":[{"id":"1","block_id":"1","cell_by_field_id":{},"height":100,"visibility":true}]}"#
r#"{"block_id":"1","row_metas":[{"id":"1","block_id":"1","cell_by_field_id":{},"height":100,"visibility":true}]}"#
);
}
fn test_pad() -> GridBlockMetaDataPad {
let delta = GridBlockMetaDelta::from_delta_str(r#"[{"insert":"{\"block_id\":\"1\",\"rows\":[]}"}]"#).unwrap();
GridBlockMetaDataPad::from_delta(delta).unwrap()
fn test_pad() -> GridBlockMetaPad {
let delta =
GridBlockMetaDelta::from_delta_str(r#"[{"insert":"{\"block_id\":\"1\",\"row_metas\":[]}"}]"#).unwrap();
GridBlockMetaPad::from_delta(delta).unwrap()
}
}

View File

@ -13,9 +13,9 @@ impl GridBuilder {
}
pub fn add_empty_row(mut self) -> Self {
let row = RowMeta::new(&self.build_context.grid_block.block_id);
self.build_context.grid_block_meta_data.row_metas.push(row);
self.build_context.grid_block.row_count += 1;
let row = RowMeta::new(&self.build_context.block_metas.block_id);
self.build_context.block_meta_data.row_metas.push(row);
self.build_context.block_metas.row_count += 1;
self
}
@ -41,7 +41,7 @@ fn check_rows(fields: &[FieldMeta], rows: &[RowMeta]) -> CollaborateResult<()> {
mod tests {
use crate::client_grid::{make_block_meta_delta, make_grid_delta, GridBuilder};
use flowy_grid_data_model::entities::{FieldMeta, FieldType, GridBlockMetaData, GridMeta};
use flowy_grid_data_model::entities::{FieldMeta, FieldType, GridBlockMetaSerde, GridMeta};
#[test]
fn create_default_grid_test() {
@ -57,13 +57,13 @@ mod tests {
let grid_meta = GridMeta {
grid_id,
fields: build_context.field_metas,
blocks: vec![build_context.grid_block],
block_metas: vec![build_context.block_metas],
};
let grid_meta_delta = make_grid_delta(&grid_meta);
let _: GridMeta = serde_json::from_str(&grid_meta_delta.to_str().unwrap()).unwrap();
let grid_block_meta_delta = make_block_meta_delta(&build_context.grid_block_meta_data);
let _: GridBlockMetaData = serde_json::from_str(&grid_block_meta_delta.to_str().unwrap()).unwrap();
let grid_block_meta_delta = make_block_meta_delta(&build_context.block_meta_data);
let _: GridBlockMetaSerde = serde_json::from_str(&grid_block_meta_delta.to_str().unwrap()).unwrap();
}
}

View File

@ -140,12 +140,12 @@ impl GridMetaPad {
pub fn create_block(&mut self, block: GridBlockMeta) -> CollaborateResult<Option<GridChangeset>> {
self.modify_grid(|grid| {
if grid.blocks.iter().any(|b| b.block_id == block.block_id) {
if grid.block_metas.iter().any(|b| b.block_id == block.block_id) {
tracing::warn!("Duplicate grid block");
Ok(None)
} else {
match grid.blocks.last() {
None => grid.blocks.push(block),
match grid.block_metas.last() {
None => grid.block_metas.push(block),
Some(last_block) => {
if last_block.start_row_index > block.start_row_index
&& last_block.len() > block.start_row_index
@ -153,7 +153,7 @@ impl GridMetaPad {
let msg = "GridBlock's start_row_index should be greater than the last_block's start_row_index and its len".to_string();
return Err(CollaborateError::internal().context(msg))
}
grid.blocks.push(block);
grid.block_metas.push(block);
}
}
Ok(Some(()))
@ -162,7 +162,7 @@ impl GridMetaPad {
}
pub fn get_blocks(&self) -> Vec<GridBlockMeta> {
self.grid_meta.blocks.clone()
self.grid_meta.block_metas.clone()
}
pub fn update_block(&mut self, changeset: GridBlockMetaChangeset) -> CollaborateResult<Option<GridChangeset>> {
@ -226,12 +226,12 @@ impl GridMetaPad {
F: FnOnce(&mut GridBlockMeta) -> CollaborateResult<Option<()>>,
{
self.modify_grid(
|grid| match grid.blocks.iter().position(|block| block.block_id == block_id) {
|grid| match grid.block_metas.iter().position(|block| block.block_id == block_id) {
None => {
tracing::warn!("[GridMetaPad]: Can't find any block with id: {}", block_id);
Ok(None)
}
Some(index) => f(&mut grid.blocks[index]),
Some(index) => f(&mut grid.block_metas[index]),
},
)
}
@ -279,7 +279,7 @@ impl std::default::Default for GridMetaPad {
let grid = GridMeta {
grid_id: uuid(),
fields: vec![],
blocks: vec![],
block_metas: vec![],
};
let delta = make_grid_delta(&grid);
GridMetaPad {

View File

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

View File

@ -85,8 +85,14 @@ pub enum ErrorCode {
UserNotExist = 312,
#[display(fmt = "Text is too long")]
TextTooLong = 400,
#[display(fmt = "Grid block id is empty")]
BlockIdIsEmpty = 401,
#[display(fmt = "Row id is empty")]
RowIdIsEmpty = 402,
#[display(fmt = "Grid id is empty")]
GridIdIsEmpty = 403,
#[display(fmt = "Invalid data")]
InvalidData = 401,
InvalidData = 404,
}
impl ErrorCode {

View File

@ -56,7 +56,10 @@ pub enum ErrorCode {
UserIdInvalid = 311,
UserNotExist = 312,
TextTooLong = 400,
InvalidData = 401,
BlockIdIsEmpty = 401,
RowIdIsEmpty = 402,
GridIdIsEmpty = 403,
InvalidData = 404,
}
impl ::protobuf::ProtobufEnum for ErrorCode {
@ -97,7 +100,10 @@ impl ::protobuf::ProtobufEnum for ErrorCode {
311 => ::std::option::Option::Some(ErrorCode::UserIdInvalid),
312 => ::std::option::Option::Some(ErrorCode::UserNotExist),
400 => ::std::option::Option::Some(ErrorCode::TextTooLong),
401 => ::std::option::Option::Some(ErrorCode::InvalidData),
401 => ::std::option::Option::Some(ErrorCode::BlockIdIsEmpty),
402 => ::std::option::Option::Some(ErrorCode::RowIdIsEmpty),
403 => ::std::option::Option::Some(ErrorCode::GridIdIsEmpty),
404 => ::std::option::Option::Some(ErrorCode::InvalidData),
_ => ::std::option::Option::None
}
}
@ -135,6 +141,9 @@ impl ::protobuf::ProtobufEnum for ErrorCode {
ErrorCode::UserIdInvalid,
ErrorCode::UserNotExist,
ErrorCode::TextTooLong,
ErrorCode::BlockIdIsEmpty,
ErrorCode::RowIdIsEmpty,
ErrorCode::GridIdIsEmpty,
ErrorCode::InvalidData,
];
values
@ -164,7 +173,7 @@ impl ::protobuf::reflect::ProtobufValue for ErrorCode {
}
static file_descriptor_proto_data: &'static [u8] = b"\
\n\ncode.proto*\xe8\x05\n\tErrorCode\x12\x0c\n\x08Internal\x10\0\x12\x14\
\n\ncode.proto*\xa4\x06\n\tErrorCode\x12\x0c\n\x08Internal\x10\0\x12\x14\
\n\x10UserUnauthorized\x10\x02\x12\x12\n\x0eRecordNotFound\x10\x03\x12\
\x18\n\x14WorkspaceNameInvalid\x10d\x12\x16\n\x12WorkspaceIdInvalid\x10e\
\x12\x18\n\x14AppColorStyleInvalid\x10f\x12\x18\n\x14WorkspaceDescTooLon\
@ -181,8 +190,9 @@ static file_descriptor_proto_data: &'static [u8] = b"\
\x14\n\x0fUserNameTooLong\x10\xb4\x02\x12'\n\"UserNameContainForbiddenCh\
aracters\x10\xb5\x02\x12\x14\n\x0fUserNameIsEmpty\x10\xb6\x02\x12\x12\n\
\rUserIdInvalid\x10\xb7\x02\x12\x11\n\x0cUserNotExist\x10\xb8\x02\x12\
\x10\n\x0bTextTooLong\x10\x90\x03\x12\x10\n\x0bInvalidData\x10\x91\x03b\
\x06proto3\
\x10\n\x0bTextTooLong\x10\x90\x03\x12\x13\n\x0eBlockIdIsEmpty\x10\x91\
\x03\x12\x11\n\x0cRowIdIsEmpty\x10\x92\x03\x12\x12\n\rGridIdIsEmpty\x10\
\x93\x03\x12\x10\n\x0bInvalidData\x10\x94\x03b\x06proto3\
";
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

View File

@ -32,5 +32,8 @@ enum ErrorCode {
UserIdInvalid = 311;
UserNotExist = 312;
TextTooLong = 400;
InvalidData = 401;
BlockIdIsEmpty = 401;
RowIdIsEmpty = 402;
GridIdIsEmpty = 403;
InvalidData = 404;
}

View File

@ -14,6 +14,7 @@ strum_macros = "0.21"
serde = { version = "1.0", features = ["derive"] }
serde_json = {version = "1.0"}
uuid = { version = "0.8", features = ["serde", "v4"] }
flowy-error-code = { path = "../flowy-error-code"}
[build-dependencies]
lib-infra = { path = "../lib-infra", features = ["protobuf_file_gen"] }

View File

@ -1,7 +1,9 @@
use crate::entities::{FieldMeta, FieldType, GridBlockMeta, RowMeta};
use crate::entities::{FieldMeta, FieldType, RowMeta};
use flowy_derive::ProtoBuf;
use std::collections::HashMap;
use std::hash::Hash;
use crate::parser::NonEmptyId;
use flowy_error_code::ErrorCode;
use std::sync::Arc;
#[derive(Debug, Clone, Default, ProtoBuf)]
@ -13,7 +15,7 @@ pub struct Grid {
pub field_orders: Vec<FieldOrder>,
#[pb(index = 3)]
pub blocks: Vec<GridBlockMeta>,
pub block_orders: Vec<GridBlockOrder>,
}
#[derive(Debug, Clone, Default, ProtoBuf)]
@ -169,6 +171,18 @@ pub struct Row {
pub height: i32,
}
#[derive(Debug, Default, ProtoBuf)]
pub struct RepeatedRow {
#[pb(index = 1)]
pub items: Vec<Row>,
}
impl std::convert::From<Vec<Row>> for RepeatedRow {
fn from(items: Vec<Row>) -> Self {
Self { items }
}
}
#[derive(Debug, Default, ProtoBuf)]
pub struct RepeatedGridBlock {
#[pb(index = 1)]
@ -181,20 +195,26 @@ impl std::convert::From<Vec<GridBlock>> for RepeatedGridBlock {
}
}
#[derive(Debug, Clone, Default, ProtoBuf)]
pub struct GridBlockOrder {
#[pb(index = 1)]
pub block_id: String,
}
#[derive(Debug, Default, ProtoBuf)]
pub struct GridBlock {
#[pb(index = 1)]
pub block_id: String,
#[pb(index = 2)]
pub rows: Vec<String>,
pub row_ids: Vec<String>,
}
impl GridBlock {
pub fn new(block_id: &str, rows: Vec<Row>) -> Self {
pub fn new(block_id: &str, row_ids: Vec<String>) -> Self {
Self {
block_id: block_id.to_owned(),
rows,
row_ids,
}
}
}
@ -278,7 +298,7 @@ pub struct CreateRowPayload {
pub grid_id: String,
#[pb(index = 2, one_of)]
pub upper_row_id: Option<String>,
pub start_row_id: Option<String>,
}
#[derive(ProtoBuf, Default)]
@ -296,5 +316,17 @@ pub struct QueryGridBlocksPayload {
pub grid_id: String,
#[pb(index = 2)]
pub blocks: Vec<GridBlockMeta>,
pub block_orders: Vec<GridBlockOrder>,
}
#[derive(ProtoBuf, Default)]
pub struct QueryRowPayload {
#[pb(index = 1)]
pub grid_id: String,
#[pb(index = 2)]
pub block_id: String,
#[pb(index = 3)]
pub row_id: String,
}

View File

@ -2,6 +2,7 @@ use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use crate::entities::GridBlockOrder;
use strum_macros::{Display, EnumCount as EnumCountMacro, EnumIter, EnumString};
pub const DEFAULT_ROW_HEIGHT: i32 = 36;
@ -16,7 +17,7 @@ pub struct GridMeta {
pub fields: Vec<FieldMeta>,
#[pb(index = 3)]
pub blocks: Vec<GridBlockMeta>,
pub block_metas: Vec<GridBlockMeta>,
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, ProtoBuf)]
@ -33,7 +34,7 @@ pub struct GridBlockMeta {
impl GridBlockMeta {
pub fn len(&self) -> i32 {
self.start_row_index + self.row_count
self.row_count
}
pub fn is_empty(&self) -> bool {
@ -67,7 +68,7 @@ impl GridBlockMetaChangeset {
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)]
pub struct GridBlockMetaData {
pub struct GridBlockMetaSerde {
#[pb(index = 1)]
pub block_id: String,
@ -329,24 +330,24 @@ pub struct BuildGridContext {
pub field_metas: Vec<FieldMeta>,
#[pb(index = 2)]
pub grid_block: GridBlockMeta,
pub block_metas: GridBlockMeta,
#[pb(index = 3)]
pub grid_block_meta_data: GridBlockMetaData,
pub block_meta_data: GridBlockMetaSerde,
}
impl std::default::Default for BuildGridContext {
fn default() -> Self {
let grid_block = GridBlockMeta::new();
let grid_block_meta_data = GridBlockMetaData {
let grid_block_meta_data = GridBlockMetaSerde {
block_id: grid_block.block_id.clone(),
row_metas: vec![],
};
Self {
field_metas: vec![],
grid_block,
grid_block_meta_data,
block_metas: grid_block,
block_meta_data: grid_block_meta_data,
}
}
}

View File

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

View File

@ -0,0 +1,82 @@
use crate::entities::{
CreateRowPayload, GridBlockOrder, QueryFieldPayload, QueryGridBlocksPayload, QueryRowPayload, RepeatedFieldOrder,
};
use crate::parser::NonEmptyId;
use flowy_error_code::ErrorCode;
#[derive(Default)]
pub struct CreateRowParams {
pub grid_id: String,
pub start_row_id: Option<String>,
}
impl TryInto<CreateRowParams> for CreateRowPayload {
type Error = ErrorCode;
fn try_into(self) -> Result<CreateRowParams, Self::Error> {
let grid_id = NonEmptyId::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
Ok(CreateRowParams {
grid_id: grid_id.0,
start_row_id: self.start_row_id,
})
}
}
#[derive(Default)]
pub struct QueryFieldParams {
pub grid_id: String,
pub field_orders: RepeatedFieldOrder,
}
impl TryInto<QueryFieldParams> for QueryFieldPayload {
type Error = ErrorCode;
fn try_into(self) -> Result<QueryFieldParams, Self::Error> {
let grid_id = NonEmptyId::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
Ok(QueryFieldParams {
grid_id: grid_id.0,
field_orders: self.field_orders,
})
}
}
#[derive(Default)]
pub struct QueryGridBlocksParams {
pub grid_id: String,
pub block_orders: Vec<GridBlockOrder>,
}
impl TryInto<QueryGridBlocksParams> for QueryGridBlocksPayload {
type Error = ErrorCode;
fn try_into(self) -> Result<QueryGridBlocksParams, Self::Error> {
let grid_id = NonEmptyId::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
Ok(QueryGridBlocksParams {
grid_id: grid_id.0,
block_orders: self.block_orders,
})
}
}
#[derive(Default)]
pub struct QueryRowParams {
pub grid_id: String,
pub block_id: String,
pub row_id: String,
}
impl TryInto<QueryRowParams> for QueryRowPayload {
type Error = ErrorCode;
fn try_into(self) -> Result<QueryRowParams, Self::Error> {
let grid_id = NonEmptyId::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
let block_id = NonEmptyId::parse(self.block_id).map_err(|_| ErrorCode::BlockIdIsEmpty)?;
let row_id = NonEmptyId::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?;
Ok(QueryRowParams {
grid_id: grid_id.0,
block_id: block_id.0,
row_id: row_id.0,
})
}
}

View File

@ -0,0 +1,20 @@
use flowy_error_code::ErrorCode;
#[derive(Debug)]
pub struct NonEmptyId(pub String);
impl NonEmptyId {
pub fn parse(s: String) -> Result<NonEmptyId, ()> {
if s.trim().is_empty() {
return Err(());
}
Ok(Self(s))
}
}
impl AsRef<str> for NonEmptyId {
fn as_ref(&self) -> &str {
&self.0
}
}

View File

@ -0,0 +1,5 @@
mod grid;
mod id;
pub use grid::*;
pub use id::*;

File diff suppressed because it is too large Load Diff

View File

@ -28,7 +28,7 @@ pub struct GridMeta {
// message fields
pub grid_id: ::std::string::String,
pub fields: ::protobuf::RepeatedField<FieldMeta>,
pub blocks: ::protobuf::RepeatedField<GridBlockMeta>,
pub block_metas: ::protobuf::RepeatedField<GridBlockMeta>,
// special fields
pub unknown_fields: ::protobuf::UnknownFields,
pub cached_size: ::protobuf::CachedSize,
@ -96,29 +96,29 @@ impl GridMeta {
::std::mem::replace(&mut self.fields, ::protobuf::RepeatedField::new())
}
// repeated .GridBlockMeta blocks = 3;
// repeated .GridBlockMeta block_metas = 3;
pub fn get_blocks(&self) -> &[GridBlockMeta] {
&self.blocks
pub fn get_block_metas(&self) -> &[GridBlockMeta] {
&self.block_metas
}
pub fn clear_blocks(&mut self) {
self.blocks.clear();
pub fn clear_block_metas(&mut self) {
self.block_metas.clear();
}
// Param is passed by value, moved
pub fn set_blocks(&mut self, v: ::protobuf::RepeatedField<GridBlockMeta>) {
self.blocks = v;
pub fn set_block_metas(&mut self, v: ::protobuf::RepeatedField<GridBlockMeta>) {
self.block_metas = v;
}
// Mutable pointer to the field.
pub fn mut_blocks(&mut self) -> &mut ::protobuf::RepeatedField<GridBlockMeta> {
&mut self.blocks
pub fn mut_block_metas(&mut self) -> &mut ::protobuf::RepeatedField<GridBlockMeta> {
&mut self.block_metas
}
// Take field
pub fn take_blocks(&mut self) -> ::protobuf::RepeatedField<GridBlockMeta> {
::std::mem::replace(&mut self.blocks, ::protobuf::RepeatedField::new())
pub fn take_block_metas(&mut self) -> ::protobuf::RepeatedField<GridBlockMeta> {
::std::mem::replace(&mut self.block_metas, ::protobuf::RepeatedField::new())
}
}
@ -129,7 +129,7 @@ impl ::protobuf::Message for GridMeta {
return false;
}
};
for v in &self.blocks {
for v in &self.block_metas {
if !v.is_initialized() {
return false;
}
@ -148,7 +148,7 @@ impl ::protobuf::Message for GridMeta {
::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.fields)?;
},
3 => {
::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.blocks)?;
::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.block_metas)?;
},
_ => {
::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
@ -169,7 +169,7 @@ impl ::protobuf::Message for GridMeta {
let len = value.compute_size();
my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
};
for value in &self.blocks {
for value in &self.block_metas {
let len = value.compute_size();
my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
};
@ -187,7 +187,7 @@ impl ::protobuf::Message for GridMeta {
os.write_raw_varint32(v.get_cached_size())?;
v.write_to_with_cached_sizes(os)?;
};
for v in &self.blocks {
for v in &self.block_metas {
os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?;
os.write_raw_varint32(v.get_cached_size())?;
v.write_to_with_cached_sizes(os)?;
@ -241,9 +241,9 @@ impl ::protobuf::Message for GridMeta {
|m: &mut GridMeta| { &mut m.fields },
));
fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<GridBlockMeta>>(
"blocks",
|m: &GridMeta| { &m.blocks },
|m: &mut GridMeta| { &mut m.blocks },
"block_metas",
|m: &GridMeta| { &m.block_metas },
|m: &mut GridMeta| { &mut m.block_metas },
));
::protobuf::reflect::MessageDescriptor::new_pb_name::<GridMeta>(
"GridMeta",
@ -263,7 +263,7 @@ impl ::protobuf::Clear for GridMeta {
fn clear(&mut self) {
self.grid_id.clear();
self.fields.clear();
self.blocks.clear();
self.block_metas.clear();
self.unknown_fields.clear();
}
}
@ -510,7 +510,7 @@ impl ::protobuf::reflect::ProtobufValue for GridBlockMeta {
}
#[derive(PartialEq,Clone,Default)]
pub struct GridBlockMetaData {
pub struct GridBlockMetaSerde {
// message fields
pub block_id: ::std::string::String,
pub row_metas: ::protobuf::RepeatedField<RowMeta>,
@ -519,14 +519,14 @@ pub struct GridBlockMetaData {
pub cached_size: ::protobuf::CachedSize,
}
impl<'a> ::std::default::Default for &'a GridBlockMetaData {
fn default() -> &'a GridBlockMetaData {
<GridBlockMetaData as ::protobuf::Message>::default_instance()
impl<'a> ::std::default::Default for &'a GridBlockMetaSerde {
fn default() -> &'a GridBlockMetaSerde {
<GridBlockMetaSerde as ::protobuf::Message>::default_instance()
}
}
impl GridBlockMetaData {
pub fn new() -> GridBlockMetaData {
impl GridBlockMetaSerde {
pub fn new() -> GridBlockMetaSerde {
::std::default::Default::default()
}
@ -582,7 +582,7 @@ impl GridBlockMetaData {
}
}
impl ::protobuf::Message for GridBlockMetaData {
impl ::protobuf::Message for GridBlockMetaSerde {
fn is_initialized(&self) -> bool {
for v in &self.row_metas {
if !v.is_initialized() {
@ -665,8 +665,8 @@ impl ::protobuf::Message for GridBlockMetaData {
Self::descriptor_static()
}
fn new() -> GridBlockMetaData {
GridBlockMetaData::new()
fn new() -> GridBlockMetaSerde {
GridBlockMetaSerde::new()
}
fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
@ -675,29 +675,29 @@ impl ::protobuf::Message for GridBlockMetaData {
let mut fields = ::std::vec::Vec::new();
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
"block_id",
|m: &GridBlockMetaData| { &m.block_id },
|m: &mut GridBlockMetaData| { &mut m.block_id },
|m: &GridBlockMetaSerde| { &m.block_id },
|m: &mut GridBlockMetaSerde| { &mut m.block_id },
));
fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<RowMeta>>(
"row_metas",
|m: &GridBlockMetaData| { &m.row_metas },
|m: &mut GridBlockMetaData| { &mut m.row_metas },
|m: &GridBlockMetaSerde| { &m.row_metas },
|m: &mut GridBlockMetaSerde| { &mut m.row_metas },
));
::protobuf::reflect::MessageDescriptor::new_pb_name::<GridBlockMetaData>(
"GridBlockMetaData",
::protobuf::reflect::MessageDescriptor::new_pb_name::<GridBlockMetaSerde>(
"GridBlockMetaSerde",
fields,
file_descriptor_proto()
)
})
}
fn default_instance() -> &'static GridBlockMetaData {
static instance: ::protobuf::rt::LazyV2<GridBlockMetaData> = ::protobuf::rt::LazyV2::INIT;
instance.get(GridBlockMetaData::new)
fn default_instance() -> &'static GridBlockMetaSerde {
static instance: ::protobuf::rt::LazyV2<GridBlockMetaSerde> = ::protobuf::rt::LazyV2::INIT;
instance.get(GridBlockMetaSerde::new)
}
}
impl ::protobuf::Clear for GridBlockMetaData {
impl ::protobuf::Clear for GridBlockMetaSerde {
fn clear(&mut self) {
self.block_id.clear();
self.row_metas.clear();
@ -705,13 +705,13 @@ impl ::protobuf::Clear for GridBlockMetaData {
}
}
impl ::std::fmt::Debug for GridBlockMetaData {
impl ::std::fmt::Debug for GridBlockMetaSerde {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
::protobuf::text_format::fmt(self, f)
}
}
impl ::protobuf::reflect::ProtobufValue for GridBlockMetaData {
impl ::protobuf::reflect::ProtobufValue for GridBlockMetaSerde {
fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
::protobuf::reflect::ReflectValueRef::Message(self)
}
@ -3119,8 +3119,8 @@ impl ::protobuf::reflect::ProtobufValue for CellMetaChangeset {
pub struct BuildGridContext {
// message fields
pub field_metas: ::protobuf::RepeatedField<FieldMeta>,
pub grid_block: ::protobuf::SingularPtrField<GridBlockMeta>,
pub grid_block_meta_data: ::protobuf::SingularPtrField<GridBlockMetaData>,
pub block_metas: ::protobuf::SingularPtrField<GridBlockMeta>,
pub block_meta_data: ::protobuf::SingularPtrField<GridBlockMetaSerde>,
// special fields
pub unknown_fields: ::protobuf::UnknownFields,
pub cached_size: ::protobuf::CachedSize,
@ -3162,70 +3162,70 @@ impl BuildGridContext {
::std::mem::replace(&mut self.field_metas, ::protobuf::RepeatedField::new())
}
// .GridBlockMeta grid_block = 2;
// .GridBlockMeta block_metas = 2;
pub fn get_grid_block(&self) -> &GridBlockMeta {
self.grid_block.as_ref().unwrap_or_else(|| <GridBlockMeta as ::protobuf::Message>::default_instance())
pub fn get_block_metas(&self) -> &GridBlockMeta {
self.block_metas.as_ref().unwrap_or_else(|| <GridBlockMeta as ::protobuf::Message>::default_instance())
}
pub fn clear_grid_block(&mut self) {
self.grid_block.clear();
pub fn clear_block_metas(&mut self) {
self.block_metas.clear();
}
pub fn has_grid_block(&self) -> bool {
self.grid_block.is_some()
pub fn has_block_metas(&self) -> bool {
self.block_metas.is_some()
}
// Param is passed by value, moved
pub fn set_grid_block(&mut self, v: GridBlockMeta) {
self.grid_block = ::protobuf::SingularPtrField::some(v);
pub fn set_block_metas(&mut self, v: GridBlockMeta) {
self.block_metas = ::protobuf::SingularPtrField::some(v);
}
// Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first.
pub fn mut_grid_block(&mut self) -> &mut GridBlockMeta {
if self.grid_block.is_none() {
self.grid_block.set_default();
pub fn mut_block_metas(&mut self) -> &mut GridBlockMeta {
if self.block_metas.is_none() {
self.block_metas.set_default();
}
self.grid_block.as_mut().unwrap()
self.block_metas.as_mut().unwrap()
}
// Take field
pub fn take_grid_block(&mut self) -> GridBlockMeta {
self.grid_block.take().unwrap_or_else(|| GridBlockMeta::new())
pub fn take_block_metas(&mut self) -> GridBlockMeta {
self.block_metas.take().unwrap_or_else(|| GridBlockMeta::new())
}
// .GridBlockMetaData grid_block_meta_data = 3;
// .GridBlockMetaSerde block_meta_data = 3;
pub fn get_grid_block_meta_data(&self) -> &GridBlockMetaData {
self.grid_block_meta_data.as_ref().unwrap_or_else(|| <GridBlockMetaData as ::protobuf::Message>::default_instance())
pub fn get_block_meta_data(&self) -> &GridBlockMetaSerde {
self.block_meta_data.as_ref().unwrap_or_else(|| <GridBlockMetaSerde as ::protobuf::Message>::default_instance())
}
pub fn clear_grid_block_meta_data(&mut self) {
self.grid_block_meta_data.clear();
pub fn clear_block_meta_data(&mut self) {
self.block_meta_data.clear();
}
pub fn has_grid_block_meta_data(&self) -> bool {
self.grid_block_meta_data.is_some()
pub fn has_block_meta_data(&self) -> bool {
self.block_meta_data.is_some()
}
// Param is passed by value, moved
pub fn set_grid_block_meta_data(&mut self, v: GridBlockMetaData) {
self.grid_block_meta_data = ::protobuf::SingularPtrField::some(v);
pub fn set_block_meta_data(&mut self, v: GridBlockMetaSerde) {
self.block_meta_data = ::protobuf::SingularPtrField::some(v);
}
// Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first.
pub fn mut_grid_block_meta_data(&mut self) -> &mut GridBlockMetaData {
if self.grid_block_meta_data.is_none() {
self.grid_block_meta_data.set_default();
pub fn mut_block_meta_data(&mut self) -> &mut GridBlockMetaSerde {
if self.block_meta_data.is_none() {
self.block_meta_data.set_default();
}
self.grid_block_meta_data.as_mut().unwrap()
self.block_meta_data.as_mut().unwrap()
}
// Take field
pub fn take_grid_block_meta_data(&mut self) -> GridBlockMetaData {
self.grid_block_meta_data.take().unwrap_or_else(|| GridBlockMetaData::new())
pub fn take_block_meta_data(&mut self) -> GridBlockMetaSerde {
self.block_meta_data.take().unwrap_or_else(|| GridBlockMetaSerde::new())
}
}
@ -3236,12 +3236,12 @@ impl ::protobuf::Message for BuildGridContext {
return false;
}
};
for v in &self.grid_block {
for v in &self.block_metas {
if !v.is_initialized() {
return false;
}
};
for v in &self.grid_block_meta_data {
for v in &self.block_meta_data {
if !v.is_initialized() {
return false;
}
@ -3257,10 +3257,10 @@ impl ::protobuf::Message for BuildGridContext {
::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.field_metas)?;
},
2 => {
::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.grid_block)?;
::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.block_metas)?;
},
3 => {
::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.grid_block_meta_data)?;
::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.block_meta_data)?;
},
_ => {
::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
@ -3278,11 +3278,11 @@ impl ::protobuf::Message for BuildGridContext {
let len = value.compute_size();
my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
};
if let Some(ref v) = self.grid_block.as_ref() {
if let Some(ref v) = self.block_metas.as_ref() {
let len = v.compute_size();
my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
}
if let Some(ref v) = self.grid_block_meta_data.as_ref() {
if let Some(ref v) = self.block_meta_data.as_ref() {
let len = v.compute_size();
my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
}
@ -3297,12 +3297,12 @@ impl ::protobuf::Message for BuildGridContext {
os.write_raw_varint32(v.get_cached_size())?;
v.write_to_with_cached_sizes(os)?;
};
if let Some(ref v) = self.grid_block.as_ref() {
if let Some(ref v) = self.block_metas.as_ref() {
os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?;
os.write_raw_varint32(v.get_cached_size())?;
v.write_to_with_cached_sizes(os)?;
}
if let Some(ref v) = self.grid_block_meta_data.as_ref() {
if let Some(ref v) = self.block_meta_data.as_ref() {
os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?;
os.write_raw_varint32(v.get_cached_size())?;
v.write_to_with_cached_sizes(os)?;
@ -3351,14 +3351,14 @@ impl ::protobuf::Message for BuildGridContext {
|m: &mut BuildGridContext| { &mut m.field_metas },
));
fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<GridBlockMeta>>(
"grid_block",
|m: &BuildGridContext| { &m.grid_block },
|m: &mut BuildGridContext| { &mut m.grid_block },
"block_metas",
|m: &BuildGridContext| { &m.block_metas },
|m: &mut BuildGridContext| { &mut m.block_metas },
));
fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<GridBlockMetaData>>(
"grid_block_meta_data",
|m: &BuildGridContext| { &m.grid_block_meta_data },
|m: &mut BuildGridContext| { &mut m.grid_block_meta_data },
fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<GridBlockMetaSerde>>(
"block_meta_data",
|m: &BuildGridContext| { &m.block_meta_data },
|m: &mut BuildGridContext| { &mut m.block_meta_data },
));
::protobuf::reflect::MessageDescriptor::new_pb_name::<BuildGridContext>(
"BuildGridContext",
@ -3377,8 +3377,8 @@ impl ::protobuf::Message for BuildGridContext {
impl ::protobuf::Clear for BuildGridContext {
fn clear(&mut self) {
self.field_metas.clear();
self.grid_block.clear();
self.grid_block_meta_data.clear();
self.block_metas.clear();
self.block_meta_data.clear();
self.unknown_fields.clear();
}
}
@ -3458,22 +3458,22 @@ impl ::protobuf::reflect::ProtobufValue for FieldType {
}
static file_descriptor_proto_data: &'static [u8] = b"\
\n\nmeta.proto\"o\n\x08GridMeta\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\
\n\nmeta.proto\"x\n\x08GridMeta\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\
\x06gridId\x12\"\n\x06fields\x18\x02\x20\x03(\x0b2\n.FieldMetaR\x06field\
s\x12&\n\x06blocks\x18\x03\x20\x03(\x0b2\x0e.GridBlockMetaR\x06blocks\"o\
\n\rGridBlockMeta\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\
\x12&\n\x0fstart_row_index\x18\x02\x20\x01(\x05R\rstartRowIndex\x12\x1b\
\n\trow_count\x18\x03\x20\x01(\x05R\x08rowCount\"U\n\x11GridBlockMetaDat\
a\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12%\n\trow_metas\
\x18\x02\x20\x03(\x0b2\x08.RowMetaR\x08rowMetas\"\xdf\x01\n\tFieldMeta\
\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\x20\
\x01(\tR\x04name\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12)\n\nf\
ield_type\x18\x04\x20\x01(\x0e2\n.FieldTypeR\tfieldType\x12\x16\n\x06fro\
zen\x18\x05\x20\x01(\x08R\x06frozen\x12\x1e\n\nvisibility\x18\x06\x20\
\x01(\x08R\nvisibility\x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05width\
\x12!\n\x0ctype_options\x18\x08\x20\x01(\tR\x0btypeOptions\"\xfd\x02\n\
\x0eFieldChangeset\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\
\x12\x14\n\x04name\x18\x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\
s\x12/\n\x0bblock_metas\x18\x03\x20\x03(\x0b2\x0e.GridBlockMetaR\nblockM\
etas\"o\n\rGridBlockMeta\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07bl\
ockId\x12&\n\x0fstart_row_index\x18\x02\x20\x01(\x05R\rstartRowIndex\x12\
\x1b\n\trow_count\x18\x03\x20\x01(\x05R\x08rowCount\"V\n\x12GridBlockMet\
aSerde\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12%\n\trow_\
metas\x18\x02\x20\x03(\x0b2\x08.RowMetaR\x08rowMetas\"\xdf\x01\n\tFieldM\
eta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\x18\x02\
\x20\x01(\tR\x04name\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12)\
\n\nfield_type\x18\x04\x20\x01(\x0e2\n.FieldTypeR\tfieldType\x12\x16\n\
\x06frozen\x18\x05\x20\x01(\x08R\x06frozen\x12\x1e\n\nvisibility\x18\x06\
\x20\x01(\x08R\nvisibility\x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05w\
idth\x12!\n\x0ctype_options\x18\x08\x20\x01(\tR\x0btypeOptions\"\xfd\x02\
\n\x0eFieldChangeset\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldI\
d\x12\x14\n\x04name\x18\x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\
\x03\x20\x01(\tH\x01R\x04desc\x12+\n\nfield_type\x18\x04\x20\x01(\x0e2\n\
.FieldTypeH\x02R\tfieldType\x12\x18\n\x06frozen\x18\x05\x20\x01(\x08H\
\x03R\x06frozen\x12\x20\n\nvisibility\x18\x06\x20\x01(\x08H\x04R\nvisibi\
@ -3501,14 +3501,13 @@ static file_descriptor_proto_data: &'static [u8] = b"\
\x11CellMetaChangeset\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\
\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\
\x18\x03\x20\x01(\tR\x07fieldId\x12\x14\n\x04data\x18\x04\x20\x01(\tH\0R\
\x04dataB\r\n\x0bone_of_data\"\xb3\x01\n\x10BuildGridContext\x12+\n\x0bf\
ield_metas\x18\x01\x20\x03(\x0b2\n.FieldMetaR\nfieldMetas\x12-\n\ngrid_b\
lock\x18\x02\x20\x01(\x0b2\x0e.GridBlockMetaR\tgridBlock\x12C\n\x14grid_\
block_meta_data\x18\x03\x20\x01(\x0b2\x12.GridBlockMetaDataR\x11gridBloc\
kMetaData*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Number\
\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\
\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06prot\
o3\
\x04dataB\r\n\x0bone_of_data\"\xad\x01\n\x10BuildGridContext\x12+\n\x0bf\
ield_metas\x18\x01\x20\x03(\x0b2\n.FieldMetaR\nfieldMetas\x12/\n\x0bbloc\
k_metas\x18\x02\x20\x01(\x0b2\x0e.GridBlockMetaR\nblockMetas\x12;\n\x0fb\
lock_meta_data\x18\x03\x20\x01(\x0b2\x13.GridBlockMetaSerdeR\rblockMetaD\
ata*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Number\x10\x01\
\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\x12\x0f\
\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06proto3\
";
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

View File

@ -4,7 +4,7 @@ import "meta.proto";
message Grid {
string id = 1;
repeated FieldOrder field_orders = 2;
repeated GridBlockMeta blocks = 3;
repeated GridBlockOrder block_orders = 3;
}
message Field {
string id = 1;
@ -36,12 +36,18 @@ message Row {
map<string, Cell> cell_by_field_id = 2;
int32 height = 3;
}
message RepeatedRow {
repeated Row items = 1;
}
message RepeatedGridBlock {
repeated GridBlock items = 1;
}
message GridBlockOrder {
string block_id = 1;
}
message GridBlock {
string block_id = 1;
repeated Row rows = 2;
repeated string row_ids = 2;
}
message Cell {
string field_id = 1;
@ -61,7 +67,7 @@ message GridBlockId {
}
message CreateRowPayload {
string grid_id = 1;
oneof one_of_upper_row_id { string upper_row_id = 2; };
oneof one_of_start_row_id { string start_row_id = 2; };
}
message QueryFieldPayload {
string grid_id = 1;
@ -69,5 +75,10 @@ message QueryFieldPayload {
}
message QueryGridBlocksPayload {
string grid_id = 1;
repeated GridBlockMeta blocks = 2;
repeated GridBlockOrder block_orders = 2;
}
message QueryRowPayload {
string grid_id = 1;
string block_id = 2;
string row_id = 3;
}

View File

@ -3,14 +3,14 @@ syntax = "proto3";
message GridMeta {
string grid_id = 1;
repeated FieldMeta fields = 2;
repeated GridBlockMeta blocks = 3;
repeated GridBlockMeta block_metas = 3;
}
message GridBlockMeta {
string block_id = 1;
int32 start_row_index = 2;
int32 row_count = 3;
}
message GridBlockMetaData {
message GridBlockMetaSerde {
string block_id = 1;
repeated RowMeta row_metas = 2;
}
@ -63,8 +63,8 @@ message CellMetaChangeset {
}
message BuildGridContext {
repeated FieldMeta field_metas = 1;
GridBlockMeta grid_block = 2;
GridBlockMetaData grid_block_meta_data = 3;
GridBlockMeta block_metas = 2;
GridBlockMetaSerde block_meta_data = 3;
}
enum FieldType {
RichText = 0;

View File

@ -7,7 +7,7 @@ fn grid_serde_test() {
let grid = GridMeta {
grid_id,
fields,
blocks: vec![],
block_metas: vec![],
};
let grid_1_json = serde_json::to_string(&grid).unwrap();
@ -24,7 +24,7 @@ fn grid_default_serde_test() {
let grid = GridMeta {
grid_id,
fields: vec![],
blocks: vec![],
block_metas: vec![],
};
let json = serde_json::to_string(&grid).unwrap();