mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
fix: state of AppFlowyBoard is wrong after reordering the group
This commit is contained in:
@ -166,11 +166,11 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _moveGroup(String fromColumnId, String toColumnId) {
|
void _moveGroup(String fromGroupId, String toGroupId) {
|
||||||
_rowService
|
_rowService
|
||||||
.moveGroup(
|
.moveGroup(
|
||||||
fromGroupId: fromColumnId,
|
fromGroupId: fromGroupId,
|
||||||
toGroupId: toColumnId,
|
toGroupId: toGroupId,
|
||||||
)
|
)
|
||||||
.then((result) {
|
.then((result) {
|
||||||
result.fold((l) => null, (r) => add(BoardEvent.didReceiveError(r)));
|
result.fold((l) => null, (r) => add(BoardEvent.didReceiveError(r)));
|
||||||
|
@ -87,13 +87,13 @@ class BoardDataController {
|
|||||||
onUpdatedGroup.call(changeset.updateGroups);
|
onUpdatedGroup.call(changeset.updateGroups);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changeset.insertedGroups.isNotEmpty) {
|
|
||||||
onInsertedGroup.call(changeset.insertedGroups);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (changeset.deletedGroups.isNotEmpty) {
|
if (changeset.deletedGroups.isNotEmpty) {
|
||||||
onDeletedGroup.call(changeset.deletedGroups);
|
onDeletedGroup.call(changeset.deletedGroups);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (changeset.insertedGroups.isNotEmpty) {
|
||||||
|
onInsertedGroup.call(changeset.insertedGroups);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
(e) => _onError?.call(e),
|
(e) => _onError?.call(e),
|
||||||
);
|
);
|
||||||
|
@ -32,4 +32,8 @@ class Log {
|
|||||||
'AppFlowyBoard: ❗️[Trace] - ${DateTime.now().second}=> $message');
|
'AppFlowyBoard: ❗️[Trace] - ${DateTime.now().second}=> $message');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void error(String? message) {
|
||||||
|
debugPrint('AppFlowyBoard: ❌[Error] - ${DateTime.now().second}=> $message');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,11 +11,11 @@ import 'reorder_phantom/phantom_controller.dart';
|
|||||||
import '../rendering/board_overlay.dart';
|
import '../rendering/board_overlay.dart';
|
||||||
|
|
||||||
class AppFlowyBoardScrollController {
|
class AppFlowyBoardScrollController {
|
||||||
AppFlowyBoardState? _groupState;
|
AppFlowyBoardState? _boardState;
|
||||||
|
|
||||||
void scrollToBottom(String groupId,
|
void scrollToBottom(String groupId,
|
||||||
{void Function(BuildContext)? completed}) {
|
{void Function(BuildContext)? completed}) {
|
||||||
_groupState?.reorderFlexActionMap[groupId]?.scrollToBottom(completed);
|
_boardState?.reorderFlexActionMap[groupId]?.scrollToBottom(completed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,11 +92,7 @@ class AppFlowyBoard extends StatelessWidget {
|
|||||||
///
|
///
|
||||||
final AppFlowyBoardScrollController? boardScrollController;
|
final AppFlowyBoardScrollController? boardScrollController;
|
||||||
|
|
||||||
final AppFlowyBoardState _groupState = AppFlowyBoardState();
|
const AppFlowyBoard({
|
||||||
|
|
||||||
late final BoardPhantomController _phantomController;
|
|
||||||
|
|
||||||
AppFlowyBoard({
|
|
||||||
required this.controller,
|
required this.controller,
|
||||||
required this.cardBuilder,
|
required this.cardBuilder,
|
||||||
this.background,
|
this.background,
|
||||||
@ -107,12 +103,7 @@ class AppFlowyBoard extends StatelessWidget {
|
|||||||
this.groupConstraints = const BoxConstraints(maxWidth: 200),
|
this.groupConstraints = const BoxConstraints(maxWidth: 200),
|
||||||
this.config = const AppFlowyBoardConfig(),
|
this.config = const AppFlowyBoardConfig(),
|
||||||
Key? key,
|
Key? key,
|
||||||
}) : super(key: key) {
|
}) : super(key: key);
|
||||||
_phantomController = BoardPhantomController(
|
|
||||||
delegate: controller,
|
|
||||||
groupsState: _groupState,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -120,8 +111,14 @@ class AppFlowyBoard extends StatelessWidget {
|
|||||||
value: controller,
|
value: controller,
|
||||||
child: Consumer<AppFlowyBoardController>(
|
child: Consumer<AppFlowyBoardController>(
|
||||||
builder: (context, notifier, child) {
|
builder: (context, notifier, child) {
|
||||||
|
final boardState = AppFlowyBoardState();
|
||||||
|
BoardPhantomController phantomController = BoardPhantomController(
|
||||||
|
delegate: controller,
|
||||||
|
groupsState: boardState,
|
||||||
|
);
|
||||||
|
|
||||||
if (boardScrollController != null) {
|
if (boardScrollController != null) {
|
||||||
boardScrollController!._groupState = _groupState;
|
boardScrollController!._boardState = boardState;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _AppFlowyBoardContent(
|
return _AppFlowyBoardContent(
|
||||||
@ -129,14 +126,14 @@ class AppFlowyBoard extends StatelessWidget {
|
|||||||
dataController: controller,
|
dataController: controller,
|
||||||
scrollController: scrollController,
|
scrollController: scrollController,
|
||||||
scrollManager: boardScrollController,
|
scrollManager: boardScrollController,
|
||||||
groupState: _groupState,
|
boardState: boardState,
|
||||||
background: background,
|
background: background,
|
||||||
delegate: _phantomController,
|
delegate: phantomController,
|
||||||
groupConstraints: groupConstraints,
|
groupConstraints: groupConstraints,
|
||||||
cardBuilder: cardBuilder,
|
cardBuilder: cardBuilder,
|
||||||
footerBuilder: footerBuilder,
|
footerBuilder: footerBuilder,
|
||||||
headerBuilder: headerBuilder,
|
headerBuilder: headerBuilder,
|
||||||
phantomController: _phantomController,
|
phantomController: phantomController,
|
||||||
onReorder: controller.moveGroup,
|
onReorder: controller.moveGroup,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -154,7 +151,7 @@ class _AppFlowyBoardContent extends StatefulWidget {
|
|||||||
final ReorderFlexConfig reorderFlexConfig;
|
final ReorderFlexConfig reorderFlexConfig;
|
||||||
final BoxConstraints groupConstraints;
|
final BoxConstraints groupConstraints;
|
||||||
final AppFlowyBoardScrollController? scrollManager;
|
final AppFlowyBoardScrollController? scrollManager;
|
||||||
final AppFlowyBoardState groupState;
|
final AppFlowyBoardState boardState;
|
||||||
final AppFlowyBoardCardBuilder cardBuilder;
|
final AppFlowyBoardCardBuilder cardBuilder;
|
||||||
final AppFlowyBoardHeaderBuilder? headerBuilder;
|
final AppFlowyBoardHeaderBuilder? headerBuilder;
|
||||||
final AppFlowyBoardFooterBuilder? footerBuilder;
|
final AppFlowyBoardFooterBuilder? footerBuilder;
|
||||||
@ -167,7 +164,7 @@ class _AppFlowyBoardContent extends StatefulWidget {
|
|||||||
required this.delegate,
|
required this.delegate,
|
||||||
required this.dataController,
|
required this.dataController,
|
||||||
required this.scrollManager,
|
required this.scrollManager,
|
||||||
required this.groupState,
|
required this.boardState,
|
||||||
this.scrollController,
|
this.scrollController,
|
||||||
this.background,
|
this.background,
|
||||||
required this.groupConstraints,
|
required this.groupConstraints,
|
||||||
@ -199,7 +196,7 @@ class _AppFlowyBoardContentState extends State<_AppFlowyBoardContent> {
|
|||||||
reorderFlexId: widget.dataController.identifier,
|
reorderFlexId: widget.dataController.identifier,
|
||||||
acceptedReorderFlexId: widget.dataController.groupIds,
|
acceptedReorderFlexId: widget.dataController.groupIds,
|
||||||
delegate: widget.delegate,
|
delegate: widget.delegate,
|
||||||
columnsState: widget.groupState,
|
columnsState: widget.boardState,
|
||||||
);
|
);
|
||||||
|
|
||||||
final reorderFlex = ReorderFlex(
|
final reorderFlex = ReorderFlex(
|
||||||
@ -253,7 +250,7 @@ class _AppFlowyBoardContentState extends State<_AppFlowyBoardContent> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
final reorderFlexAction = ReorderFlexActionImpl();
|
final reorderFlexAction = ReorderFlexActionImpl();
|
||||||
widget.groupState.reorderFlexActionMap[columnData.id] =
|
widget.boardState.reorderFlexActionMap[columnData.id] =
|
||||||
reorderFlexAction;
|
reorderFlexAction;
|
||||||
|
|
||||||
return ChangeNotifierProvider.value(
|
return ChangeNotifierProvider.value(
|
||||||
@ -274,8 +271,8 @@ class _AppFlowyBoardContentState extends State<_AppFlowyBoardContent> {
|
|||||||
onReorder: widget.dataController.moveGroupItem,
|
onReorder: widget.dataController.moveGroupItem,
|
||||||
cornerRadius: widget.config.cornerRadius,
|
cornerRadius: widget.config.cornerRadius,
|
||||||
backgroundColor: widget.config.groupBackgroundColor,
|
backgroundColor: widget.config.groupBackgroundColor,
|
||||||
dragStateStorage: widget.groupState,
|
dragStateStorage: widget.boardState,
|
||||||
dragTargetKeys: widget.groupState,
|
dragTargetKeys: widget.boardState,
|
||||||
reorderFlexAction: reorderFlexAction,
|
reorderFlexAction: reorderFlexAction,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -138,7 +138,11 @@ class AppFlowyBoardController extends ChangeNotifier
|
|||||||
/// groups or get ready to reinitialize the [AppFlowyBoard].
|
/// groups or get ready to reinitialize the [AppFlowyBoard].
|
||||||
void clear() {
|
void clear() {
|
||||||
_groupDatas.clear();
|
_groupDatas.clear();
|
||||||
|
for (final group in _groupControllers.values) {
|
||||||
|
group.dispose();
|
||||||
|
}
|
||||||
_groupControllers.clear();
|
_groupControllers.clear();
|
||||||
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,6 +227,8 @@ class AppFlowyBoardController extends ChangeNotifier
|
|||||||
final fromGroupController = getGroupController(fromGroupId)!;
|
final fromGroupController = getGroupController(fromGroupId)!;
|
||||||
final toGroupController = getGroupController(toGroupId)!;
|
final toGroupController = getGroupController(toGroupId)!;
|
||||||
final fromGroupItem = fromGroupController.removeAt(fromGroupIndex);
|
final fromGroupItem = fromGroupController.removeAt(fromGroupIndex);
|
||||||
|
if (fromGroupItem == null) return;
|
||||||
|
|
||||||
if (toGroupController.items.length > toGroupIndex) {
|
if (toGroupController.items.length > toGroupIndex) {
|
||||||
assert(toGroupController.items[toGroupIndex] is PhantomGroupItem);
|
assert(toGroupController.items[toGroupIndex] is PhantomGroupItem);
|
||||||
|
|
||||||
@ -283,7 +289,9 @@ class AppFlowyBoardController extends ChangeNotifier
|
|||||||
Log.trace(
|
Log.trace(
|
||||||
'[$BoardPhantomController] update $groupId:$index to $groupId:$newIndex');
|
'[$BoardPhantomController] update $groupId:$index to $groupId:$newIndex');
|
||||||
final item = groupController.removeAt(index, notify: false);
|
final item = groupController.removeAt(index, notify: false);
|
||||||
groupController.insert(newIndex, item, notify: false);
|
if (item != null) {
|
||||||
|
groupController.insert(newIndex, item, notify: false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,9 +156,9 @@ class _AppFlowyBoardGroupState extends State<AppFlowyBoardGroup> {
|
|||||||
widget.onDragStarted?.call(index);
|
widget.onDragStarted?.call(index);
|
||||||
},
|
},
|
||||||
onReorder: ((fromIndex, toIndex) {
|
onReorder: ((fromIndex, toIndex) {
|
||||||
if (widget.phantomController.isFromGroup(widget.groupId)) {
|
if (widget.phantomController.shouldReorder(widget.groupId)) {
|
||||||
widget.onReorder(widget.groupId, fromIndex, toIndex);
|
widget.onReorder(widget.groupId, fromIndex, toIndex);
|
||||||
widget.phantomController.transformIndex(fromIndex, toIndex);
|
widget.phantomController.updateIndex(fromIndex, toIndex);
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
onDragEnded: () {
|
onDragEnded: () {
|
||||||
|
@ -52,8 +52,17 @@ class AppFlowyGroupController extends ChangeNotifier with EquatableMixin {
|
|||||||
/// * [notify] the default value of [notify] is true, it will notify the
|
/// * [notify] the default value of [notify] is true, it will notify the
|
||||||
/// listener. Set to false if you do not want to notify the listeners.
|
/// listener. Set to false if you do not want to notify the listeners.
|
||||||
///
|
///
|
||||||
AppFlowyGroupItem removeAt(int index, {bool notify = true}) {
|
AppFlowyGroupItem? removeAt(int index, {bool notify = true}) {
|
||||||
assert(index >= 0);
|
if (groupData._items.length <= index) {
|
||||||
|
Log.error(
|
||||||
|
'Fatal error, index is out of bounds. Index: $index, len: ${groupData._items.length}');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index < 0) {
|
||||||
|
Log.error('Invalid index:$index');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
Log.debug('[$AppFlowyGroupController] $groupData remove item at $index');
|
Log.debug('[$AppFlowyGroupController] $groupData remove item at $index');
|
||||||
final item = groupData._items.removeAt(index);
|
final item = groupData._items.removeAt(index);
|
||||||
@ -73,12 +82,17 @@ class AppFlowyGroupController extends ChangeNotifier with EquatableMixin {
|
|||||||
/// Move the item from [fromIndex] to [toIndex]. It will do nothing if the
|
/// Move the item from [fromIndex] to [toIndex]. It will do nothing if the
|
||||||
/// [fromIndex] equal to the [toIndex].
|
/// [fromIndex] equal to the [toIndex].
|
||||||
bool move(int fromIndex, int toIndex) {
|
bool move(int fromIndex, int toIndex) {
|
||||||
assert(fromIndex >= 0);
|
|
||||||
assert(toIndex >= 0);
|
assert(toIndex >= 0);
|
||||||
|
if (groupData._items.length < fromIndex) {
|
||||||
|
Log.error(
|
||||||
|
'Out of bounds error. index: $fromIndex should not greater than ${groupData._items.length}');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (fromIndex == toIndex) {
|
if (fromIndex == toIndex) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.debug(
|
Log.debug(
|
||||||
'[$AppFlowyGroupController] $groupData move item from $fromIndex to $toIndex');
|
'[$AppFlowyGroupController] $groupData move item from $fromIndex to $toIndex');
|
||||||
final item = groupData._items.removeAt(fromIndex);
|
final item = groupData._items.removeAt(fromIndex);
|
||||||
@ -126,7 +140,7 @@ class AppFlowyGroupController extends ChangeNotifier with EquatableMixin {
|
|||||||
Log.debug('[$AppFlowyGroupController] $groupData add $newItem');
|
Log.debug('[$AppFlowyGroupController] $groupData add $newItem');
|
||||||
} else {
|
} else {
|
||||||
if (index >= groupData._items.length) {
|
if (index >= groupData._items.length) {
|
||||||
Log.warn(
|
Log.error(
|
||||||
'[$AppFlowyGroupController] unexpected items length, index should less than the count of the items. Index: $index, items count: ${items.length}');
|
'[$AppFlowyGroupController] unexpected items length, index should less than the count of the items. Index: $index, items count: ${items.length}');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -46,15 +46,23 @@ class BoardPhantomController extends OverlapDragTargetDelegate
|
|||||||
required this.groupsState,
|
required this.groupsState,
|
||||||
});
|
});
|
||||||
|
|
||||||
bool isFromGroup(String groupId) {
|
/// Determines whether the group should perform reorder
|
||||||
|
///
|
||||||
|
/// Returns `true` if the fromGroupId and toGroupId of the phantomRecord
|
||||||
|
/// equal to the passed in groupId.
|
||||||
|
///
|
||||||
|
/// Returns `true` if the phantomRecord is null
|
||||||
|
///
|
||||||
|
bool shouldReorder(String groupId) {
|
||||||
if (phantomRecord != null) {
|
if (phantomRecord != null) {
|
||||||
return phantomRecord!.fromGroupId == groupId;
|
return phantomRecord!.toGroupId == groupId &&
|
||||||
|
phantomRecord!.fromGroupId == groupId;
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void transformIndex(int fromIndex, int toIndex) {
|
void updateIndex(int fromIndex, int toIndex) {
|
||||||
if (phantomRecord == null) {
|
if (phantomRecord == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -69,7 +77,6 @@ class BoardPhantomController extends OverlapDragTargetDelegate
|
|||||||
/// Remove the phantom in the group when the group is end dragging.
|
/// Remove the phantom in the group when the group is end dragging.
|
||||||
void groupEndDragging(String groupId) {
|
void groupEndDragging(String groupId) {
|
||||||
phantomState.setGroupIsDragging(groupId, false);
|
phantomState.setGroupIsDragging(groupId, false);
|
||||||
|
|
||||||
if (phantomRecord == null) return;
|
if (phantomRecord == null) return;
|
||||||
|
|
||||||
final fromGroupId = phantomRecord!.fromGroupId;
|
final fromGroupId = phantomRecord!.fromGroupId;
|
||||||
@ -246,10 +253,6 @@ class PhantomRecord {
|
|||||||
});
|
});
|
||||||
|
|
||||||
void updateFromGroupIndex(int index) {
|
void updateFromGroupIndex(int index) {
|
||||||
if (fromGroupIndex == index) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
fromGroupIndex = index;
|
fromGroupIndex = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -623,7 +623,7 @@ impl GridRevisionEditor {
|
|||||||
self.view_manager
|
self.view_manager
|
||||||
.move_group_row(row_rev, to_group_id, to_row_id.clone(), |row_changeset| {
|
.move_group_row(row_rev, to_group_id, to_row_id.clone(), |row_changeset| {
|
||||||
wrap_future(async move {
|
wrap_future(async move {
|
||||||
tracing::trace!("Move group row cause row data changed: {:?}", row_changeset);
|
tracing::trace!("Row data changed: {:?}", row_changeset);
|
||||||
let cell_changesets = row_changeset
|
let cell_changesets = row_changeset
|
||||||
.cell_by_field_id
|
.cell_by_field_id
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -79,7 +79,7 @@ impl GridViewRevisionEditor {
|
|||||||
Ok(json_str)
|
Ok(json_str)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn will_create_row(&self, row_rev: &mut RowRevision, params: &CreateRowParams) {
|
pub(crate) async fn will_create_view_row(&self, row_rev: &mut RowRevision, params: &CreateRowParams) {
|
||||||
if params.group_id.is_none() {
|
if params.group_id.is_none() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -92,7 +92,7 @@ impl GridViewRevisionEditor {
|
|||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn did_create_row(&self, row_pb: &RowPB, params: &CreateRowParams) {
|
pub(crate) async fn did_create_view_row(&self, row_pb: &RowPB, params: &CreateRowParams) {
|
||||||
// Send the group notification if the current view has groups
|
// Send the group notification if the current view has groups
|
||||||
match params.group_id.as_ref() {
|
match params.group_id.as_ref() {
|
||||||
None => {}
|
None => {}
|
||||||
@ -115,7 +115,7 @@ impl GridViewRevisionEditor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "trace", skip_all)]
|
#[tracing::instrument(level = "trace", skip_all)]
|
||||||
pub(crate) async fn did_delete_row(&self, row_rev: &RowRevision) {
|
pub(crate) async fn did_delete_view_row(&self, row_rev: &RowRevision) {
|
||||||
// Send the group notification if the current view has groups;
|
// Send the group notification if the current view has groups;
|
||||||
let changesets = self
|
let changesets = self
|
||||||
.mut_group_controller(|group_controller, field_rev| group_controller.did_delete_row(row_rev, &field_rev))
|
.mut_group_controller(|group_controller, field_rev| group_controller.did_delete_row(row_rev, &field_rev))
|
||||||
@ -129,7 +129,7 @@ impl GridViewRevisionEditor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn did_update_row(&self, row_rev: &RowRevision) {
|
pub(crate) async fn did_update_view_row(&self, row_rev: &RowRevision) {
|
||||||
let changesets = self
|
let changesets = self
|
||||||
.mut_group_controller(|group_controller, field_rev| group_controller.did_update_row(row_rev, &field_rev))
|
.mut_group_controller(|group_controller, field_rev| group_controller.did_update_row(row_rev, &field_rev))
|
||||||
.await;
|
.await;
|
||||||
@ -141,7 +141,7 @@ impl GridViewRevisionEditor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn move_group_row(
|
pub(crate) async fn move_view_group_row(
|
||||||
&self,
|
&self,
|
||||||
row_rev: &RowRevision,
|
row_rev: &RowRevision,
|
||||||
row_changeset: &mut RowChangeset,
|
row_changeset: &mut RowChangeset,
|
||||||
@ -167,14 +167,14 @@ impl GridViewRevisionEditor {
|
|||||||
}
|
}
|
||||||
/// Only call once after grid view editor initialized
|
/// Only call once after grid view editor initialized
|
||||||
#[tracing::instrument(level = "trace", skip(self))]
|
#[tracing::instrument(level = "trace", skip(self))]
|
||||||
pub(crate) async fn load_groups(&self) -> FlowyResult<Vec<GroupPB>> {
|
pub(crate) async fn load_view_groups(&self) -> FlowyResult<Vec<GroupPB>> {
|
||||||
let groups = self.group_controller.read().await.groups();
|
let groups = self.group_controller.read().await.groups();
|
||||||
tracing::trace!("Number of groups: {}", groups.len());
|
tracing::trace!("Number of groups: {}", groups.len());
|
||||||
Ok(groups.into_iter().map(GroupPB::from).collect())
|
Ok(groups.into_iter().map(GroupPB::from).collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "trace", skip(self), err)]
|
#[tracing::instrument(level = "trace", skip(self), err)]
|
||||||
pub(crate) async fn move_group(&self, params: MoveGroupParams) -> FlowyResult<()> {
|
pub(crate) async fn move_view_group(&self, params: MoveGroupParams) -> FlowyResult<()> {
|
||||||
let _ = self
|
let _ = self
|
||||||
.group_controller
|
.group_controller
|
||||||
.write()
|
.write()
|
||||||
@ -206,13 +206,13 @@ impl GridViewRevisionEditor {
|
|||||||
self.group_controller.read().await.field_id().to_owned()
|
self.group_controller.read().await.field_id().to_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn get_setting(&self) -> GridSettingPB {
|
pub(crate) async fn get_view_setting(&self) -> GridSettingPB {
|
||||||
let field_revs = self.field_delegate.get_field_revs().await;
|
let field_revs = self.field_delegate.get_field_revs().await;
|
||||||
let grid_setting = make_grid_setting(&*self.pad.read().await, &field_revs);
|
let grid_setting = make_grid_setting(&*self.pad.read().await, &field_revs);
|
||||||
grid_setting
|
grid_setting
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn get_filters(&self) -> Vec<GridFilterConfigurationPB> {
|
pub(crate) async fn get_view_filters(&self) -> Vec<GridFilterConfigurationPB> {
|
||||||
let field_revs = self.field_delegate.get_field_revs().await;
|
let field_revs = self.field_delegate.get_field_revs().await;
|
||||||
match self.pad.read().await.get_all_filters(&field_revs) {
|
match self.pad.read().await.get_all_filters(&field_revs) {
|
||||||
None => vec![],
|
None => vec![],
|
||||||
@ -245,7 +245,7 @@ impl GridViewRevisionEditor {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn delete_group(&self, params: DeleteGroupParams) -> FlowyResult<()> {
|
pub(crate) async fn delete_view_group(&self, params: DeleteGroupParams) -> FlowyResult<()> {
|
||||||
self.modify(|pad| {
|
self.modify(|pad| {
|
||||||
let changeset = pad.delete_filter(¶ms.field_id, ¶ms.field_type_rev, ¶ms.group_id)?;
|
let changeset = pad.delete_filter(¶ms.field_id, ¶ms.field_type_rev, ¶ms.group_id)?;
|
||||||
Ok(changeset)
|
Ok(changeset)
|
||||||
@ -253,7 +253,7 @@ impl GridViewRevisionEditor {
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn insert_filter(&self, params: InsertFilterParams) -> FlowyResult<()> {
|
pub(crate) async fn insert_view_filter(&self, params: InsertFilterParams) -> FlowyResult<()> {
|
||||||
self.modify(|pad| {
|
self.modify(|pad| {
|
||||||
let filter_rev = FilterConfigurationRevision {
|
let filter_rev = FilterConfigurationRevision {
|
||||||
id: gen_grid_filter_id(),
|
id: gen_grid_filter_id(),
|
||||||
@ -267,7 +267,7 @@ impl GridViewRevisionEditor {
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn delete_filter(&self, delete_filter: DeleteFilterParams) -> FlowyResult<()> {
|
pub(crate) async fn delete_view_filter(&self, delete_filter: DeleteFilterParams) -> FlowyResult<()> {
|
||||||
self.modify(|pad| {
|
self.modify(|pad| {
|
||||||
let changeset = pad.delete_filter(
|
let changeset = pad.delete_filter(
|
||||||
&delete_filter.field_id,
|
&delete_filter.field_id,
|
||||||
@ -324,7 +324,7 @@ impl GridViewRevisionEditor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn notify_did_update_setting(&self) {
|
async fn notify_did_update_setting(&self) {
|
||||||
let setting = self.get_setting().await;
|
let setting = self.get_view_setting().await;
|
||||||
send_dart_notification(&self.view_id, GridNotification::DidUpdateGridSetting)
|
send_dart_notification(&self.view_id, GridNotification::DidUpdateGridSetting)
|
||||||
.payload(setting)
|
.payload(setting)
|
||||||
.send();
|
.send();
|
||||||
|
@ -65,14 +65,14 @@ impl GridViewManager {
|
|||||||
/// When the row was created, we may need to modify the [RowRevision] according to the [CreateRowParams].
|
/// When the row was created, we may need to modify the [RowRevision] according to the [CreateRowParams].
|
||||||
pub(crate) async fn will_create_row(&self, row_rev: &mut RowRevision, params: &CreateRowParams) {
|
pub(crate) async fn will_create_row(&self, row_rev: &mut RowRevision, params: &CreateRowParams) {
|
||||||
for view_editor in self.view_editors.iter() {
|
for view_editor in self.view_editors.iter() {
|
||||||
view_editor.will_create_row(row_rev, params).await;
|
view_editor.will_create_view_row(row_rev, params).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Notify the view that the row was created. For the moment, the view is just sending notifications.
|
/// Notify the view that the row was created. For the moment, the view is just sending notifications.
|
||||||
pub(crate) async fn did_create_row(&self, row_pb: &RowPB, params: &CreateRowParams) {
|
pub(crate) async fn did_create_row(&self, row_pb: &RowPB, params: &CreateRowParams) {
|
||||||
for view_editor in self.view_editors.iter() {
|
for view_editor in self.view_editors.iter() {
|
||||||
view_editor.did_create_row(row_pb, params).await;
|
view_editor.did_create_view_row(row_pb, params).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,7 +84,7 @@ impl GridViewManager {
|
|||||||
}
|
}
|
||||||
Some(row_rev) => {
|
Some(row_rev) => {
|
||||||
for view_editor in self.view_editors.iter() {
|
for view_editor in self.view_editors.iter() {
|
||||||
view_editor.did_update_row(&row_rev).await;
|
view_editor.did_update_view_row(&row_rev).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -102,33 +102,33 @@ impl GridViewManager {
|
|||||||
|
|
||||||
pub(crate) async fn did_delete_row(&self, row_rev: Arc<RowRevision>) {
|
pub(crate) async fn did_delete_row(&self, row_rev: Arc<RowRevision>) {
|
||||||
for view_editor in self.view_editors.iter() {
|
for view_editor in self.view_editors.iter() {
|
||||||
view_editor.did_delete_row(&row_rev).await;
|
view_editor.did_delete_view_row(&row_rev).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn get_setting(&self) -> FlowyResult<GridSettingPB> {
|
pub(crate) async fn get_setting(&self) -> FlowyResult<GridSettingPB> {
|
||||||
let view_editor = self.get_default_view_editor().await?;
|
let view_editor = self.get_default_view_editor().await?;
|
||||||
Ok(view_editor.get_setting().await)
|
Ok(view_editor.get_view_setting().await)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn get_filters(&self) -> FlowyResult<Vec<GridFilterConfigurationPB>> {
|
pub(crate) async fn get_filters(&self) -> FlowyResult<Vec<GridFilterConfigurationPB>> {
|
||||||
let view_editor = self.get_default_view_editor().await?;
|
let view_editor = self.get_default_view_editor().await?;
|
||||||
Ok(view_editor.get_filters().await)
|
Ok(view_editor.get_view_filters().await)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn insert_or_update_filter(&self, params: InsertFilterParams) -> FlowyResult<()> {
|
pub(crate) async fn insert_or_update_filter(&self, params: InsertFilterParams) -> FlowyResult<()> {
|
||||||
let view_editor = self.get_default_view_editor().await?;
|
let view_editor = self.get_default_view_editor().await?;
|
||||||
view_editor.insert_filter(params).await
|
view_editor.insert_view_filter(params).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn delete_filter(&self, params: DeleteFilterParams) -> FlowyResult<()> {
|
pub(crate) async fn delete_filter(&self, params: DeleteFilterParams) -> FlowyResult<()> {
|
||||||
let view_editor = self.get_default_view_editor().await?;
|
let view_editor = self.get_default_view_editor().await?;
|
||||||
view_editor.delete_filter(params).await
|
view_editor.delete_view_filter(params).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn load_groups(&self) -> FlowyResult<RepeatedGridGroupPB> {
|
pub(crate) async fn load_groups(&self) -> FlowyResult<RepeatedGridGroupPB> {
|
||||||
let view_editor = self.get_default_view_editor().await?;
|
let view_editor = self.get_default_view_editor().await?;
|
||||||
let groups = view_editor.load_groups().await?;
|
let groups = view_editor.load_view_groups().await?;
|
||||||
Ok(RepeatedGridGroupPB { items: groups })
|
Ok(RepeatedGridGroupPB { items: groups })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,12 +139,12 @@ impl GridViewManager {
|
|||||||
|
|
||||||
pub(crate) async fn delete_group(&self, params: DeleteGroupParams) -> FlowyResult<()> {
|
pub(crate) async fn delete_group(&self, params: DeleteGroupParams) -> FlowyResult<()> {
|
||||||
let view_editor = self.get_default_view_editor().await?;
|
let view_editor = self.get_default_view_editor().await?;
|
||||||
view_editor.delete_group(params).await
|
view_editor.delete_view_group(params).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn move_group(&self, params: MoveGroupParams) -> FlowyResult<()> {
|
pub(crate) async fn move_group(&self, params: MoveGroupParams) -> FlowyResult<()> {
|
||||||
let view_editor = self.get_default_view_editor().await?;
|
let view_editor = self.get_default_view_editor().await?;
|
||||||
let _ = view_editor.move_group(params).await?;
|
let _ = view_editor.move_view_group(params).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,7 +161,7 @@ impl GridViewManager {
|
|||||||
let mut row_changeset = RowChangeset::new(row_rev.id.clone());
|
let mut row_changeset = RowChangeset::new(row_rev.id.clone());
|
||||||
let view_editor = self.get_default_view_editor().await?;
|
let view_editor = self.get_default_view_editor().await?;
|
||||||
let group_changesets = view_editor
|
let group_changesets = view_editor
|
||||||
.move_group_row(&row_rev, &mut row_changeset, &to_group_id, to_row_id.clone())
|
.move_view_group_row(&row_rev, &mut row_changeset, &to_group_id, to_row_id.clone())
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
if !row_changeset.is_empty() {
|
if !row_changeset.is_empty() {
|
||||||
|
@ -119,12 +119,20 @@ where
|
|||||||
self.mut_configuration(|configuration| {
|
self.mut_configuration(|configuration| {
|
||||||
let from_index = configuration.groups.iter().position(|group| group.id == from_id);
|
let from_index = configuration.groups.iter().position(|group| group.id == from_id);
|
||||||
let to_index = configuration.groups.iter().position(|group| group.id == to_id);
|
let to_index = configuration.groups.iter().position(|group| group.id == to_id);
|
||||||
tracing::info!("Configuration groups: {:?} ", configuration.groups);
|
|
||||||
if let (Some(from), Some(to)) = &(from_index, to_index) {
|
if let (Some(from), Some(to)) = &(from_index, to_index) {
|
||||||
tracing::trace!("Move group from index:{:?} to index:{:?}", from_index, to_index);
|
tracing::trace!("Move group from index:{:?} to index:{:?}", from_index, to_index);
|
||||||
let group = configuration.groups.remove(*from);
|
let group = configuration.groups.remove(*from);
|
||||||
configuration.groups.insert(*to, group);
|
configuration.groups.insert(*to, group);
|
||||||
}
|
}
|
||||||
|
tracing::debug!(
|
||||||
|
"Group order: {:?} ",
|
||||||
|
configuration
|
||||||
|
.groups
|
||||||
|
.iter()
|
||||||
|
.map(|group| group.name.clone())
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join(",")
|
||||||
|
);
|
||||||
|
|
||||||
from_index.is_some() && to_index.is_some()
|
from_index.is_some() && to_index.is_some()
|
||||||
})?;
|
})?;
|
||||||
|
@ -80,9 +80,9 @@ pub fn move_group_row(group: &mut Group, context: &mut MoveGroupRowContext) -> O
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Remove the row in which group contains it
|
// Remove the row in which group contains it
|
||||||
if from_index.is_some() {
|
if let Some(from_index) = &from_index {
|
||||||
changeset.deleted_rows.push(row_rev.id.clone());
|
changeset.deleted_rows.push(row_rev.id.clone());
|
||||||
tracing::debug!("Group:{} remove row:{}", group.id, row_rev.id);
|
tracing::debug!("Group:{} remove {} at {}", group.id, row_rev.id, from_index);
|
||||||
group.remove_row(&row_rev.id);
|
group.remove_row(&row_rev.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,10 +97,11 @@ pub fn move_group_row(group: &mut Group, context: &mut MoveGroupRowContext) -> O
|
|||||||
}
|
}
|
||||||
Some(to_index) => {
|
Some(to_index) => {
|
||||||
if to_index < group.number_of_row() {
|
if to_index < group.number_of_row() {
|
||||||
tracing::debug!("Group:{} insert row:{} at {} ", group.id, row_rev.id, to_index);
|
tracing::debug!("Group:{} insert {} at {} ", group.id, row_rev.id, to_index);
|
||||||
inserted_row.index = Some(to_index as i32);
|
inserted_row.index = Some(to_index as i32);
|
||||||
group.insert_row(to_index, row_pb);
|
group.insert_row(to_index, row_pb);
|
||||||
} else {
|
} else {
|
||||||
|
tracing::warn!("Mote to index: {} is out of bounds", to_index);
|
||||||
tracing::debug!("Group:{} append row:{}", group.id, row_rev.id);
|
tracing::debug!("Group:{} append row:{}", group.id, row_rev.id);
|
||||||
group.add_row(row_pb);
|
group.add_row(row_pb);
|
||||||
}
|
}
|
||||||
|
@ -350,6 +350,36 @@ async fn group_move_from_default_group_test() {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn group_move_group_test() {
|
async fn group_move_group_test() {
|
||||||
|
let mut test = GridGroupTest::new().await;
|
||||||
|
let group_0 = test.group_at_index(0).await;
|
||||||
|
let group_1 = test.group_at_index(1).await;
|
||||||
|
let scripts = vec![
|
||||||
|
MoveGroup {
|
||||||
|
from_group_index: 0,
|
||||||
|
to_group_index: 1,
|
||||||
|
},
|
||||||
|
AssertGroupRowCount {
|
||||||
|
group_index: 0,
|
||||||
|
row_count: 2,
|
||||||
|
},
|
||||||
|
AssertGroup {
|
||||||
|
group_index: 0,
|
||||||
|
expected_group: group_1,
|
||||||
|
},
|
||||||
|
AssertGroupRowCount {
|
||||||
|
group_index: 1,
|
||||||
|
row_count: 2,
|
||||||
|
},
|
||||||
|
AssertGroup {
|
||||||
|
group_index: 1,
|
||||||
|
expected_group: group_0,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
test.run_scripts(scripts).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn group_move_group_row_after_move_group_test() {
|
||||||
let mut test = GridGroupTest::new().await;
|
let mut test = GridGroupTest::new().await;
|
||||||
let group_0 = test.group_at_index(0).await;
|
let group_0 = test.group_at_index(0).await;
|
||||||
let group_1 = test.group_at_index(1).await;
|
let group_1 = test.group_at_index(1).await;
|
||||||
@ -366,6 +396,20 @@ async fn group_move_group_test() {
|
|||||||
group_index: 1,
|
group_index: 1,
|
||||||
expected_group: group_0,
|
expected_group: group_0,
|
||||||
},
|
},
|
||||||
|
MoveRow {
|
||||||
|
from_group_index: 0,
|
||||||
|
from_row_index: 0,
|
||||||
|
to_group_index: 1,
|
||||||
|
to_row_index: 0,
|
||||||
|
},
|
||||||
|
AssertGroupRowCount {
|
||||||
|
group_index: 0,
|
||||||
|
row_count: 1,
|
||||||
|
},
|
||||||
|
AssertGroupRowCount {
|
||||||
|
group_index: 1,
|
||||||
|
row_count: 3,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
test.run_scripts(scripts).await;
|
test.run_scripts(scripts).await;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user