mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
refactor: fetch block data
This commit is contained in:
parent
a08590bcba
commit
0f868f48f3
@ -0,0 +1,90 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'dart:collection';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:app_flowy/core/notification_helper.dart';
|
||||||
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:flowy_infra/notifier.dart';
|
||||||
|
import 'package:flowy_sdk/log.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
|
||||||
|
|
||||||
|
class GridBlockCache {
|
||||||
|
final String gridId;
|
||||||
|
void Function(GridBlockUpdateNotifierValue)? _onBlockChanged;
|
||||||
|
|
||||||
|
final LinkedHashMap<String, _GridBlockListener> _listeners = LinkedHashMap();
|
||||||
|
GridBlockCache({required this.gridId});
|
||||||
|
|
||||||
|
void start(void Function(GridBlockUpdateNotifierValue) onBlockChanged) {
|
||||||
|
_onBlockChanged = onBlockChanged;
|
||||||
|
for (final listener in _listeners.values) {
|
||||||
|
listener.start(onBlockChanged);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> dispose() async {
|
||||||
|
for (final listener in _listeners.values) {
|
||||||
|
await listener.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void addBlockListener(String blockId) {
|
||||||
|
if (_onBlockChanged == null) {
|
||||||
|
Log.error("Should call start() first");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (_listeners.containsKey(blockId)) {
|
||||||
|
Log.error("Duplicate block listener");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final listener = _GridBlockListener(blockId: blockId);
|
||||||
|
listener.start(_onBlockChanged!);
|
||||||
|
_listeners[blockId] = listener;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef GridBlockUpdateNotifierValue = Either<List<GridRowsChangeset>, FlowyError>;
|
||||||
|
|
||||||
|
class _GridBlockListener {
|
||||||
|
final String blockId;
|
||||||
|
PublishNotifier<GridBlockUpdateNotifierValue>? _rowsUpdateNotifier = PublishNotifier();
|
||||||
|
GridNotificationListener? _listener;
|
||||||
|
|
||||||
|
_GridBlockListener({required this.blockId});
|
||||||
|
|
||||||
|
void start(void Function(GridBlockUpdateNotifierValue) onBlockChanged) {
|
||||||
|
if (_listener != null) {
|
||||||
|
_listener?.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
_listener = GridNotificationListener(
|
||||||
|
objectId: blockId,
|
||||||
|
handler: _handler,
|
||||||
|
);
|
||||||
|
|
||||||
|
_rowsUpdateNotifier?.addPublishListener(onBlockChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _handler(GridNotification ty, Either<Uint8List, FlowyError> result) {
|
||||||
|
switch (ty) {
|
||||||
|
case GridNotification.DidUpdateGridRow:
|
||||||
|
result.fold(
|
||||||
|
(payload) => _rowsUpdateNotifier?.value = left([GridRowsChangeset.fromBuffer(payload)]),
|
||||||
|
(error) => _rowsUpdateNotifier?.value = right(error),
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> stop() async {
|
||||||
|
await _listener?.stop();
|
||||||
|
_rowsUpdateNotifier?.dispose();
|
||||||
|
_rowsUpdateNotifier = null;
|
||||||
|
}
|
||||||
|
}
|
@ -2,21 +2,21 @@ part of 'cell_service.dart';
|
|||||||
|
|
||||||
typedef GridCellMap = LinkedHashMap<String, GridCell>;
|
typedef GridCellMap = LinkedHashMap<String, GridCell>;
|
||||||
|
|
||||||
class GridCellCacheData {
|
class _GridCellCacheObject {
|
||||||
GridCellCacheKey key;
|
_GridCellCacheKey key;
|
||||||
dynamic object;
|
dynamic object;
|
||||||
GridCellCacheData({
|
_GridCellCacheObject({
|
||||||
required this.key,
|
required this.key,
|
||||||
required this.object,
|
required this.object,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class GridCellCacheKey {
|
class _GridCellCacheKey {
|
||||||
final String fieldId;
|
final String fieldId;
|
||||||
final String objectId;
|
final String rowId;
|
||||||
GridCellCacheKey({
|
_GridCellCacheKey({
|
||||||
required this.fieldId,
|
required this.fieldId,
|
||||||
required this.objectId,
|
required this.rowId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,46 +51,46 @@ class GridCellCache {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void addFieldListener(GridCellCacheKey cacheKey, VoidCallback onFieldChanged) {
|
void addFieldListener(_GridCellCacheKey cacheKey, VoidCallback onFieldChanged) {
|
||||||
var map = _fieldListenerByFieldId[cacheKey.fieldId];
|
var map = _fieldListenerByFieldId[cacheKey.fieldId];
|
||||||
if (map == null) {
|
if (map == null) {
|
||||||
_fieldListenerByFieldId[cacheKey.fieldId] = {};
|
_fieldListenerByFieldId[cacheKey.fieldId] = {};
|
||||||
map = _fieldListenerByFieldId[cacheKey.fieldId];
|
map = _fieldListenerByFieldId[cacheKey.fieldId];
|
||||||
map![cacheKey.objectId] = [onFieldChanged];
|
map![cacheKey.rowId] = [onFieldChanged];
|
||||||
} else {
|
} else {
|
||||||
var objects = map[cacheKey.objectId];
|
var objects = map[cacheKey.rowId];
|
||||||
if (objects == null) {
|
if (objects == null) {
|
||||||
map[cacheKey.objectId] = [onFieldChanged];
|
map[cacheKey.rowId] = [onFieldChanged];
|
||||||
} else {
|
} else {
|
||||||
objects.add(onFieldChanged);
|
objects.add(onFieldChanged);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeFieldListener(GridCellCacheKey cacheKey, VoidCallback fn) {
|
void removeFieldListener(_GridCellCacheKey cacheKey, VoidCallback fn) {
|
||||||
var callbacks = _fieldListenerByFieldId[cacheKey.fieldId]?[cacheKey.objectId];
|
var callbacks = _fieldListenerByFieldId[cacheKey.fieldId]?[cacheKey.rowId];
|
||||||
final index = callbacks?.indexWhere((callback) => callback == fn);
|
final index = callbacks?.indexWhere((callback) => callback == fn);
|
||||||
if (index != null && index != -1) {
|
if (index != null && index != -1) {
|
||||||
callbacks?.removeAt(index);
|
callbacks?.removeAt(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void insert<T extends GridCellCacheData>(T item) {
|
void insert<T extends _GridCellCacheObject>(T item) {
|
||||||
var map = _cellDataByFieldId[item.key.fieldId];
|
var map = _cellDataByFieldId[item.key.fieldId];
|
||||||
if (map == null) {
|
if (map == null) {
|
||||||
_cellDataByFieldId[item.key.fieldId] = {};
|
_cellDataByFieldId[item.key.fieldId] = {};
|
||||||
map = _cellDataByFieldId[item.key.fieldId];
|
map = _cellDataByFieldId[item.key.fieldId];
|
||||||
}
|
}
|
||||||
|
|
||||||
map![item.key.objectId] = item.object;
|
map![item.key.rowId] = item.object;
|
||||||
}
|
}
|
||||||
|
|
||||||
T? get<T>(GridCellCacheKey key) {
|
T? get<T>(_GridCellCacheKey key) {
|
||||||
final map = _cellDataByFieldId[key.fieldId];
|
final map = _cellDataByFieldId[key.fieldId];
|
||||||
if (map == null) {
|
if (map == null) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
final object = map[key.objectId];
|
final object = map[key.rowId];
|
||||||
if (object is T) {
|
if (object is T) {
|
||||||
return object;
|
return object;
|
||||||
} else {
|
} else {
|
@ -19,10 +19,10 @@ import 'package:app_flowy/workspace/application/grid/cell/select_option_service.
|
|||||||
import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
|
import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
|
||||||
import 'dart:convert' show utf8;
|
import 'dart:convert' show utf8;
|
||||||
part 'cell_service.freezed.dart';
|
part 'cell_service.freezed.dart';
|
||||||
part 'data_loader.dart';
|
part 'cell_data_loader.dart';
|
||||||
part 'context_builder.dart';
|
part 'context_builder.dart';
|
||||||
part 'data_cache.dart';
|
part 'cell_data_cache.dart';
|
||||||
part 'data_persistence.dart';
|
part 'cell_data_persistence.dart';
|
||||||
|
|
||||||
// key: rowId
|
// key: rowId
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ class GridCellContextBuilder {
|
|||||||
class _GridCellContext<T, D> extends Equatable {
|
class _GridCellContext<T, D> extends Equatable {
|
||||||
final GridCell gridCell;
|
final GridCell gridCell;
|
||||||
final GridCellCache cellCache;
|
final GridCellCache cellCache;
|
||||||
final GridCellCacheKey _cacheKey;
|
final _GridCellCacheKey _cacheKey;
|
||||||
final IGridCellDataLoader<T> cellDataLoader;
|
final IGridCellDataLoader<T> cellDataLoader;
|
||||||
final _GridCellDataPersistence<D> cellDataPersistence;
|
final _GridCellDataPersistence<D> cellDataPersistence;
|
||||||
final FieldService _fieldService;
|
final FieldService _fieldService;
|
||||||
@ -118,7 +118,7 @@ class _GridCellContext<T, D> extends Equatable {
|
|||||||
required this.cellDataLoader,
|
required this.cellDataLoader,
|
||||||
required this.cellDataPersistence,
|
required this.cellDataPersistence,
|
||||||
}) : _fieldService = FieldService(gridId: gridCell.gridId, fieldId: gridCell.field.id),
|
}) : _fieldService = FieldService(gridId: gridCell.gridId, fieldId: gridCell.field.id),
|
||||||
_cacheKey = GridCellCacheKey(objectId: gridCell.rowId, fieldId: gridCell.field.id);
|
_cacheKey = _GridCellCacheKey(rowId: gridCell.rowId, fieldId: gridCell.field.id);
|
||||||
|
|
||||||
_GridCellContext<T, D> clone() {
|
_GridCellContext<T, D> clone() {
|
||||||
return _GridCellContext(
|
return _GridCellContext(
|
||||||
@ -213,7 +213,7 @@ class _GridCellContext<T, D> extends Equatable {
|
|||||||
_loadDataOperation = Timer(const Duration(milliseconds: 10), () {
|
_loadDataOperation = Timer(const Duration(milliseconds: 10), () {
|
||||||
cellDataLoader.loadData().then((data) {
|
cellDataLoader.loadData().then((data) {
|
||||||
_cellDataNotifier?.value = data;
|
_cellDataNotifier?.value = data;
|
||||||
cellCache.insert(GridCellCacheData(key: _cacheKey, object: data));
|
cellCache.insert(_GridCellCacheObject(key: _cacheKey, object: data));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
|
import 'package:flowy_sdk/log.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/protobuf.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/protobuf.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
import 'block/block_listener.dart';
|
||||||
import 'cell/cell_service/cell_service.dart';
|
import 'cell/cell_service/cell_service.dart';
|
||||||
import 'grid_service.dart';
|
import 'grid_service.dart';
|
||||||
import 'row/row_service.dart';
|
import 'row/row_service.dart';
|
||||||
@ -19,9 +21,12 @@ class GridBloc extends Bloc<GridEvent, GridState> {
|
|||||||
late final GridRowCache rowCache;
|
late final GridRowCache rowCache;
|
||||||
late final GridCellCache cellCache;
|
late final GridCellCache cellCache;
|
||||||
|
|
||||||
|
final GridBlockCache blockCache;
|
||||||
|
|
||||||
GridBloc({required View view})
|
GridBloc({required View view})
|
||||||
: _gridService = GridService(gridId: view.id),
|
: _gridService = GridService(gridId: view.id),
|
||||||
fieldCache = GridFieldCache(gridId: view.id),
|
fieldCache = GridFieldCache(gridId: view.id),
|
||||||
|
blockCache = GridBlockCache(gridId: view.id),
|
||||||
super(GridState.initial(view.id)) {
|
super(GridState.initial(view.id)) {
|
||||||
rowCache = GridRowCache(
|
rowCache = GridRowCache(
|
||||||
gridId: view.id,
|
gridId: view.id,
|
||||||
@ -33,6 +38,13 @@ class GridBloc extends Bloc<GridEvent, GridState> {
|
|||||||
fieldDelegate: GridCellCacheDelegateImpl(fieldCache),
|
fieldDelegate: GridCellCacheDelegateImpl(fieldCache),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
blockCache.start((result) {
|
||||||
|
result.fold(
|
||||||
|
(changesets) => rowCache.applyChangesets(changesets),
|
||||||
|
(err) => Log.error(err),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
on<GridEvent>(
|
on<GridEvent>(
|
||||||
(event, emit) async {
|
(event, emit) async {
|
||||||
await event.when(
|
await event.when(
|
||||||
@ -60,6 +72,7 @@ class GridBloc extends Bloc<GridEvent, GridState> {
|
|||||||
await cellCache.dispose();
|
await cellCache.dispose();
|
||||||
await rowCache.dispose();
|
await rowCache.dispose();
|
||||||
await fieldCache.dispose();
|
await fieldCache.dispose();
|
||||||
|
await blockCache.dispose();
|
||||||
return super.close();
|
return super.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,7 +92,15 @@ class GridBloc extends Bloc<GridEvent, GridState> {
|
|||||||
final result = await _gridService.loadGrid();
|
final result = await _gridService.loadGrid();
|
||||||
return Future(
|
return Future(
|
||||||
() => result.fold(
|
() => result.fold(
|
||||||
(grid) async => await _loadFields(grid, emit),
|
(grid) async {
|
||||||
|
for (final block in grid.blocks) {
|
||||||
|
blockCache.addBlockListener(block.id);
|
||||||
|
}
|
||||||
|
final rowOrders = grid.blocks.expand((block) => block.rowOrders).toList();
|
||||||
|
rowCache.initialRows(rowOrders);
|
||||||
|
|
||||||
|
await _loadFields(grid, emit);
|
||||||
|
},
|
||||||
(err) => emit(state.copyWith(loadingState: GridLoadingState.finish(right(err)))),
|
(err) => emit(state.copyWith(loadingState: GridLoadingState.finish(right(err)))),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -91,7 +112,6 @@ class GridBloc extends Bloc<GridEvent, GridState> {
|
|||||||
() => result.fold(
|
() => result.fold(
|
||||||
(fields) {
|
(fields) {
|
||||||
fieldCache.fields = fields.items;
|
fieldCache.fields = fields.items;
|
||||||
rowCache.resetRows(grid.blockOrders);
|
|
||||||
|
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
grid: Some(grid),
|
grid: Some(grid),
|
||||||
@ -143,7 +163,6 @@ class GridLoadingState with _$GridLoadingState {
|
|||||||
|
|
||||||
class GridFieldEquatable extends Equatable {
|
class GridFieldEquatable extends Equatable {
|
||||||
final List<Field> _fields;
|
final List<Field> _fields;
|
||||||
|
|
||||||
const GridFieldEquatable(List<Field> fields) : _fields = fields;
|
const GridFieldEquatable(List<Field> fields) : _fields = fields;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -1,42 +0,0 @@
|
|||||||
import 'package:dartz/dartz.dart';
|
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
|
|
||||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
|
|
||||||
import 'package:flowy_infra/notifier.dart';
|
|
||||||
import 'dart:async';
|
|
||||||
import 'dart:typed_data';
|
|
||||||
import 'package:app_flowy/core/notification_helper.dart';
|
|
||||||
|
|
||||||
class GridRowListener {
|
|
||||||
final String gridId;
|
|
||||||
PublishNotifier<Either<List<GridRowsChangeset>, FlowyError>> rowsUpdateNotifier = PublishNotifier(comparable: null);
|
|
||||||
GridNotificationListener? _listener;
|
|
||||||
|
|
||||||
GridRowListener({required this.gridId});
|
|
||||||
|
|
||||||
void start() {
|
|
||||||
_listener = GridNotificationListener(
|
|
||||||
objectId: gridId,
|
|
||||||
handler: _handler,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _handler(GridNotification ty, Either<Uint8List, FlowyError> result) {
|
|
||||||
switch (ty) {
|
|
||||||
case GridNotification.DidUpdateGridRow:
|
|
||||||
result.fold(
|
|
||||||
(payload) => rowsUpdateNotifier.value = left([GridRowsChangeset.fromBuffer(payload)]),
|
|
||||||
(error) => rowsUpdateNotifier.value = right(error),
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> stop() async {
|
|
||||||
await _listener?.stop();
|
|
||||||
rowsUpdateNotifier.dispose();
|
|
||||||
}
|
|
||||||
}
|
|
@ -10,7 +10,6 @@ import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
|
|||||||
import 'package:flowy_sdk/protobuf/flowy-grid/row_entities.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/row_entities.pb.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'package:app_flowy/workspace/application/grid/grid_listener.dart';
|
|
||||||
part 'row_service.freezed.dart';
|
part 'row_service.freezed.dart';
|
||||||
|
|
||||||
typedef RowUpdateCallback = void Function();
|
typedef RowUpdateCallback = void Function();
|
||||||
@ -24,7 +23,6 @@ abstract class GridRowFieldDelegate {
|
|||||||
class GridRowCache {
|
class GridRowCache {
|
||||||
final String gridId;
|
final String gridId;
|
||||||
final RowsNotifier _rowsNotifier;
|
final RowsNotifier _rowsNotifier;
|
||||||
final GridRowListener _rowsListener;
|
|
||||||
final GridRowFieldDelegate _fieldDelegate;
|
final GridRowFieldDelegate _fieldDelegate;
|
||||||
List<GridRow> get clonedRows => _rowsNotifier.clonedRows;
|
List<GridRow> get clonedRows => _rowsNotifier.clonedRows;
|
||||||
|
|
||||||
@ -39,32 +37,23 @@ class GridRowCache {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
_rowsListener = GridRowListener(gridId: gridId),
|
|
||||||
_fieldDelegate = fieldDelegate {
|
_fieldDelegate = fieldDelegate {
|
||||||
//
|
//
|
||||||
fieldDelegate.onFieldChanged(() => _rowsNotifier.fieldDidChange());
|
fieldDelegate.onFieldChanged(() => _rowsNotifier.fieldDidChange());
|
||||||
|
|
||||||
// listen on the row update
|
|
||||||
_rowsListener.rowsUpdateNotifier.addPublishListener((result) {
|
|
||||||
result.fold(
|
|
||||||
(changesets) {
|
|
||||||
for (final changeset in changesets) {
|
|
||||||
_rowsNotifier.deleteRows(changeset.deletedRows);
|
|
||||||
_rowsNotifier.insertRows(changeset.insertedRows);
|
|
||||||
_rowsNotifier.updateRows(changeset.updatedRows);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
(err) => Log.error(err),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
_rowsListener.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> dispose() async {
|
Future<void> dispose() async {
|
||||||
await _rowsListener.stop();
|
|
||||||
_rowsNotifier.dispose();
|
_rowsNotifier.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void applyChangesets(List<GridRowsChangeset> changesets) {
|
||||||
|
for (final changeset in changesets) {
|
||||||
|
_rowsNotifier.deleteRows(changeset.deletedRows);
|
||||||
|
_rowsNotifier.insertRows(changeset.insertedRows);
|
||||||
|
_rowsNotifier.updateRows(changeset.updatedRows);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void addListener({
|
void addListener({
|
||||||
void Function(List<GridRow>, GridRowChangeReason)? onChanged,
|
void Function(List<GridRow>, GridRowChangeReason)? onChanged,
|
||||||
bool Function()? listenWhen,
|
bool Function()? listenWhen,
|
||||||
@ -130,9 +119,8 @@ class GridRowCache {
|
|||||||
return _makeGridCells(rowId, data);
|
return _makeGridCells(rowId, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void resetRows(List<GridBlockOrder> blocks) {
|
void initialRows(List<RowOrder> rowOrders) {
|
||||||
final rowOrders = blocks.expand((block) => block.rowOrders).toList();
|
_rowsNotifier.initialRows(rowOrders);
|
||||||
_rowsNotifier.reset(rowOrders);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _loadRow(String rowId) async {
|
Future<void> _loadRow(String rowId) async {
|
||||||
@ -142,7 +130,11 @@ class GridRowCache {
|
|||||||
|
|
||||||
final result = await GridEventGetRow(payload).send();
|
final result = await GridEventGetRow(payload).send();
|
||||||
result.fold(
|
result.fold(
|
||||||
(rowData) => _rowsNotifier.rowData = rowData,
|
(rowData) {
|
||||||
|
if (rowData.hasRow()) {
|
||||||
|
_rowsNotifier.rowData = rowData.row;
|
||||||
|
}
|
||||||
|
},
|
||||||
(err) => Log.error(err),
|
(err) => Log.error(err),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -173,7 +165,9 @@ class RowsNotifier extends ChangeNotifier {
|
|||||||
required this.rowBuilder,
|
required this.rowBuilder,
|
||||||
});
|
});
|
||||||
|
|
||||||
void reset(List<RowOrder> rowOrders) {
|
List<GridRow> get clonedRows => [..._rows];
|
||||||
|
|
||||||
|
void initialRows(List<RowOrder> rowOrders) {
|
||||||
_rowDataMap = HashMap();
|
_rowDataMap = HashMap();
|
||||||
final rows = rowOrders.map((rowOrder) => rowBuilder(rowOrder)).toList();
|
final rows = rowOrders.map((rowOrder) => rowBuilder(rowOrder)).toList();
|
||||||
_update(rows, const GridRowChangeReason.initial());
|
_update(rows, const GridRowChangeReason.initial());
|
||||||
@ -199,20 +193,20 @@ class RowsNotifier extends ChangeNotifier {
|
|||||||
_update(newRows, GridRowChangeReason.delete(deletedIndex));
|
_update(newRows, GridRowChangeReason.delete(deletedIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
void insertRows(List<IndexRowOrder> createdRows) {
|
void insertRows(List<IndexRowOrder> insertRows) {
|
||||||
if (createdRows.isEmpty) {
|
if (insertRows.isEmpty) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
InsertedIndexs insertIndexs = [];
|
InsertedIndexs insertIndexs = [];
|
||||||
final List<GridRow> newRows = clonedRows;
|
final List<GridRow> newRows = clonedRows;
|
||||||
for (final createdRow in createdRows) {
|
for (final insertRow in insertRows) {
|
||||||
final insertIndex = InsertedIndex(
|
final insertIndex = InsertedIndex(
|
||||||
index: createdRow.index,
|
index: insertRow.index,
|
||||||
rowId: createdRow.rowOrder.rowId,
|
rowId: insertRow.rowOrder.rowId,
|
||||||
);
|
);
|
||||||
insertIndexs.add(insertIndex);
|
insertIndexs.add(insertIndex);
|
||||||
newRows.insert(createdRow.index, (rowBuilder(createdRow.rowOrder)));
|
newRows.insert(insertRow.index, (rowBuilder(insertRow.rowOrder)));
|
||||||
}
|
}
|
||||||
_update(newRows, GridRowChangeReason.insert(insertIndexs));
|
_update(newRows, GridRowChangeReason.insert(insertIndexs));
|
||||||
}
|
}
|
||||||
@ -281,8 +275,6 @@ class RowsNotifier extends ChangeNotifier {
|
|||||||
Row? rowDataWithId(String rowId) {
|
Row? rowDataWithId(String rowId) {
|
||||||
return _rowDataMap[rowId];
|
return _rowDataMap[rowId];
|
||||||
}
|
}
|
||||||
|
|
||||||
List<GridRow> get clonedRows => [..._rows];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class RowService {
|
class RowService {
|
||||||
@ -310,7 +302,7 @@ class RowService {
|
|||||||
return GridEventMoveItem(payload).send();
|
return GridEventMoveItem(payload).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Either<Row, FlowyError>> getRow() {
|
Future<Either<OptionalRow, FlowyError>> getRow() {
|
||||||
final payload = RowIdentifierPayload.create()
|
final payload = RowIdentifierPayload.create()
|
||||||
..gridId = gridId
|
..gridId = gridId
|
||||||
..rowId = rowId;
|
..rowId = rowId;
|
||||||
|
@ -48,12 +48,7 @@ pub(crate) async fn get_grid_blocks_handler(
|
|||||||
) -> DataResult<RepeatedGridBlock, FlowyError> {
|
) -> DataResult<RepeatedGridBlock, FlowyError> {
|
||||||
let params: QueryGridBlocksParams = data.into_inner().try_into()?;
|
let params: QueryGridBlocksParams = data.into_inner().try_into()?;
|
||||||
let editor = manager.get_grid_editor(¶ms.grid_id)?;
|
let editor = manager.get_grid_editor(¶ms.grid_id)?;
|
||||||
let block_ids = params
|
let repeated_grid_block = editor.get_blocks(Some(params.block_ids)).await?;
|
||||||
.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)
|
data_result(repeated_grid_block)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,13 +215,13 @@ async fn get_type_option_data(field_rev: &FieldRevision, field_type: &FieldType)
|
|||||||
pub(crate) async fn get_row_handler(
|
pub(crate) async fn get_row_handler(
|
||||||
data: Data<RowIdentifierPayload>,
|
data: Data<RowIdentifierPayload>,
|
||||||
manager: AppData<Arc<GridManager>>,
|
manager: AppData<Arc<GridManager>>,
|
||||||
) -> DataResult<Row, FlowyError> {
|
) -> DataResult<OptionalRow, FlowyError> {
|
||||||
let params: RowIdentifier = data.into_inner().try_into()?;
|
let params: RowIdentifier = data.into_inner().try_into()?;
|
||||||
let editor = manager.get_grid_editor(¶ms.grid_id)?;
|
let editor = manager.get_grid_editor(¶ms.grid_id)?;
|
||||||
match editor.get_row(¶ms.row_id).await? {
|
let row = OptionalRow {
|
||||||
None => Err(FlowyError::record_not_found().context("Can not find the row")),
|
row: editor.get_row(¶ms.row_id).await?,
|
||||||
Some(row) => data_result(row),
|
};
|
||||||
}
|
data_result(row)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip(data, manager), err)]
|
#[tracing::instrument(level = "debug", skip(data, manager), err)]
|
||||||
|
@ -99,7 +99,7 @@ pub enum GridEvent {
|
|||||||
#[event(input = "CreateRowPayload", output = "Row")]
|
#[event(input = "CreateRowPayload", output = "Row")]
|
||||||
CreateRow = 50,
|
CreateRow = 50,
|
||||||
|
|
||||||
#[event(input = "RowIdentifierPayload", output = "Row")]
|
#[event(input = "RowIdentifierPayload", output = "OptionalRow")]
|
||||||
GetRow = 51,
|
GetRow = 51,
|
||||||
|
|
||||||
#[event(input = "RowIdentifierPayload")]
|
#[event(input = "RowIdentifierPayload")]
|
||||||
|
@ -2,7 +2,7 @@ use crate::dart_notification::{send_dart_notification, GridNotification};
|
|||||||
use crate::manager::GridUser;
|
use crate::manager::GridUser;
|
||||||
use crate::services::block_revision_editor::GridBlockRevisionEditor;
|
use crate::services::block_revision_editor::GridBlockRevisionEditor;
|
||||||
use crate::services::persistence::block_index::BlockIndexCache;
|
use crate::services::persistence::block_index::BlockIndexCache;
|
||||||
use crate::services::row::{group_row_orders, GridBlockSnapshot};
|
use crate::services::row::{block_from_row_orders, GridBlockSnapshot};
|
||||||
use dashmap::DashMap;
|
use dashmap::DashMap;
|
||||||
use flowy_error::FlowyResult;
|
use flowy_error::FlowyResult;
|
||||||
use flowy_grid_data_model::entities::{
|
use flowy_grid_data_model::entities::{
|
||||||
@ -77,7 +77,7 @@ impl GridBlockManager {
|
|||||||
index_row_order.index = row_index;
|
index_row_order.index = row_index;
|
||||||
|
|
||||||
let _ = self
|
let _ = self
|
||||||
.notify_did_update_block(GridRowsChangeset::insert(block_id, vec![index_row_order]))
|
.notify_did_update_block(block_id, GridRowsChangeset::insert(block_id, vec![index_row_order]))
|
||||||
.await?;
|
.await?;
|
||||||
Ok(row_count)
|
Ok(row_count)
|
||||||
}
|
}
|
||||||
@ -102,7 +102,7 @@ impl GridBlockManager {
|
|||||||
changesets.push(GridBlockRevisionChangeset::from_row_count(&block_id, row_count));
|
changesets.push(GridBlockRevisionChangeset::from_row_count(&block_id, row_count));
|
||||||
|
|
||||||
let _ = self
|
let _ = self
|
||||||
.notify_did_update_block(GridRowsChangeset::insert(&block_id, inserted_row_orders))
|
.notify_did_update_block(&block_id, GridRowsChangeset::insert(&block_id, inserted_row_orders))
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,7 +121,9 @@ impl GridBlockManager {
|
|||||||
if let Some(row) = row_builder(row_rev.clone()) {
|
if let Some(row) = row_builder(row_rev.clone()) {
|
||||||
let row_order = UpdatedRowOrder::new(&row_rev, row);
|
let row_order = UpdatedRowOrder::new(&row_rev, row);
|
||||||
let block_order_changeset = GridRowsChangeset::update(&editor.block_id, vec![row_order]);
|
let block_order_changeset = GridRowsChangeset::update(&editor.block_id, vec![row_order]);
|
||||||
let _ = self.notify_did_update_block(block_order_changeset).await?;
|
let _ = self
|
||||||
|
.notify_did_update_block(&editor.block_id, block_order_changeset)
|
||||||
|
.await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -137,7 +139,7 @@ impl GridBlockManager {
|
|||||||
Some(row_order) => {
|
Some(row_order) => {
|
||||||
let _ = editor.delete_rows(vec![Cow::Borrowed(&row_id)]).await?;
|
let _ = editor.delete_rows(vec![Cow::Borrowed(&row_id)]).await?;
|
||||||
let _ = self
|
let _ = self
|
||||||
.notify_did_update_block(GridRowsChangeset::delete(&block_id, vec![row_order]))
|
.notify_did_update_block(&block_id, GridRowsChangeset::delete(&block_id, vec![row_order]))
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -147,15 +149,15 @@ impl GridBlockManager {
|
|||||||
|
|
||||||
pub(crate) async fn delete_rows(&self, row_orders: Vec<RowOrder>) -> FlowyResult<Vec<GridBlockRevisionChangeset>> {
|
pub(crate) async fn delete_rows(&self, row_orders: Vec<RowOrder>) -> FlowyResult<Vec<GridBlockRevisionChangeset>> {
|
||||||
let mut changesets = vec![];
|
let mut changesets = vec![];
|
||||||
for block_order in group_row_orders(row_orders) {
|
for block_order in block_from_row_orders(row_orders) {
|
||||||
let editor = self.get_editor(&block_order.block_id).await?;
|
let editor = self.get_editor(&block_order.id).await?;
|
||||||
let row_ids = block_order
|
let row_ids = block_order
|
||||||
.row_orders
|
.row_orders
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|row_order| Cow::Owned(row_order.row_id))
|
.map(|row_order| Cow::Owned(row_order.row_id))
|
||||||
.collect::<Vec<Cow<String>>>();
|
.collect::<Vec<Cow<String>>>();
|
||||||
let row_count = editor.delete_rows(row_ids).await?;
|
let row_count = editor.delete_rows(row_ids).await?;
|
||||||
let changeset = GridBlockRevisionChangeset::from_row_count(&block_order.block_id, row_count);
|
let changeset = GridBlockRevisionChangeset::from_row_count(&block_order.id, row_count);
|
||||||
changesets.push(changeset);
|
changesets.push(changeset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,7 +183,9 @@ impl GridBlockManager {
|
|||||||
updated_rows: vec![],
|
updated_rows: vec![],
|
||||||
};
|
};
|
||||||
|
|
||||||
let _ = self.notify_did_update_block(notified_changeset).await?;
|
let _ = self
|
||||||
|
.notify_did_update_block(&editor.block_id, notified_changeset)
|
||||||
|
.await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,8 +245,8 @@ impl GridBlockManager {
|
|||||||
Ok(block_cell_revs)
|
Ok(block_cell_revs)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn notify_did_update_block(&self, changeset: GridRowsChangeset) -> FlowyResult<()> {
|
async fn notify_did_update_block(&self, block_id: &str, changeset: GridRowsChangeset) -> FlowyResult<()> {
|
||||||
send_dart_notification(&self.grid_id, GridNotification::DidUpdateGridRow)
|
send_dart_notification(block_id, GridNotification::DidUpdateGridRow)
|
||||||
.payload(changeset)
|
.payload(changeset)
|
||||||
.send();
|
.send();
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -424,8 +424,8 @@ impl GridRevisionEditor {
|
|||||||
let mut block_orders = vec![];
|
let mut block_orders = vec![];
|
||||||
for block_order in pad_read_guard.get_block_revs() {
|
for block_order in pad_read_guard.get_block_revs() {
|
||||||
let row_orders = self.block_manager.get_row_orders(&block_order.block_id).await?;
|
let row_orders = self.block_manager.get_row_orders(&block_order.block_id).await?;
|
||||||
let block_order = GridBlockOrder {
|
let block_order = GridBlock {
|
||||||
block_id: block_order.block_id,
|
id: block_order.block_id,
|
||||||
row_orders,
|
row_orders,
|
||||||
};
|
};
|
||||||
block_orders.push(block_order);
|
block_orders.push(block_order);
|
||||||
@ -434,7 +434,7 @@ impl GridRevisionEditor {
|
|||||||
Ok(Grid {
|
Ok(Grid {
|
||||||
id: self.grid_id.clone(),
|
id: self.grid_id.clone(),
|
||||||
field_orders,
|
field_orders,
|
||||||
block_orders,
|
blocks: block_orders,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::services::row::decode_cell_data_from_type_option_cell_data;
|
use crate::services::row::decode_cell_data_from_type_option_cell_data;
|
||||||
use flowy_error::FlowyResult;
|
use flowy_error::FlowyResult;
|
||||||
use flowy_grid_data_model::entities::{Cell, GridBlock, GridBlockOrder, RepeatedGridBlock, Row, RowOrder};
|
use flowy_grid_data_model::entities::{Cell, GridBlock, RepeatedGridBlock, Row, RowOrder};
|
||||||
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, RowRevision};
|
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, RowRevision};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@ -10,13 +10,13 @@ pub struct GridBlockSnapshot {
|
|||||||
pub row_revs: Vec<Arc<RowRevision>>,
|
pub row_revs: Vec<Arc<RowRevision>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn group_row_orders(row_orders: Vec<RowOrder>) -> Vec<GridBlockOrder> {
|
pub(crate) fn block_from_row_orders(row_orders: Vec<RowOrder>) -> Vec<GridBlock> {
|
||||||
let mut map: HashMap<String, GridBlockOrder> = HashMap::new();
|
let mut map: HashMap<String, GridBlock> = HashMap::new();
|
||||||
row_orders.into_iter().for_each(|row_order| {
|
row_orders.into_iter().for_each(|row_order| {
|
||||||
// Memory Optimization: escape clone block_id
|
// Memory Optimization: escape clone block_id
|
||||||
let block_id = row_order.block_id.clone();
|
let block_id = row_order.block_id.clone();
|
||||||
map.entry(block_id)
|
map.entry(block_id)
|
||||||
.or_insert_with(|| GridBlockOrder::new(&row_order.block_id))
|
.or_insert_with(|| GridBlock::new(&row_order.block_id, vec![]))
|
||||||
.row_orders
|
.row_orders
|
||||||
.push(row_order);
|
.push(row_order);
|
||||||
});
|
});
|
||||||
|
@ -6,7 +6,7 @@ use flowy_grid_data_model::entities::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn grid_setting_create_text_filter_test() {
|
async fn grid_filter_create_test() {
|
||||||
let test = GridEditorTest::new().await;
|
let test = GridEditorTest::new().await;
|
||||||
let field_rev = test.text_field();
|
let field_rev = test.text_field();
|
||||||
let payload = CreateGridFilterPayload::new(field_rev, TextFilterCondition::TextIsEmpty, Some("abc".to_owned()));
|
let payload = CreateGridFilterPayload::new(field_rev, TextFilterCondition::TextIsEmpty, Some("abc".to_owned()));
|
||||||
@ -16,7 +16,7 @@ async fn grid_setting_create_text_filter_test() {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
async fn grid_setting_create_text_filter_panic_test() {
|
async fn grid_filter_invalid_condition_panic_test() {
|
||||||
let test = GridEditorTest::new().await;
|
let test = GridEditorTest::new().await;
|
||||||
let field_rev = test.text_field();
|
let field_rev = test.text_field();
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ async fn grid_setting_create_text_filter_panic_test() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn grid_setting_delete_text_filter_test() {
|
async fn grid_filter_delete_test() {
|
||||||
let mut test = GridEditorTest::new().await;
|
let mut test = GridEditorTest::new().await;
|
||||||
let field_rev = test.text_field();
|
let field_rev = test.text_field();
|
||||||
let payload = CreateGridFilterPayload::new(field_rev, 100, Some("abc".to_owned()));
|
let payload = CreateGridFilterPayload::new(field_rev, 100, Some("abc".to_owned()));
|
||||||
@ -43,4 +43,4 @@ async fn grid_setting_delete_text_filter_test() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn grid_setting_sort_test() {}
|
async fn grid_filter_get_rows_test() {}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use crate::grid::script::GridEditorTest;
|
use crate::grid::script::GridEditorTest;
|
||||||
|
use flowy_grid::services::field::DateCellContentChangeset;
|
||||||
use flowy_grid::services::row::{CreateRowRevisionBuilder, CreateRowRevisionPayload};
|
use flowy_grid::services::row::{CreateRowRevisionBuilder, CreateRowRevisionPayload};
|
||||||
use flowy_grid_data_model::entities::FieldType;
|
use flowy_grid_data_model::entities::FieldType;
|
||||||
use flowy_grid_data_model::revision::FieldRevision;
|
use flowy_grid_data_model::revision::FieldRevision;
|
||||||
@ -17,13 +18,47 @@ impl<'a> GridRowTestBuilder<'a> {
|
|||||||
Self { test, inner_builder }
|
Self { test, inner_builder }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_text_cell(&mut self) -> Self {
|
pub fn update_text_cell(mut self, data: String) -> Self {
|
||||||
let text_field = self
|
let text_field = self.field_rev_with_type(&FieldType::DateTime);
|
||||||
.test
|
self.inner_builder.add_cell(&text_field.id, data).unwrap();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_number_cell(mut self, data: String) -> Self {
|
||||||
|
let number_field = self.field_rev_with_type(&FieldType::DateTime);
|
||||||
|
self.inner_builder.add_cell(&number_field.id, data).unwrap();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_date_cell(mut self, value: i64) -> Self {
|
||||||
|
let value = serde_json::to_string(&DateCellContentChangeset {
|
||||||
|
date: Some(value.to_string()),
|
||||||
|
time: None,
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
let date_field = self.field_rev_with_type(&FieldType::DateTime);
|
||||||
|
self.inner_builder.add_cell(&date_field.id, value).unwrap();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_checkbox_cell(mut self, data: bool) -> Self {
|
||||||
|
let number_field = self.field_rev_with_type(&FieldType::Checkbox);
|
||||||
|
self.inner_builder.add_cell(&number_field.id, data.to_string()).unwrap();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_url_cell(mut self, data: String) -> Self {
|
||||||
|
let number_field = self.field_rev_with_type(&FieldType::Checkbox);
|
||||||
|
self.inner_builder.add_cell(&number_field.id, data).unwrap();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn field_rev_with_type(&self, field_type: &FieldType) -> &FieldRevision {
|
||||||
|
self.test
|
||||||
.field_revs
|
.field_revs
|
||||||
.iter()
|
.iter()
|
||||||
.find(|field_rev| field_rev.field_type == FieldType::RichText);
|
.find(|field_rev| field_rev.field_type == &field_type)
|
||||||
// self.inner_builder
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(self) -> CreateRowRevisionPayload {
|
pub fn build(self) -> CreateRowRevisionPayload {
|
||||||
|
@ -15,7 +15,7 @@ pub struct Grid {
|
|||||||
pub field_orders: Vec<FieldOrder>,
|
pub field_orders: Vec<FieldOrder>,
|
||||||
|
|
||||||
#[pb(index = 3)]
|
#[pb(index = 3)]
|
||||||
pub block_orders: Vec<GridBlockOrder>,
|
pub blocks: Vec<GridBlock>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, ProtoBuf)]
|
#[derive(Debug, Default, Clone, ProtoBuf)]
|
||||||
@ -42,6 +42,12 @@ pub struct Row {
|
|||||||
pub height: i32,
|
pub height: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, ProtoBuf)]
|
||||||
|
pub struct OptionalRow {
|
||||||
|
#[pb(index = 1, one_of)]
|
||||||
|
pub row: Option<Row>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, ProtoBuf)]
|
#[derive(Debug, Default, ProtoBuf)]
|
||||||
pub struct RepeatedRow {
|
pub struct RepeatedRow {
|
||||||
#[pb(index = 1)]
|
#[pb(index = 1)]
|
||||||
@ -66,24 +72,6 @@ impl std::convert::From<Vec<GridBlock>> for RepeatedGridBlock {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, ProtoBuf)]
|
|
||||||
pub struct GridBlockOrder {
|
|
||||||
#[pb(index = 1)]
|
|
||||||
pub block_id: String,
|
|
||||||
|
|
||||||
#[pb(index = 2)]
|
|
||||||
pub row_orders: Vec<RowOrder>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GridBlockOrder {
|
|
||||||
pub fn new(block_id: &str) -> Self {
|
|
||||||
GridBlockOrder {
|
|
||||||
block_id: block_id.to_owned(),
|
|
||||||
row_orders: vec![],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, ProtoBuf)]
|
#[derive(Debug, Clone, Default, ProtoBuf)]
|
||||||
pub struct IndexRowOrder {
|
pub struct IndexRowOrder {
|
||||||
#[pb(index = 1)]
|
#[pb(index = 1)]
|
||||||
@ -168,7 +156,7 @@ impl GridRowsChangeset {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, ProtoBuf)]
|
#[derive(Debug, Clone, Default, ProtoBuf)]
|
||||||
pub struct GridBlock {
|
pub struct GridBlock {
|
||||||
#[pb(index = 1)]
|
#[pb(index = 1)]
|
||||||
pub id: String,
|
pub id: String,
|
||||||
@ -305,12 +293,12 @@ pub struct QueryGridBlocksPayload {
|
|||||||
pub grid_id: String,
|
pub grid_id: String,
|
||||||
|
|
||||||
#[pb(index = 2)]
|
#[pb(index = 2)]
|
||||||
pub block_orders: Vec<GridBlockOrder>,
|
pub block_ids: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct QueryGridBlocksParams {
|
pub struct QueryGridBlocksParams {
|
||||||
pub grid_id: String,
|
pub grid_id: String,
|
||||||
pub block_orders: Vec<GridBlockOrder>,
|
pub block_ids: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryInto<QueryGridBlocksParams> for QueryGridBlocksPayload {
|
impl TryInto<QueryGridBlocksParams> for QueryGridBlocksPayload {
|
||||||
@ -320,7 +308,7 @@ impl TryInto<QueryGridBlocksParams> for QueryGridBlocksPayload {
|
|||||||
let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
|
let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
|
||||||
Ok(QueryGridBlocksParams {
|
Ok(QueryGridBlocksParams {
|
||||||
grid_id: grid_id.0,
|
grid_id: grid_id.0,
|
||||||
block_orders: self.block_orders,
|
block_ids: self.block_ids,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ pub struct GridRevision {
|
|||||||
pub fields: Vec<FieldRevision>,
|
pub fields: Vec<FieldRevision>,
|
||||||
pub blocks: Vec<GridBlockRevision>,
|
pub blocks: Vec<GridBlockRevision>,
|
||||||
|
|
||||||
#[serde(default)]
|
#[serde(default, skip)]
|
||||||
pub setting: GridSettingRevision,
|
pub setting: GridSettingRevision,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user