mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: reload after delete or insert row
This commit is contained in:
parent
420b8ca05d
commit
f01d3250ae
@ -34,8 +34,6 @@ class GridBloc extends Bloc<GridEvent, GridState> {
|
||||
createRow: (_CreateRow value) {
|
||||
_gridService.createRow(gridId: view.id);
|
||||
},
|
||||
delete: (_Delete value) {},
|
||||
rename: (_Rename value) {},
|
||||
updateDesc: (_Desc value) {},
|
||||
didReceiveRowUpdate: (_DidReceiveRowUpdate value) {
|
||||
emit(state.copyWith(rows: value.rows));
|
||||
@ -71,14 +69,18 @@ class GridBloc extends Bloc<GridEvent, GridState> {
|
||||
_gridListener.rowsUpdateNotifier.addPublishListener((result) {
|
||||
result.fold((gridBlockChangeset) {
|
||||
for (final changeset in gridBlockChangeset) {
|
||||
if (changeset.insertedRows.isNotEmpty) {}
|
||||
|
||||
if (changeset.deletedRows.isNotEmpty) {}
|
||||
|
||||
if (changeset.updatedRows.isNotEmpty) {}
|
||||
if (changeset.insertedRows.isNotEmpty) {
|
||||
_insertRows(changeset.insertedRows);
|
||||
}
|
||||
|
||||
// add(GridEvent.didReceiveRowUpdate(_buildRows(blockOrders)));
|
||||
if (changeset.deletedRows.isNotEmpty) {
|
||||
_deleteRows(changeset.deletedRows);
|
||||
}
|
||||
|
||||
if (changeset.updatedRows.isNotEmpty) {
|
||||
_updateRows(changeset.updatedRows);
|
||||
}
|
||||
}
|
||||
}, (err) => Log.error(err));
|
||||
});
|
||||
_gridListener.start();
|
||||
@ -111,29 +113,50 @@ class GridBloc extends Bloc<GridEvent, GridState> {
|
||||
);
|
||||
}
|
||||
|
||||
List<GridBlockRow> _buildRows(List<GridBlockOrder> blockOrders) {
|
||||
List<GridBlockRow> rows = [];
|
||||
for (final blockOrder in blockOrders) {
|
||||
rows.addAll(blockOrder.rowOrders.map(
|
||||
(rowOrder) => GridBlockRow(
|
||||
gridId: view.id,
|
||||
rowId: rowOrder.rowId,
|
||||
height: rowOrder.height.toDouble(),
|
||||
),
|
||||
));
|
||||
void _deleteRows(List<RowOrder> deletedRows) {
|
||||
final List<RowOrder> rows = List.from(state.rows);
|
||||
rows.retainWhere(
|
||||
(row) => deletedRows.where((deletedRow) => deletedRow.rowId == row.rowId).isEmpty,
|
||||
);
|
||||
|
||||
add(GridEvent.didReceiveRowUpdate(rows));
|
||||
}
|
||||
return rows;
|
||||
|
||||
void _insertRows(List<IndexRowOrder> createdRows) {
|
||||
final List<RowOrder> rows = List.from(state.rows);
|
||||
for (final newRow in createdRows) {
|
||||
if (newRow.hasIndex()) {
|
||||
rows.insert(newRow.index, newRow.rowOrder);
|
||||
} else {
|
||||
rows.add(newRow.rowOrder);
|
||||
}
|
||||
}
|
||||
add(GridEvent.didReceiveRowUpdate(rows));
|
||||
}
|
||||
|
||||
void _updateRows(List<RowOrder> updatedRows) {
|
||||
final List<RowOrder> rows = List.from(state.rows);
|
||||
for (final updatedRow in updatedRows) {
|
||||
final index = rows.indexWhere((row) => row.rowId == updatedRow.rowId);
|
||||
if (index != -1) {
|
||||
rows.removeAt(index);
|
||||
rows.insert(index, updatedRow);
|
||||
}
|
||||
}
|
||||
add(GridEvent.didReceiveRowUpdate(rows));
|
||||
}
|
||||
|
||||
List<RowOrder> _buildRows(List<GridBlockOrder> blockOrders) {
|
||||
return blockOrders.expand((blockOrder) => blockOrder.rowOrders).toList();
|
||||
}
|
||||
}
|
||||
|
||||
@freezed
|
||||
class GridEvent with _$GridEvent {
|
||||
const factory GridEvent.initial() = InitialGrid;
|
||||
const factory GridEvent.rename(String gridId, String name) = _Rename;
|
||||
const factory GridEvent.updateDesc(String gridId, String desc) = _Desc;
|
||||
const factory GridEvent.delete(String gridId) = _Delete;
|
||||
const factory GridEvent.createRow() = _CreateRow;
|
||||
const factory GridEvent.didReceiveRowUpdate(List<GridBlockRow> rows) = _DidReceiveRowUpdate;
|
||||
const factory GridEvent.didReceiveRowUpdate(List<RowOrder> rows) = _DidReceiveRowUpdate;
|
||||
const factory GridEvent.didReceiveFieldUpdate(List<Field> fields) = _DidReceiveFieldUpdate;
|
||||
}
|
||||
|
||||
@ -142,7 +165,7 @@ class GridState with _$GridState {
|
||||
const factory GridState({
|
||||
required GridLoadingState loadingState,
|
||||
required List<Field> fields,
|
||||
required List<GridBlockRow> rows,
|
||||
required List<RowOrder> rows,
|
||||
required Option<Grid> grid,
|
||||
}) = _GridState;
|
||||
|
||||
|
@ -65,21 +65,12 @@ class RowData with _$RowData {
|
||||
required double height,
|
||||
}) = _RowData;
|
||||
|
||||
factory RowData.fromBlockRow(GridBlockRow row, List<Field> fields) {
|
||||
factory RowData.fromBlockRow(String gridId, RowOrder row, List<Field> fields) {
|
||||
return RowData(
|
||||
gridId: row.gridId,
|
||||
gridId: gridId,
|
||||
rowId: row.rowId,
|
||||
fields: fields,
|
||||
height: row.height,
|
||||
height: row.height.toDouble(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@freezed
|
||||
class GridBlockRow with _$GridBlockRow {
|
||||
const factory GridBlockRow({
|
||||
required String gridId,
|
||||
required String rowId,
|
||||
required double height,
|
||||
}) = _GridBlockRow;
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ class FlowyGrid extends StatefulWidget {
|
||||
|
||||
class _FlowyGridState extends State<FlowyGrid> {
|
||||
final _scrollController = GridScrollController();
|
||||
final _key = GlobalKey<SliverAnimatedListState>();
|
||||
// final _key = GlobalKey<SliverAnimatedListState>();
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
@ -105,7 +105,7 @@ class _FlowyGridState extends State<FlowyGrid> {
|
||||
slivers: [
|
||||
_renderToolbar(gridId),
|
||||
GridHeader(gridId: gridId, fields: List.from(state.fields)),
|
||||
_renderRows(context),
|
||||
_renderRows(gridId: gridId, context: context),
|
||||
const GridFooter(),
|
||||
],
|
||||
),
|
||||
@ -147,7 +147,7 @@ class _FlowyGridState extends State<FlowyGrid> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _renderRows(BuildContext context) {
|
||||
Widget _renderRows({required String gridId, required BuildContext context}) {
|
||||
return BlocBuilder<GridBloc, GridState>(
|
||||
buildWhen: (previous, current) {
|
||||
final rowChanged = previous.rows.length != current.rows.length;
|
||||
@ -160,7 +160,7 @@ class _FlowyGridState extends State<FlowyGrid> {
|
||||
(context, index) {
|
||||
final blockRow = context.read<GridBloc>().state.rows[index];
|
||||
final fields = context.read<GridBloc>().state.fields;
|
||||
final rowData = RowData.fromBlockRow(blockRow, fields);
|
||||
final rowData = RowData.fromBlockRow(gridId, blockRow, fields);
|
||||
return GridRowWidget(data: rowData, key: ValueKey(rowData.rowId));
|
||||
},
|
||||
childCount: context.read<GridBloc>().state.rows.length,
|
||||
|
@ -84,10 +84,16 @@ class _RowActionCell extends StatelessWidget {
|
||||
return SizedBox(
|
||||
height: GridSize.typeOptionItemHeight,
|
||||
child: FlowyButton(
|
||||
text: FlowyText.medium(action.title(), fontSize: 12),
|
||||
text: FlowyText.medium(
|
||||
action.title(),
|
||||
fontSize: 12,
|
||||
color: action.enable() ? theme.textColor : theme.shader3,
|
||||
),
|
||||
hoverColor: theme.hover,
|
||||
onTap: () {
|
||||
if (action.enable()) {
|
||||
action.performAction(context);
|
||||
}
|
||||
onDismissed();
|
||||
},
|
||||
leftIcon: svgWidget(action.iconName(), color: theme.iconColor),
|
||||
@ -120,13 +126,22 @@ extension _RowActionExtension on _RowAction {
|
||||
}
|
||||
}
|
||||
|
||||
bool enable() {
|
||||
switch (this) {
|
||||
case _RowAction.duplicate:
|
||||
return false;
|
||||
case _RowAction.delete:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void performAction(BuildContext context) {
|
||||
switch (this) {
|
||||
case _RowAction.duplicate:
|
||||
// context.read<RowActionSheetBloc>().add(const RowActionSheetEvent.duplicateRow());
|
||||
context.read<RowActionSheetBloc>().add(const RowActionSheetEvent.duplicateRow());
|
||||
break;
|
||||
case _RowAction.delete:
|
||||
// context.read<RowActionSheetBloc>().add(const RowActionSheetEvent.deleteRow());
|
||||
context.read<RowActionSheetBloc>().add(const RowActionSheetEvent.deleteRow());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -858,7 +858,7 @@ class GridBlockOrder extends $pb.GeneratedMessage {
|
||||
class GridBlockOrderChangeset extends $pb.GeneratedMessage {
|
||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GridBlockOrderChangeset', createEmptyInstance: create)
|
||||
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId')
|
||||
..pc<RowOrder>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'insertedRows', $pb.PbFieldType.PM, subBuilder: RowOrder.create)
|
||||
..pc<IndexRowOrder>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'insertedRows', $pb.PbFieldType.PM, subBuilder: IndexRowOrder.create)
|
||||
..pc<RowOrder>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'deletedRows', $pb.PbFieldType.PM, subBuilder: RowOrder.create)
|
||||
..pc<RowOrder>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'updatedRows', $pb.PbFieldType.PM, subBuilder: RowOrder.create)
|
||||
..hasRequiredFields = false
|
||||
@ -867,7 +867,7 @@ class GridBlockOrderChangeset extends $pb.GeneratedMessage {
|
||||
GridBlockOrderChangeset._() : super();
|
||||
factory GridBlockOrderChangeset({
|
||||
$core.String? blockId,
|
||||
$core.Iterable<RowOrder>? insertedRows,
|
||||
$core.Iterable<IndexRowOrder>? insertedRows,
|
||||
$core.Iterable<RowOrder>? deletedRows,
|
||||
$core.Iterable<RowOrder>? updatedRows,
|
||||
}) {
|
||||
@ -917,7 +917,7 @@ class GridBlockOrderChangeset extends $pb.GeneratedMessage {
|
||||
void clearBlockId() => clearField(1);
|
||||
|
||||
@$pb.TagNumber(2)
|
||||
$core.List<RowOrder> get insertedRows => $_getList(1);
|
||||
$core.List<IndexRowOrder> get insertedRows => $_getList(1);
|
||||
|
||||
@$pb.TagNumber(3)
|
||||
$core.List<RowOrder> get deletedRows => $_getList(2);
|
||||
@ -926,6 +926,82 @@ class GridBlockOrderChangeset extends $pb.GeneratedMessage {
|
||||
$core.List<RowOrder> get updatedRows => $_getList(3);
|
||||
}
|
||||
|
||||
enum IndexRowOrder_OneOfIndex {
|
||||
index_,
|
||||
notSet
|
||||
}
|
||||
|
||||
class IndexRowOrder extends $pb.GeneratedMessage {
|
||||
static const $core.Map<$core.int, IndexRowOrder_OneOfIndex> _IndexRowOrder_OneOfIndexByTag = {
|
||||
2 : IndexRowOrder_OneOfIndex.index_,
|
||||
0 : IndexRowOrder_OneOfIndex.notSet
|
||||
};
|
||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'IndexRowOrder', createEmptyInstance: create)
|
||||
..oo(0, [2])
|
||||
..aOM<RowOrder>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'rowOrder', subBuilder: RowOrder.create)
|
||||
..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'index', $pb.PbFieldType.O3)
|
||||
..hasRequiredFields = false
|
||||
;
|
||||
|
||||
IndexRowOrder._() : super();
|
||||
factory IndexRowOrder({
|
||||
RowOrder? rowOrder,
|
||||
$core.int? index,
|
||||
}) {
|
||||
final _result = create();
|
||||
if (rowOrder != null) {
|
||||
_result.rowOrder = rowOrder;
|
||||
}
|
||||
if (index != null) {
|
||||
_result.index = index;
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
factory IndexRowOrder.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
|
||||
factory IndexRowOrder.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')
|
||||
IndexRowOrder clone() => IndexRowOrder()..mergeFromMessage(this);
|
||||
@$core.Deprecated(
|
||||
'Using this can add significant overhead to your binary. '
|
||||
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
|
||||
'Will be removed in next major version')
|
||||
IndexRowOrder copyWith(void Function(IndexRowOrder) updates) => super.copyWith((message) => updates(message as IndexRowOrder)) as IndexRowOrder; // ignore: deprecated_member_use
|
||||
$pb.BuilderInfo get info_ => _i;
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static IndexRowOrder create() => IndexRowOrder._();
|
||||
IndexRowOrder createEmptyInstance() => create();
|
||||
static $pb.PbList<IndexRowOrder> createRepeated() => $pb.PbList<IndexRowOrder>();
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static IndexRowOrder getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<IndexRowOrder>(create);
|
||||
static IndexRowOrder? _defaultInstance;
|
||||
|
||||
IndexRowOrder_OneOfIndex whichOneOfIndex() => _IndexRowOrder_OneOfIndexByTag[$_whichOneof(0)]!;
|
||||
void clearOneOfIndex() => clearField($_whichOneof(0));
|
||||
|
||||
@$pb.TagNumber(1)
|
||||
RowOrder get rowOrder => $_getN(0);
|
||||
@$pb.TagNumber(1)
|
||||
set rowOrder(RowOrder v) { setField(1, v); }
|
||||
@$pb.TagNumber(1)
|
||||
$core.bool hasRowOrder() => $_has(0);
|
||||
@$pb.TagNumber(1)
|
||||
void clearRowOrder() => clearField(1);
|
||||
@$pb.TagNumber(1)
|
||||
RowOrder ensureRowOrder() => $_ensure(0);
|
||||
|
||||
@$pb.TagNumber(2)
|
||||
$core.int get index => $_getIZ(1);
|
||||
@$pb.TagNumber(2)
|
||||
set index($core.int v) { $_setSignedInt32(1, v); }
|
||||
@$pb.TagNumber(2)
|
||||
$core.bool hasIndex() => $_has(1);
|
||||
@$pb.TagNumber(2)
|
||||
void clearIndex() => clearField(2);
|
||||
}
|
||||
|
||||
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') ? '' : 'id')
|
||||
|
@ -176,14 +176,28 @@ const GridBlockOrderChangeset$json = const {
|
||||
'1': 'GridBlockOrderChangeset',
|
||||
'2': const [
|
||||
const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'},
|
||||
const {'1': 'inserted_rows', '3': 2, '4': 3, '5': 11, '6': '.RowOrder', '10': 'insertedRows'},
|
||||
const {'1': 'inserted_rows', '3': 2, '4': 3, '5': 11, '6': '.IndexRowOrder', '10': 'insertedRows'},
|
||||
const {'1': 'deleted_rows', '3': 3, '4': 3, '5': 11, '6': '.RowOrder', '10': 'deletedRows'},
|
||||
const {'1': 'updated_rows', '3': 4, '4': 3, '5': 11, '6': '.RowOrder', '10': 'updatedRows'},
|
||||
],
|
||||
};
|
||||
|
||||
/// Descriptor for `GridBlockOrderChangeset`. Decode as a `google.protobuf.DescriptorProto`.
|
||||
final $typed_data.Uint8List gridBlockOrderChangesetDescriptor = $convert.base64Decode('ChdHcmlkQmxvY2tPcmRlckNoYW5nZXNldBIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZBIuCg1pbnNlcnRlZF9yb3dzGAIgAygLMgkuUm93T3JkZXJSDGluc2VydGVkUm93cxIsCgxkZWxldGVkX3Jvd3MYAyADKAsyCS5Sb3dPcmRlclILZGVsZXRlZFJvd3MSLAoMdXBkYXRlZF9yb3dzGAQgAygLMgkuUm93T3JkZXJSC3VwZGF0ZWRSb3dz');
|
||||
final $typed_data.Uint8List gridBlockOrderChangesetDescriptor = $convert.base64Decode('ChdHcmlkQmxvY2tPcmRlckNoYW5nZXNldBIZCghibG9ja19pZBgBIAEoCVIHYmxvY2tJZBIzCg1pbnNlcnRlZF9yb3dzGAIgAygLMg4uSW5kZXhSb3dPcmRlclIMaW5zZXJ0ZWRSb3dzEiwKDGRlbGV0ZWRfcm93cxgDIAMoCzIJLlJvd09yZGVyUgtkZWxldGVkUm93cxIsCgx1cGRhdGVkX3Jvd3MYBCADKAsyCS5Sb3dPcmRlclILdXBkYXRlZFJvd3M=');
|
||||
@$core.Deprecated('Use indexRowOrderDescriptor instead')
|
||||
const IndexRowOrder$json = const {
|
||||
'1': 'IndexRowOrder',
|
||||
'2': const [
|
||||
const {'1': 'row_order', '3': 1, '4': 1, '5': 11, '6': '.RowOrder', '10': 'rowOrder'},
|
||||
const {'1': 'index', '3': 2, '4': 1, '5': 5, '9': 0, '10': 'index'},
|
||||
],
|
||||
'8': const [
|
||||
const {'1': 'one_of_index'},
|
||||
],
|
||||
};
|
||||
|
||||
/// Descriptor for `IndexRowOrder`. Decode as a `google.protobuf.DescriptorProto`.
|
||||
final $typed_data.Uint8List indexRowOrderDescriptor = $convert.base64Decode('Cg1JbmRleFJvd09yZGVyEiYKCXJvd19vcmRlchgBIAEoCzIJLlJvd09yZGVyUghyb3dPcmRlchIWCgVpbmRleBgCIAEoBUgAUgVpbmRleEIOCgxvbmVfb2ZfaW5kZXg=');
|
||||
@$core.Deprecated('Use gridBlockDescriptor instead')
|
||||
const GridBlock$json = const {
|
||||
'1': 'GridBlock',
|
||||
|
@ -42,17 +42,30 @@ impl ClientGridBlockMetaEditor {
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) async fn create_row(&self, row: RowMeta, start_row_id: Option<String>) -> FlowyResult<i32> {
|
||||
/// return current number of rows and the inserted index. The inserted index will be None if the start_row_id is None
|
||||
pub(crate) async fn create_row(
|
||||
&self,
|
||||
row: RowMeta,
|
||||
start_row_id: Option<String>,
|
||||
) -> FlowyResult<(i32, Option<i32>)> {
|
||||
let mut row_count = 0;
|
||||
let mut row_index = None;
|
||||
let _ = self
|
||||
.modify(|pad| {
|
||||
if let Some(start_row_id) = start_row_id.as_ref() {
|
||||
match pad.index_of_row(start_row_id) {
|
||||
None => {}
|
||||
Some(index) => row_index = Some(index + 1),
|
||||
}
|
||||
}
|
||||
|
||||
let change = pad.add_row_meta(row, start_row_id)?;
|
||||
row_count = pad.number_of_rows();
|
||||
Ok(change)
|
||||
})
|
||||
.await?;
|
||||
|
||||
Ok(row_count)
|
||||
Ok((row_count, row_index))
|
||||
}
|
||||
|
||||
pub async fn delete_rows(&self, ids: Vec<Cow<'_, String>>) -> FlowyResult<i32> {
|
||||
@ -89,7 +102,10 @@ impl ClientGridBlockMetaEditor {
|
||||
Ok(cell_metas)
|
||||
}
|
||||
|
||||
pub async fn get_row_orders(&self, row_ids: Option<Vec<Cow<'_, String>>>) -> FlowyResult<Vec<RowOrder>> {
|
||||
pub async fn get_row_orders<T>(&self, row_ids: Option<Vec<Cow<'_, T>>>) -> FlowyResult<Vec<RowOrder>>
|
||||
where
|
||||
T: AsRef<str> + ToOwned + ?Sized,
|
||||
{
|
||||
let row_orders = self
|
||||
.pad
|
||||
.read()
|
||||
|
@ -9,7 +9,7 @@ use dashmap::DashMap;
|
||||
use flowy_error::FlowyResult;
|
||||
use flowy_grid_data_model::entities::{
|
||||
CellMeta, CellMetaChangeset, CellNotificationData, FieldMeta, GridBlockMeta, GridBlockMetaChangeset,
|
||||
GridBlockOrder, GridBlockOrderChangeset, RowMeta, RowMetaChangeset, RowOrder,
|
||||
GridBlockOrderChangeset, IndexRowOrder, RowMeta, RowMetaChangeset, RowOrder,
|
||||
};
|
||||
use flowy_revision::disk::SQLiteGridBlockMetaRevisionPersistence;
|
||||
use flowy_revision::{RevisionManager, RevisionPersistence};
|
||||
@ -70,11 +70,13 @@ impl GridBlockMetaEditorManager {
|
||||
) -> FlowyResult<i32> {
|
||||
let _ = self.persistence.insert_or_update(&row_meta.block_id, &row_meta.id)?;
|
||||
let editor = self.get_editor(&row_meta.block_id).await?;
|
||||
let row_order = RowOrder::from(&row_meta);
|
||||
let row_count = editor.create_row(row_meta, start_row_id).await?;
|
||||
|
||||
let mut index_row_order = IndexRowOrder::from(&row_meta);
|
||||
let (row_count, row_index) = editor.create_row(row_meta, start_row_id).await?;
|
||||
index_row_order.index = row_index;
|
||||
|
||||
let _ = self
|
||||
.notify_block_did_update_row(GridBlockOrderChangeset::from_update(block_id, vec![row_order]))
|
||||
.notify_did_update_grid_rows(GridBlockOrderChangeset::from_insert(block_id, vec![index_row_order]))
|
||||
.await?;
|
||||
Ok(row_count)
|
||||
}
|
||||
@ -90,12 +92,13 @@ impl GridBlockMetaEditorManager {
|
||||
let mut row_count = 0;
|
||||
for row in row_metas {
|
||||
let _ = self.persistence.insert_or_update(&row.block_id, &row.id)?;
|
||||
inserted_row_orders.push(RowOrder::from(&row));
|
||||
row_count = editor.create_row(row, None).await?;
|
||||
inserted_row_orders.push(IndexRowOrder::from(&row));
|
||||
row_count = editor.create_row(row, None).await?.0;
|
||||
}
|
||||
changesets.push(GridBlockMetaChangeset::from_row_count(&block_id, row_count));
|
||||
|
||||
let _ = self
|
||||
.notify_block_did_update_row(GridBlockOrderChangeset::from_insert(&block_id, inserted_row_orders))
|
||||
.notify_did_update_grid_rows(GridBlockOrderChangeset::from_insert(&block_id, inserted_row_orders))
|
||||
.await?;
|
||||
}
|
||||
|
||||
@ -114,13 +117,26 @@ impl GridBlockMetaEditorManager {
|
||||
None => {}
|
||||
Some(row_order) => {
|
||||
let block_order_changeset = GridBlockOrderChangeset::from_update(&editor.block_id, vec![row_order]);
|
||||
let _ = self.notify_block_did_update_row(block_order_changeset).await?;
|
||||
let _ = self.notify_did_update_grid_rows(block_order_changeset).await?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn delete_row(&self, row_id: &str) -> FlowyResult<()> {
|
||||
let row_id = row_id.to_owned();
|
||||
let block_id = self.persistence.get_block_id(&row_id)?;
|
||||
let editor = self.get_editor(&block_id).await?;
|
||||
let row_orders = editor.get_row_orders(Some(vec![Cow::Borrowed(&row_id)])).await?;
|
||||
let _ = editor.delete_rows(vec![Cow::Borrowed(&row_id)]).await?;
|
||||
let _ = self
|
||||
.notify_did_update_grid_rows(GridBlockOrderChangeset::from_delete(&block_id, row_orders))
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn delete_rows(&self, row_orders: Vec<RowOrder>) -> FlowyResult<Vec<GridBlockMetaChangeset>> {
|
||||
let mut changesets = vec![];
|
||||
for block_order in group_row_orders(row_orders) {
|
||||
@ -167,7 +183,7 @@ impl GridBlockMetaEditorManager {
|
||||
|
||||
pub async fn get_row_orders(&self, block_id: &str) -> FlowyResult<Vec<RowOrder>> {
|
||||
let editor = self.get_editor(block_id).await?;
|
||||
editor.get_row_orders(None).await
|
||||
editor.get_row_orders::<&str>(None).await
|
||||
}
|
||||
|
||||
pub(crate) async fn make_block_snapshots(&self, block_ids: Vec<String>) -> FlowyResult<Vec<GridBlockSnapshot>> {
|
||||
@ -197,7 +213,7 @@ impl GridBlockMetaEditorManager {
|
||||
Ok(block_cell_metas)
|
||||
}
|
||||
|
||||
async fn notify_block_did_update_row(&self, changeset: GridBlockOrderChangeset) -> FlowyResult<()> {
|
||||
async fn notify_did_update_grid_rows(&self, changeset: GridBlockOrderChangeset) -> FlowyResult<()> {
|
||||
send_dart_notification(&self.grid_id, GridNotification::DidUpdateGridBlock)
|
||||
.payload(changeset)
|
||||
.send();
|
||||
|
@ -70,7 +70,7 @@ impl CellDataOperation for DateTypeOption {
|
||||
) -> Result<String, FlowyError> {
|
||||
let changeset = changeset.into();
|
||||
if changeset.parse::<f64>().is_err() || changeset.parse::<i64>().is_err() {
|
||||
return Err(FlowyError::internal().context(format!("Parse {} failed", changeset.to_string())));
|
||||
return Err(FlowyError::internal().context(format!("Parse {} failed", changeset)));
|
||||
};
|
||||
|
||||
Ok(TypeOptionCellData::new(changeset, self.field_type()).json())
|
||||
|
@ -469,7 +469,7 @@ mod tests {
|
||||
let single_select = SingleSelectTypeOptionBuilder::default()
|
||||
.option(google_option.clone())
|
||||
.option(facebook_option.clone())
|
||||
.option(twitter_option.clone());
|
||||
.option(twitter_option);
|
||||
|
||||
let field_meta = FieldBuilder::new(single_select)
|
||||
.name("Platform")
|
||||
@ -478,7 +478,7 @@ mod tests {
|
||||
|
||||
let type_option = SingleSelectTypeOption::from(&field_meta);
|
||||
|
||||
let option_ids = vec![google_option.id.clone(), facebook_option.id.clone()].join(SELECTION_IDS_SEPARATOR);
|
||||
let option_ids = vec![google_option.id.clone(), facebook_option.id].join(SELECTION_IDS_SEPARATOR);
|
||||
let data = SelectOptionCellChangeset::from_insert(&option_ids).cell_data();
|
||||
let cell_data = type_option.apply_changeset(data, None).unwrap();
|
||||
assert_eq!(type_option.decode_cell_data(cell_data, &field_meta), google_option.name,);
|
||||
@ -511,7 +511,7 @@ mod tests {
|
||||
let multi_select = MultiSelectTypeOptionBuilder::default()
|
||||
.option(google_option.clone())
|
||||
.option(facebook_option.clone())
|
||||
.option(twitter_option.clone());
|
||||
.option(twitter_option);
|
||||
|
||||
let field_meta = FieldBuilder::new(multi_select)
|
||||
.name("Platform")
|
||||
@ -525,7 +525,7 @@ mod tests {
|
||||
let cell_data = type_option.apply_changeset(data, None).unwrap();
|
||||
assert_eq!(
|
||||
type_option.decode_cell_data(cell_data, &field_meta),
|
||||
vec![google_option.name.clone(), facebook_option.name.clone()].join(SELECTION_IDS_SEPARATOR),
|
||||
vec![google_option.name.clone(), facebook_option.name].join(SELECTION_IDS_SEPARATOR),
|
||||
);
|
||||
|
||||
let data = SelectOptionCellChangeset::from_insert(&google_option.id).cell_data();
|
||||
|
@ -268,11 +268,12 @@ impl ClientGridEditor {
|
||||
}
|
||||
}
|
||||
pub async fn delete_row(&self, row_id: &str) -> FlowyResult<()> {
|
||||
todo!()
|
||||
let _ = self.block_meta_manager.delete_row(row_id).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn duplicate_row(&self, row_id: &str) -> FlowyResult<()> {
|
||||
todo!()
|
||||
pub async fn duplicate_row(&self, _row_id: &str) -> FlowyResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn get_cell(&self, params: &CellIdentifier) -> Option<Cell> {
|
||||
@ -429,7 +430,7 @@ impl ClientGridEditor {
|
||||
debug_assert!(field_metas.len() == 1);
|
||||
|
||||
if let Some(field_meta) = field_metas.pop() {
|
||||
send_dart_notification(&field_id, GridNotification::DidUpdateField)
|
||||
send_dart_notification(field_id, GridNotification::DidUpdateField)
|
||||
.payload(field_meta)
|
||||
.send();
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ use flowy_grid_data_model::entities::{
|
||||
Cell, CellMeta, FieldMeta, GridBlock, GridBlockOrder, RepeatedGridBlock, Row, RowMeta, RowOrder,
|
||||
};
|
||||
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
||||
use std::borrow::Cow;
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
@ -4,7 +4,7 @@ use chrono::NaiveDateTime;
|
||||
use flowy_grid::services::field::{
|
||||
MultiSelectTypeOption, SelectOption, SelectOptionCellChangeset, SingleSelectTypeOption, SELECTION_IDS_SEPARATOR,
|
||||
};
|
||||
use flowy_grid::services::row::{apply_cell_data_changeset, decode_cell_data, CellDataOperation, CreateRowMetaBuilder};
|
||||
use flowy_grid::services::row::{decode_cell_data, CreateRowMetaBuilder};
|
||||
use flowy_grid_data_model::entities::{
|
||||
CellMetaChangeset, FieldChangesetParams, FieldType, GridBlockMeta, GridBlockMetaChangeset, RowMetaChangeset,
|
||||
TypeOptionDataEntry,
|
||||
|
@ -280,7 +280,7 @@ pub struct GridBlockOrderChangeset {
|
||||
pub block_id: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub inserted_rows: Vec<RowOrder>,
|
||||
pub inserted_rows: Vec<IndexRowOrder>,
|
||||
|
||||
#[pb(index = 3)]
|
||||
pub deleted_rows: Vec<RowOrder>,
|
||||
@ -289,8 +289,30 @@ pub struct GridBlockOrderChangeset {
|
||||
pub updated_rows: Vec<RowOrder>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, ProtoBuf)]
|
||||
pub struct IndexRowOrder {
|
||||
#[pb(index = 1)]
|
||||
pub row_order: RowOrder,
|
||||
|
||||
#[pb(index = 2, one_of)]
|
||||
pub index: Option<i32>,
|
||||
}
|
||||
|
||||
impl std::convert::From<RowOrder> for IndexRowOrder {
|
||||
fn from(row_order: RowOrder) -> Self {
|
||||
Self { row_order, index: None }
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<&RowMeta> for IndexRowOrder {
|
||||
fn from(row: &RowMeta) -> Self {
|
||||
let row_order = RowOrder::from(row);
|
||||
Self::from(row_order)
|
||||
}
|
||||
}
|
||||
|
||||
impl GridBlockOrderChangeset {
|
||||
pub fn from_insert(block_id: &str, inserted_rows: Vec<RowOrder>) -> Self {
|
||||
pub fn from_insert(block_id: &str, inserted_rows: Vec<IndexRowOrder>) -> Self {
|
||||
Self {
|
||||
block_id: block_id.to_owned(),
|
||||
inserted_rows,
|
||||
|
@ -2923,7 +2923,7 @@ impl ::protobuf::reflect::ProtobufValue for GridBlockOrder {
|
||||
pub struct GridBlockOrderChangeset {
|
||||
// message fields
|
||||
pub block_id: ::std::string::String,
|
||||
pub inserted_rows: ::protobuf::RepeatedField<RowOrder>,
|
||||
pub inserted_rows: ::protobuf::RepeatedField<IndexRowOrder>,
|
||||
pub deleted_rows: ::protobuf::RepeatedField<RowOrder>,
|
||||
pub updated_rows: ::protobuf::RepeatedField<RowOrder>,
|
||||
// special fields
|
||||
@ -2968,10 +2968,10 @@ impl GridBlockOrderChangeset {
|
||||
::std::mem::replace(&mut self.block_id, ::std::string::String::new())
|
||||
}
|
||||
|
||||
// repeated .RowOrder inserted_rows = 2;
|
||||
// repeated .IndexRowOrder inserted_rows = 2;
|
||||
|
||||
|
||||
pub fn get_inserted_rows(&self) -> &[RowOrder] {
|
||||
pub fn get_inserted_rows(&self) -> &[IndexRowOrder] {
|
||||
&self.inserted_rows
|
||||
}
|
||||
pub fn clear_inserted_rows(&mut self) {
|
||||
@ -2979,17 +2979,17 @@ impl GridBlockOrderChangeset {
|
||||
}
|
||||
|
||||
// Param is passed by value, moved
|
||||
pub fn set_inserted_rows(&mut self, v: ::protobuf::RepeatedField<RowOrder>) {
|
||||
pub fn set_inserted_rows(&mut self, v: ::protobuf::RepeatedField<IndexRowOrder>) {
|
||||
self.inserted_rows = v;
|
||||
}
|
||||
|
||||
// Mutable pointer to the field.
|
||||
pub fn mut_inserted_rows(&mut self) -> &mut ::protobuf::RepeatedField<RowOrder> {
|
||||
pub fn mut_inserted_rows(&mut self) -> &mut ::protobuf::RepeatedField<IndexRowOrder> {
|
||||
&mut self.inserted_rows
|
||||
}
|
||||
|
||||
// Take field
|
||||
pub fn take_inserted_rows(&mut self) -> ::protobuf::RepeatedField<RowOrder> {
|
||||
pub fn take_inserted_rows(&mut self) -> ::protobuf::RepeatedField<IndexRowOrder> {
|
||||
::std::mem::replace(&mut self.inserted_rows, ::protobuf::RepeatedField::new())
|
||||
}
|
||||
|
||||
@ -3174,7 +3174,7 @@ impl ::protobuf::Message for GridBlockOrderChangeset {
|
||||
|m: &GridBlockOrderChangeset| { &m.block_id },
|
||||
|m: &mut GridBlockOrderChangeset| { &mut m.block_id },
|
||||
));
|
||||
fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<RowOrder>>(
|
||||
fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<IndexRowOrder>>(
|
||||
"inserted_rows",
|
||||
|m: &GridBlockOrderChangeset| { &m.inserted_rows },
|
||||
|m: &mut GridBlockOrderChangeset| { &mut m.inserted_rows },
|
||||
@ -3225,6 +3225,238 @@ impl ::protobuf::reflect::ProtobufValue for GridBlockOrderChangeset {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq,Clone,Default)]
|
||||
pub struct IndexRowOrder {
|
||||
// message fields
|
||||
pub row_order: ::protobuf::SingularPtrField<RowOrder>,
|
||||
// message oneof groups
|
||||
pub one_of_index: ::std::option::Option<IndexRowOrder_oneof_one_of_index>,
|
||||
// special fields
|
||||
pub unknown_fields: ::protobuf::UnknownFields,
|
||||
pub cached_size: ::protobuf::CachedSize,
|
||||
}
|
||||
|
||||
impl<'a> ::std::default::Default for &'a IndexRowOrder {
|
||||
fn default() -> &'a IndexRowOrder {
|
||||
<IndexRowOrder as ::protobuf::Message>::default_instance()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone,PartialEq,Debug)]
|
||||
pub enum IndexRowOrder_oneof_one_of_index {
|
||||
index(i32),
|
||||
}
|
||||
|
||||
impl IndexRowOrder {
|
||||
pub fn new() -> IndexRowOrder {
|
||||
::std::default::Default::default()
|
||||
}
|
||||
|
||||
// .RowOrder row_order = 1;
|
||||
|
||||
|
||||
pub fn get_row_order(&self) -> &RowOrder {
|
||||
self.row_order.as_ref().unwrap_or_else(|| <RowOrder as ::protobuf::Message>::default_instance())
|
||||
}
|
||||
pub fn clear_row_order(&mut self) {
|
||||
self.row_order.clear();
|
||||
}
|
||||
|
||||
pub fn has_row_order(&self) -> bool {
|
||||
self.row_order.is_some()
|
||||
}
|
||||
|
||||
// Param is passed by value, moved
|
||||
pub fn set_row_order(&mut self, v: RowOrder) {
|
||||
self.row_order = ::protobuf::SingularPtrField::some(v);
|
||||
}
|
||||
|
||||
// Mutable pointer to the field.
|
||||
// If field is not initialized, it is initialized with default value first.
|
||||
pub fn mut_row_order(&mut self) -> &mut RowOrder {
|
||||
if self.row_order.is_none() {
|
||||
self.row_order.set_default();
|
||||
}
|
||||
self.row_order.as_mut().unwrap()
|
||||
}
|
||||
|
||||
// Take field
|
||||
pub fn take_row_order(&mut self) -> RowOrder {
|
||||
self.row_order.take().unwrap_or_else(|| RowOrder::new())
|
||||
}
|
||||
|
||||
// int32 index = 2;
|
||||
|
||||
|
||||
pub fn get_index(&self) -> i32 {
|
||||
match self.one_of_index {
|
||||
::std::option::Option::Some(IndexRowOrder_oneof_one_of_index::index(v)) => v,
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
pub fn clear_index(&mut self) {
|
||||
self.one_of_index = ::std::option::Option::None;
|
||||
}
|
||||
|
||||
pub fn has_index(&self) -> bool {
|
||||
match self.one_of_index {
|
||||
::std::option::Option::Some(IndexRowOrder_oneof_one_of_index::index(..)) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
// Param is passed by value, moved
|
||||
pub fn set_index(&mut self, v: i32) {
|
||||
self.one_of_index = ::std::option::Option::Some(IndexRowOrder_oneof_one_of_index::index(v))
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Message for IndexRowOrder {
|
||||
fn is_initialized(&self) -> bool {
|
||||
for v in &self.row_order {
|
||||
if !v.is_initialized() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
true
|
||||
}
|
||||
|
||||
fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
|
||||
while !is.eof()? {
|
||||
let (field_number, wire_type) = is.read_tag_unpack()?;
|
||||
match field_number {
|
||||
1 => {
|
||||
::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.row_order)?;
|
||||
},
|
||||
2 => {
|
||||
if wire_type != ::protobuf::wire_format::WireTypeVarint {
|
||||
return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
|
||||
}
|
||||
self.one_of_index = ::std::option::Option::Some(IndexRowOrder_oneof_one_of_index::index(is.read_int32()?));
|
||||
},
|
||||
_ => {
|
||||
::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
|
||||
},
|
||||
};
|
||||
}
|
||||
::std::result::Result::Ok(())
|
||||
}
|
||||
|
||||
// Compute sizes of nested messages
|
||||
#[allow(unused_variables)]
|
||||
fn compute_size(&self) -> u32 {
|
||||
let mut my_size = 0;
|
||||
if let Some(ref v) = self.row_order.as_ref() {
|
||||
let len = v.compute_size();
|
||||
my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
|
||||
}
|
||||
if let ::std::option::Option::Some(ref v) = self.one_of_index {
|
||||
match v {
|
||||
&IndexRowOrder_oneof_one_of_index::index(v) => {
|
||||
my_size += ::protobuf::rt::value_size(2, v, ::protobuf::wire_format::WireTypeVarint);
|
||||
},
|
||||
};
|
||||
}
|
||||
my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
|
||||
self.cached_size.set(my_size);
|
||||
my_size
|
||||
}
|
||||
|
||||
fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
|
||||
if let Some(ref v) = self.row_order.as_ref() {
|
||||
os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?;
|
||||
os.write_raw_varint32(v.get_cached_size())?;
|
||||
v.write_to_with_cached_sizes(os)?;
|
||||
}
|
||||
if let ::std::option::Option::Some(ref v) = self.one_of_index {
|
||||
match v {
|
||||
&IndexRowOrder_oneof_one_of_index::index(v) => {
|
||||
os.write_int32(2, v)?;
|
||||
},
|
||||
};
|
||||
}
|
||||
os.write_unknown_fields(self.get_unknown_fields())?;
|
||||
::std::result::Result::Ok(())
|
||||
}
|
||||
|
||||
fn get_cached_size(&self) -> u32 {
|
||||
self.cached_size.get()
|
||||
}
|
||||
|
||||
fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
|
||||
&self.unknown_fields
|
||||
}
|
||||
|
||||
fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
|
||||
&mut self.unknown_fields
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn (::std::any::Any) {
|
||||
self as &dyn (::std::any::Any)
|
||||
}
|
||||
fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
|
||||
self as &mut dyn (::std::any::Any)
|
||||
}
|
||||
fn into_any(self: ::std::boxed::Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
|
||||
self
|
||||
}
|
||||
|
||||
fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
|
||||
Self::descriptor_static()
|
||||
}
|
||||
|
||||
fn new() -> IndexRowOrder {
|
||||
IndexRowOrder::new()
|
||||
}
|
||||
|
||||
fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
|
||||
static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT;
|
||||
descriptor.get(|| {
|
||||
let mut fields = ::std::vec::Vec::new();
|
||||
fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<RowOrder>>(
|
||||
"row_order",
|
||||
|m: &IndexRowOrder| { &m.row_order },
|
||||
|m: &mut IndexRowOrder| { &mut m.row_order },
|
||||
));
|
||||
fields.push(::protobuf::reflect::accessor::make_singular_i32_accessor::<_>(
|
||||
"index",
|
||||
IndexRowOrder::has_index,
|
||||
IndexRowOrder::get_index,
|
||||
));
|
||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<IndexRowOrder>(
|
||||
"IndexRowOrder",
|
||||
fields,
|
||||
file_descriptor_proto()
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn default_instance() -> &'static IndexRowOrder {
|
||||
static instance: ::protobuf::rt::LazyV2<IndexRowOrder> = ::protobuf::rt::LazyV2::INIT;
|
||||
instance.get(IndexRowOrder::new)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Clear for IndexRowOrder {
|
||||
fn clear(&mut self) {
|
||||
self.row_order.clear();
|
||||
self.one_of_index = ::std::option::Option::None;
|
||||
self.unknown_fields.clear();
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::fmt::Debug for IndexRowOrder {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
|
||||
::protobuf::text_format::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::reflect::ProtobufValue for IndexRowOrder {
|
||||
fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
|
||||
::protobuf::reflect::ReflectValueRef::Message(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq,Clone,Default)]
|
||||
pub struct GridBlock {
|
||||
// message fields
|
||||
@ -5640,34 +5872,36 @@ static file_descriptor_proto_data: &'static [u8] = b"\
|
||||
\x20\x03(\x0b2\x04.RowR\x05items\"5\n\x11RepeatedGridBlock\x12\x20\n\x05\
|
||||
items\x18\x01\x20\x03(\x0b2\n.GridBlockR\x05items\"U\n\x0eGridBlockOrder\
|
||||
\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12(\n\nrow_orders\
|
||||
\x18\x02\x20\x03(\x0b2\t.RowOrderR\trowOrders\"\xc0\x01\n\x17GridBlockOr\
|
||||
derChangeset\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12.\n\
|
||||
\rinserted_rows\x18\x02\x20\x03(\x0b2\t.RowOrderR\x0cinsertedRows\x12,\n\
|
||||
\x0cdeleted_rows\x18\x03\x20\x03(\x0b2\t.RowOrderR\x0bdeletedRows\x12,\n\
|
||||
\x0cupdated_rows\x18\x04\x20\x03(\x0b2\t.RowOrderR\x0bupdatedRows\"E\n\t\
|
||||
GridBlock\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12(\n\nrow_orders\
|
||||
\x18\x02\x20\x03(\x0b2\t.RowOrderR\trowOrders\";\n\x04Cell\x12\x19\n\x08\
|
||||
field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x02\x20\
|
||||
\x01(\tR\x07content\"\x8f\x01\n\x14CellNotificationData\x12\x17\n\x07gri\
|
||||
d_id\x18\x01\x20\x01(\tR\x06gridId\x12\x19\n\x08field_id\x18\x02\x20\x01\
|
||||
(\tR\x07fieldId\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowId\x12\x1a\
|
||||
\n\x07content\x18\x04\x20\x01(\tH\0R\x07contentB\x10\n\x0eone_of_content\
|
||||
\"+\n\x0cRepeatedCell\x12\x1b\n\x05items\x18\x01\x20\x03(\x0b2\x05.CellR\
|
||||
\x05items\"'\n\x11CreateGridPayload\x12\x12\n\x04name\x18\x01\x20\x01(\t\
|
||||
R\x04name\"\x1e\n\x06GridId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05va\
|
||||
lue\"#\n\x0bGridBlockId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\
|
||||
\"f\n\x10CreateRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gr\
|
||||
idId\x12\"\n\x0cstart_row_id\x18\x02\x20\x01(\tH\0R\nstartRowIdB\x15\n\
|
||||
\x13one_of_start_row_id\"\xb6\x01\n\x12CreateFieldPayload\x12\x17\n\x07g\
|
||||
rid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x1c\n\x05field\x18\x02\x20\x01(\
|
||||
\x0b2\x06.FieldR\x05field\x12(\n\x10type_option_data\x18\x03\x20\x01(\
|
||||
\x0cR\x0etypeOptionData\x12&\n\x0estart_field_id\x18\x04\x20\x01(\tH\0R\
|
||||
\x0cstartFieldIdB\x17\n\x15one_of_start_field_id\"d\n\x11QueryFieldPaylo\
|
||||
ad\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_or\
|
||||
ders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"e\n\
|
||||
\x16QueryGridBlocksPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06g\
|
||||
ridId\x122\n\x0cblock_orders\x18\x02\x20\x03(\x0b2\x0f.GridBlockOrderR\
|
||||
\x0bblockOrdersb\x06proto3\
|
||||
\x18\x02\x20\x03(\x0b2\t.RowOrderR\trowOrders\"\xc5\x01\n\x17GridBlockOr\
|
||||
derChangeset\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x123\n\
|
||||
\rinserted_rows\x18\x02\x20\x03(\x0b2\x0e.IndexRowOrderR\x0cinsertedRows\
|
||||
\x12,\n\x0cdeleted_rows\x18\x03\x20\x03(\x0b2\t.RowOrderR\x0bdeletedRows\
|
||||
\x12,\n\x0cupdated_rows\x18\x04\x20\x03(\x0b2\t.RowOrderR\x0bupdatedRows\
|
||||
\"_\n\rIndexRowOrder\x12&\n\trow_order\x18\x01\x20\x01(\x0b2\t.RowOrderR\
|
||||
\x08rowOrder\x12\x16\n\x05index\x18\x02\x20\x01(\x05H\0R\x05indexB\x0e\n\
|
||||
\x0cone_of_index\"E\n\tGridBlock\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02\
|
||||
id\x12(\n\nrow_orders\x18\x02\x20\x03(\x0b2\t.RowOrderR\trowOrders\";\n\
|
||||
\x04Cell\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\
|
||||
\x07content\x18\x02\x20\x01(\tR\x07content\"\x8f\x01\n\x14CellNotificati\
|
||||
onData\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x19\n\x08f\
|
||||
ield_id\x18\x02\x20\x01(\tR\x07fieldId\x12\x15\n\x06row_id\x18\x03\x20\
|
||||
\x01(\tR\x05rowId\x12\x1a\n\x07content\x18\x04\x20\x01(\tH\0R\x07content\
|
||||
B\x10\n\x0eone_of_content\"+\n\x0cRepeatedCell\x12\x1b\n\x05items\x18\
|
||||
\x01\x20\x03(\x0b2\x05.CellR\x05items\"'\n\x11CreateGridPayload\x12\x12\
|
||||
\n\x04name\x18\x01\x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\n\x05va\
|
||||
lue\x18\x01\x20\x01(\tR\x05value\"#\n\x0bGridBlockId\x12\x14\n\x05value\
|
||||
\x18\x01\x20\x01(\tR\x05value\"f\n\x10CreateRowPayload\x12\x17\n\x07grid\
|
||||
_id\x18\x01\x20\x01(\tR\x06gridId\x12\"\n\x0cstart_row_id\x18\x02\x20\
|
||||
\x01(\tH\0R\nstartRowIdB\x15\n\x13one_of_start_row_id\"\xb6\x01\n\x12Cre\
|
||||
ateFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\
|
||||
\x1c\n\x05field\x18\x02\x20\x01(\x0b2\x06.FieldR\x05field\x12(\n\x10type\
|
||||
_option_data\x18\x03\x20\x01(\x0cR\x0etypeOptionData\x12&\n\x0estart_fie\
|
||||
ld_id\x18\x04\x20\x01(\tH\0R\x0cstartFieldIdB\x17\n\x15one_of_start_fiel\
|
||||
d_id\"d\n\x11QueryFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\
|
||||
\x06gridId\x126\n\x0cfield_orders\x18\x02\x20\x01(\x0b2\x13.RepeatedFiel\
|
||||
dOrderR\x0bfieldOrders\"e\n\x16QueryGridBlocksPayload\x12\x17\n\x07grid_\
|
||||
id\x18\x01\x20\x01(\tR\x06gridId\x122\n\x0cblock_orders\x18\x02\x20\x03(\
|
||||
\x0b2\x0f.GridBlockOrderR\x0bblockOrdersb\x06proto3\
|
||||
";
|
||||
|
||||
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
|
||||
|
@ -61,10 +61,14 @@ message GridBlockOrder {
|
||||
}
|
||||
message GridBlockOrderChangeset {
|
||||
string block_id = 1;
|
||||
repeated RowOrder inserted_rows = 2;
|
||||
repeated IndexRowOrder inserted_rows = 2;
|
||||
repeated RowOrder deleted_rows = 3;
|
||||
repeated RowOrder updated_rows = 4;
|
||||
}
|
||||
message IndexRowOrder {
|
||||
RowOrder row_order = 1;
|
||||
oneof one_of_index { int32 index = 2; };
|
||||
}
|
||||
message GridBlock {
|
||||
string id = 1;
|
||||
repeated RowOrder row_orders = 2;
|
||||
|
@ -48,16 +48,13 @@ impl GridBlockMetaPad {
|
||||
) -> CollaborateResult<Option<GridBlockMetaChange>> {
|
||||
self.modify(|rows| {
|
||||
if let Some(start_row_id) = start_row_id {
|
||||
if start_row_id.is_empty() {
|
||||
rows.insert(0, Arc::new(row));
|
||||
return Ok(Some(()));
|
||||
}
|
||||
|
||||
if !start_row_id.is_empty() {
|
||||
if let Some(index) = rows.iter().position(|row| row.id == start_row_id) {
|
||||
rows.insert(index + 1, Arc::new(row));
|
||||
return Ok(Some(()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rows.push(Arc::new(row));
|
||||
Ok(Some(()))
|
||||
@ -121,6 +118,13 @@ impl GridBlockMetaPad {
|
||||
self.rows.len() as i32
|
||||
}
|
||||
|
||||
pub fn index_of_row(&self, row_id: &str) -> Option<i32> {
|
||||
self.rows
|
||||
.iter()
|
||||
.position(|row| row.id == row_id)
|
||||
.map(|index| index as i32)
|
||||
}
|
||||
|
||||
pub fn update_row(&mut self, changeset: RowMetaChangeset) -> CollaborateResult<Option<GridBlockMetaChange>> {
|
||||
let row_id = changeset.row_id.clone();
|
||||
self.modify_row(&row_id, |row| {
|
||||
|
Loading…
Reference in New Issue
Block a user