chore: reorder field

This commit is contained in:
appflowy
2022-04-15 19:56:44 +08:00
parent 6dbb708991
commit 0c8850503f
6 changed files with 78 additions and 13 deletions

View File

@ -29,6 +29,17 @@ class FieldService {
return GridEventGetEditFieldContext(payload).send(); return GridEventGetEditFieldContext(payload).send();
} }
Future<Either<Unit, FlowyError>> moveField(String fieldId, int fromIndex, int toIndex) {
final payload = MoveItemPayload.create()
..gridId = gridId
..itemId = fieldId
..ty = MoveItemType.MoveField
..fromIndex = fromIndex
..toIndex = toIndex;
return GridEventMoveItem(payload).send();
}
Future<Either<Unit, FlowyError>> updateField({ Future<Either<Unit, FlowyError>> updateField({
required String fieldId, required String fieldId,
String? name, String? name,

View File

@ -1,4 +1,5 @@
import 'package:app_flowy/workspace/application/grid/field/field_service.dart'; import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
import 'package:flowy_sdk/log.dart';
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';
@ -25,7 +26,10 @@ class GridHeaderBloc extends Bloc<GridHeaderEvent, GridHeaderState> {
didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) { didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) {
emit(state.copyWith(fields: value.fields)); emit(state.copyWith(fields: value.fields));
}, },
moveField: (_MoveField value) {}, moveField: (_MoveField value) async {
final result = await _fieldService.moveField(value.field.id, value.fromIndex, value.toIndex);
result.fold((l) {}, (err) => Log.error(err));
},
); );
}, },
); );
@ -49,7 +53,7 @@ class GridHeaderBloc extends Bloc<GridHeaderEvent, GridHeaderState> {
class GridHeaderEvent with _$GridHeaderEvent { class GridHeaderEvent with _$GridHeaderEvent {
const factory GridHeaderEvent.initial() = _InitialHeader; const factory GridHeaderEvent.initial() = _InitialHeader;
const factory GridHeaderEvent.didReceiveFieldUpdate(List<Field> fields) = _DidReceiveFieldUpdate; const factory GridHeaderEvent.didReceiveFieldUpdate(List<Field> fields) = _DidReceiveFieldUpdate;
const factory GridHeaderEvent.moveField(int fromIndex, int toIndex) = _MoveField; const factory GridHeaderEvent.moveField(Field field, int fromIndex, int toIndex) = _MoveField;
} }
@freezed @freezed

View File

@ -75,6 +75,13 @@ class FlowyGrid extends StatefulWidget {
class _FlowyGridState extends State<FlowyGrid> { class _FlowyGridState extends State<FlowyGrid> {
final _scrollController = GridScrollController(scrollGroupContorller: LinkedScrollControllerGroup()); final _scrollController = GridScrollController(scrollGroupContorller: LinkedScrollControllerGroup());
late ScrollController headerScrollController;
@override
void initState() {
headerScrollController = _scrollController.linkHorizontalController();
super.initState();
}
@override @override
void dispose() { void dispose() {
@ -96,11 +103,14 @@ class _FlowyGridState extends State<FlowyGrid> {
], ],
); );
return Column(children: [ return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const _GridToolbarAdaptor(), const _GridToolbarAdaptor(),
_gridHeader(context, state.gridId, contentWidth), _gridHeader(context, state.gridId, contentWidth),
Flexible(child: child), Flexible(child: child),
]); ],
);
}, },
); );
} }
@ -145,7 +155,7 @@ class _FlowyGridState extends State<FlowyGrid> {
child: GridHeaderSliverAdaptor( child: GridHeaderSliverAdaptor(
gridId: gridId, gridId: gridId,
fieldCache: fieldCache, fieldCache: fieldCache,
anchorScrollController: _scrollController.linkHorizontalController(), anchorScrollController: headerScrollController,
), ),
); );
} }

View File

@ -110,7 +110,7 @@ class _GridHeaderState extends State<_GridHeader> {
header: const _CellLeading(), header: const _CellLeading(),
footer: _CellTrailing(gridId: widget.gridId), footer: _CellTrailing(gridId: widget.gridId),
onReorder: (int oldIndex, int newIndex) { onReorder: (int oldIndex, int newIndex) {
Log.info("from $oldIndex to $newIndex"); _onReorder(cells, oldIndex, context, newIndex);
}, },
children: cells, children: cells,
), ),
@ -119,6 +119,13 @@ class _GridHeaderState extends State<_GridHeader> {
}, },
); );
} }
void _onReorder(List<GridFieldCell> cells, int oldIndex, BuildContext context, int newIndex) {
if (cells.length > oldIndex) {
final field = cells[oldIndex].cellContext.field;
context.read<GridHeaderBloc>().add(GridHeaderEvent.moveField(field, oldIndex, newIndex));
}
}
} }
class _CellLeading extends StatelessWidget { class _CellLeading extends StatelessWidget {

View File

@ -385,16 +385,30 @@ impl ClientGridEditor {
pub async fn move_item(&self, params: MoveItemParams) -> FlowyResult<()> { pub async fn move_item(&self, params: MoveItemParams) -> FlowyResult<()> {
match params.ty { match params.ty {
MoveItemType::MoveField => { MoveItemType::MoveField => {
self.move_field(params.from_index, params.to_index, &params.item_id) self.move_field(&params.item_id, params.from_index, params.to_index)
.await .await
} }
MoveItemType::MoveRow => self.move_row(params.from_index, params.to_index, &params.item_id).await, MoveItemType::MoveRow => self.move_row(params.from_index, params.to_index, &params.item_id).await,
} }
} }
pub async fn move_field(&self, from: i32, to: i32, field_id: &str) -> FlowyResult<()> { pub async fn move_field(&self, field_id: &str, from: i32, to: i32) -> FlowyResult<()> {
// GridFieldChangeset let _ = self
todo!() .modify(|grid_pad| Ok(grid_pad.move_field(field_id, from as usize, to as usize)?))
.await?;
if let Some((index, field_meta)) = self.pad.read().await.get_field_meta(field_id) {
let delete_field_order = FieldOrder::from(field_id);
let insert_field = IndexField::from_field_meta(field_meta, index);
let notified_changeset = GridFieldChangeset {
grid_id: self.grid_id.clone(),
inserted_fields: vec![insert_field],
deleted_fields: vec![delete_field_order],
updated_fields: vec![],
};
let _ = self.notify_did_update_grid(notified_changeset).await?;
}
Ok(())
} }
pub async fn move_row(&self, from: i32, to: i32, row_id: &str) -> FlowyResult<()> { pub async fn move_row(&self, from: i32, to: i32, row_id: &str) -> FlowyResult<()> {

View File

@ -205,6 +205,25 @@ impl GridMetaPad {
) )
} }
pub fn move_field(
&mut self,
field_id: &str,
from_index: usize,
to_index: usize,
) -> CollaborateResult<Option<GridChangeset>> {
self.modify_grid(
|grid_meta| match grid_meta.fields.iter().position(|field| field.id == field_id) {
None => Ok(None),
Some(index) => {
debug_assert_eq!(index, from_index);
let field_meta = grid_meta.fields.remove(index);
grid_meta.fields.insert(to_index, field_meta);
Ok(Some(()))
}
},
)
}
pub fn contain_field(&self, field_id: &str) -> bool { pub fn contain_field(&self, field_id: &str) -> bool {
self.grid_meta.fields.iter().any(|field| field.id == field_id) self.grid_meta.fields.iter().any(|field| field.id == field_id)
} }