mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
Merge branch 'AppFlowy-IO:main' into documentation/flowy_editor
This commit is contained in:
commit
713e6abaa6
@ -14,12 +14,14 @@ import 'package:freezed_annotation/freezed_annotation.dart';
|
|||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
|
|
||||||
import 'board_data_controller.dart';
|
import 'board_data_controller.dart';
|
||||||
|
import 'group_controller.dart';
|
||||||
|
|
||||||
part 'board_bloc.freezed.dart';
|
part 'board_bloc.freezed.dart';
|
||||||
|
|
||||||
class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
||||||
final BoardDataController _dataController;
|
final BoardDataController _dataController;
|
||||||
late final AFBoardDataController boardDataController;
|
late final AFBoardDataController afBoardDataController;
|
||||||
|
List<GroupController> groupControllers = [];
|
||||||
|
|
||||||
GridFieldCache get fieldCache => _dataController.fieldCache;
|
GridFieldCache get fieldCache => _dataController.fieldCache;
|
||||||
String get gridId => _dataController.gridId;
|
String get gridId => _dataController.gridId;
|
||||||
@ -27,7 +29,7 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
|||||||
BoardBloc({required ViewPB view})
|
BoardBloc({required ViewPB view})
|
||||||
: _dataController = BoardDataController(view: view),
|
: _dataController = BoardDataController(view: view),
|
||||||
super(BoardState.initial(view.id)) {
|
super(BoardState.initial(view.id)) {
|
||||||
boardDataController = AFBoardDataController(
|
afBoardDataController = AFBoardDataController(
|
||||||
onMoveColumn: (
|
onMoveColumn: (
|
||||||
fromIndex,
|
fromIndex,
|
||||||
toIndex,
|
toIndex,
|
||||||
@ -71,9 +73,6 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
|||||||
didReceiveGridUpdate: (GridPB grid) {
|
didReceiveGridUpdate: (GridPB grid) {
|
||||||
emit(state.copyWith(grid: Some(grid)));
|
emit(state.copyWith(grid: Some(grid)));
|
||||||
},
|
},
|
||||||
didReceiveGroups: (List<GroupPB> groups) {
|
|
||||||
emit(state.copyWith(groups: groups));
|
|
||||||
},
|
|
||||||
didReceiveRows: (List<RowInfo> rowInfos) {
|
didReceiveRows: (List<RowInfo> rowInfos) {
|
||||||
emit(state.copyWith(rowInfos: rowInfos));
|
emit(state.copyWith(rowInfos: rowInfos));
|
||||||
},
|
},
|
||||||
@ -85,9 +84,24 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
|||||||
@override
|
@override
|
||||||
Future<void> close() async {
|
Future<void> close() async {
|
||||||
await _dataController.dispose();
|
await _dataController.dispose();
|
||||||
|
for (final controller in groupControllers) {
|
||||||
|
controller.dispose();
|
||||||
|
}
|
||||||
return super.close();
|
return super.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void initializeGroups(List<GroupPB> groups) {
|
||||||
|
for (final group in groups) {
|
||||||
|
final delegate = GroupControllerDelegateImpl(afBoardDataController);
|
||||||
|
final controller = GroupController(
|
||||||
|
group: group,
|
||||||
|
delegate: delegate,
|
||||||
|
);
|
||||||
|
controller.startListening();
|
||||||
|
groupControllers.add(controller);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GridRowCache? getRowCache(String blockId) {
|
GridRowCache? getRowCache(String blockId) {
|
||||||
final GridBlockCache? blockCache = _dataController.blocks[blockId];
|
final GridBlockCache? blockCache = _dataController.blocks[blockId];
|
||||||
return blockCache?.rowCache;
|
return blockCache?.rowCache;
|
||||||
@ -100,7 +114,7 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
|||||||
add(BoardEvent.didReceiveGridUpdate(grid));
|
add(BoardEvent.didReceiveGridUpdate(grid));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onGroupChanged: (groups) {
|
didLoadGroups: (groups) {
|
||||||
List<AFBoardColumnData> columns = groups.map((group) {
|
List<AFBoardColumnData> columns = groups.map((group) {
|
||||||
return AFBoardColumnData(
|
return AFBoardColumnData(
|
||||||
id: group.groupId,
|
id: group.groupId,
|
||||||
@ -110,7 +124,8 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
|||||||
);
|
);
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
||||||
boardDataController.addColumns(columns);
|
afBoardDataController.addColumns(columns);
|
||||||
|
initializeGroups(groups);
|
||||||
},
|
},
|
||||||
onRowsChanged: (List<RowInfo> rowInfos, RowsChangedReason reason) {
|
onRowsChanged: (List<RowInfo> rowInfos, RowsChangedReason reason) {
|
||||||
add(BoardEvent.didReceiveRows(rowInfos));
|
add(BoardEvent.didReceiveRows(rowInfos));
|
||||||
@ -123,14 +138,6 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
|||||||
|
|
||||||
List<AFColumnItem> _buildRows(List<RowPB> rows) {
|
List<AFColumnItem> _buildRows(List<RowPB> rows) {
|
||||||
final items = rows.map((row) {
|
final items = rows.map((row) {
|
||||||
// final rowInfo = RowInfo(
|
|
||||||
// gridId: _dataController.gridId,
|
|
||||||
// blockId: row.blockId,
|
|
||||||
// id: row.id,
|
|
||||||
// fields: _dataController.fieldCache.unmodifiableFields,
|
|
||||||
// height: row.height.toDouble(),
|
|
||||||
// rawRow: row,
|
|
||||||
// );
|
|
||||||
return BoardColumnItem(row: row);
|
return BoardColumnItem(row: row);
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
||||||
@ -155,8 +162,6 @@ class BoardEvent with _$BoardEvent {
|
|||||||
const factory BoardEvent.initial() = InitialGrid;
|
const factory BoardEvent.initial() = InitialGrid;
|
||||||
const factory BoardEvent.createRow(String groupId) = _CreateRow;
|
const factory BoardEvent.createRow(String groupId) = _CreateRow;
|
||||||
const factory BoardEvent.endEditRow(String rowId) = _EndEditRow;
|
const factory BoardEvent.endEditRow(String rowId) = _EndEditRow;
|
||||||
const factory BoardEvent.didReceiveGroups(List<GroupPB> groups) =
|
|
||||||
_DidReceiveGroup;
|
|
||||||
const factory BoardEvent.didReceiveRows(List<RowInfo> rowInfos) =
|
const factory BoardEvent.didReceiveRows(List<RowInfo> rowInfos) =
|
||||||
_DidReceiveRows;
|
_DidReceiveRows;
|
||||||
const factory BoardEvent.didReceiveGridUpdate(
|
const factory BoardEvent.didReceiveGridUpdate(
|
||||||
@ -169,7 +174,6 @@ class BoardState with _$BoardState {
|
|||||||
const factory BoardState({
|
const factory BoardState({
|
||||||
required String gridId,
|
required String gridId,
|
||||||
required Option<GridPB> grid,
|
required Option<GridPB> grid,
|
||||||
required List<GroupPB> groups,
|
|
||||||
required Option<RowPB> editingRow,
|
required Option<RowPB> editingRow,
|
||||||
required List<RowInfo> rowInfos,
|
required List<RowInfo> rowInfos,
|
||||||
required GridLoadingState loadingState,
|
required GridLoadingState loadingState,
|
||||||
@ -177,7 +181,6 @@ class BoardState with _$BoardState {
|
|||||||
|
|
||||||
factory BoardState.initial(String gridId) => BoardState(
|
factory BoardState.initial(String gridId) => BoardState(
|
||||||
rowInfos: [],
|
rowInfos: [],
|
||||||
groups: [],
|
|
||||||
grid: none(),
|
grid: none(),
|
||||||
gridId: gridId,
|
gridId: gridId,
|
||||||
editingRow: none(),
|
editingRow: none(),
|
||||||
@ -228,3 +231,27 @@ class CreateCardItem extends AFColumnItem {
|
|||||||
@override
|
@override
|
||||||
String get id => '$CreateCardItem';
|
String get id => '$CreateCardItem';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class GroupControllerDelegateImpl extends GroupControllerDelegate {
|
||||||
|
final AFBoardDataController controller;
|
||||||
|
|
||||||
|
GroupControllerDelegateImpl(this.controller);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void insertRow(String groupId, RowPB row, int? index) {
|
||||||
|
final item = BoardColumnItem(row: row);
|
||||||
|
if (index != null) {
|
||||||
|
controller.insertColumnItem(groupId, index, item);
|
||||||
|
} else {
|
||||||
|
controller.addColumnItem(groupId, item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void removeRow(String groupId, String rowId) {
|
||||||
|
controller.removeColumnItem(groupId, rowId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void updateRow(String groupId, RowPB row) {}
|
||||||
|
}
|
||||||
|
@ -12,7 +12,7 @@ import 'package:flowy_sdk/protobuf/flowy-grid/protobuf.dart';
|
|||||||
|
|
||||||
typedef OnFieldsChanged = void Function(UnmodifiableListView<FieldPB>);
|
typedef OnFieldsChanged = void Function(UnmodifiableListView<FieldPB>);
|
||||||
typedef OnGridChanged = void Function(GridPB);
|
typedef OnGridChanged = void Function(GridPB);
|
||||||
typedef OnGroupChanged = void Function(List<GroupPB>);
|
typedef DidLoadGroups = void Function(List<GroupPB>);
|
||||||
typedef OnRowsChanged = void Function(
|
typedef OnRowsChanged = void Function(
|
||||||
List<RowInfo>,
|
List<RowInfo>,
|
||||||
RowsChangedReason,
|
RowsChangedReason,
|
||||||
@ -30,7 +30,7 @@ class BoardDataController {
|
|||||||
|
|
||||||
OnFieldsChanged? _onFieldsChanged;
|
OnFieldsChanged? _onFieldsChanged;
|
||||||
OnGridChanged? _onGridChanged;
|
OnGridChanged? _onGridChanged;
|
||||||
OnGroupChanged? _onGroupChanged;
|
DidLoadGroups? _didLoadGroup;
|
||||||
OnRowsChanged? _onRowsChanged;
|
OnRowsChanged? _onRowsChanged;
|
||||||
OnError? _onError;
|
OnError? _onError;
|
||||||
|
|
||||||
@ -51,13 +51,13 @@ class BoardDataController {
|
|||||||
void addListener({
|
void addListener({
|
||||||
OnGridChanged? onGridChanged,
|
OnGridChanged? onGridChanged,
|
||||||
OnFieldsChanged? onFieldsChanged,
|
OnFieldsChanged? onFieldsChanged,
|
||||||
OnGroupChanged? onGroupChanged,
|
DidLoadGroups? didLoadGroups,
|
||||||
OnRowsChanged? onRowsChanged,
|
OnRowsChanged? onRowsChanged,
|
||||||
OnError? onError,
|
OnError? onError,
|
||||||
}) {
|
}) {
|
||||||
_onGridChanged = onGridChanged;
|
_onGridChanged = onGridChanged;
|
||||||
_onFieldsChanged = onFieldsChanged;
|
_onFieldsChanged = onFieldsChanged;
|
||||||
_onGroupChanged = onGroupChanged;
|
_didLoadGroup = didLoadGroups;
|
||||||
_onRowsChanged = onRowsChanged;
|
_onRowsChanged = onRowsChanged;
|
||||||
_onError = onError;
|
_onError = onError;
|
||||||
|
|
||||||
@ -133,7 +133,7 @@ class BoardDataController {
|
|||||||
return Future(
|
return Future(
|
||||||
() => result.fold(
|
() => result.fold(
|
||||||
(groups) {
|
(groups) {
|
||||||
_onGroupChanged?.call(groups.items);
|
_didLoadGroup?.call(groups.items);
|
||||||
},
|
},
|
||||||
(err) => _onError?.call(err),
|
(err) => _onError?.call(err),
|
||||||
),
|
),
|
||||||
|
@ -23,7 +23,6 @@ class BoardCardBloc extends Bloc<BoardCardEvent, BoardCardState> {
|
|||||||
}) : _rowService = RowFFIService(
|
}) : _rowService = RowFFIService(
|
||||||
gridId: gridId,
|
gridId: gridId,
|
||||||
blockId: dataController.rowPB.blockId,
|
blockId: dataController.rowPB.blockId,
|
||||||
rowId: dataController.rowPB.id,
|
|
||||||
),
|
),
|
||||||
_dataController = dataController,
|
_dataController = dataController,
|
||||||
super(BoardCardState.initial(
|
super(BoardCardState.initial(
|
||||||
@ -34,9 +33,6 @@ class BoardCardBloc extends Bloc<BoardCardEvent, BoardCardState> {
|
|||||||
initial: (_InitialRow value) async {
|
initial: (_InitialRow value) async {
|
||||||
await _startListening();
|
await _startListening();
|
||||||
},
|
},
|
||||||
createRow: (_CreateRow value) {
|
|
||||||
_rowService.createRow();
|
|
||||||
},
|
|
||||||
didReceiveCells: (_DidReceiveCells value) async {
|
didReceiveCells: (_DidReceiveCells value) async {
|
||||||
final cells = value.gridCellMap.values
|
final cells = value.gridCellMap.values
|
||||||
.map((e) => GridCellEquatable(e.field))
|
.map((e) => GridCellEquatable(e.field))
|
||||||
@ -58,6 +54,16 @@ class BoardCardBloc extends Bloc<BoardCardEvent, BoardCardState> {
|
|||||||
return super.close();
|
return super.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RowInfo rowInfo() {
|
||||||
|
return RowInfo(
|
||||||
|
gridId: _rowService.gridId,
|
||||||
|
fields: UnmodifiableListView(
|
||||||
|
state.cells.map((cell) => cell._field).toList(),
|
||||||
|
),
|
||||||
|
rowPB: state.rowPB,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _startListening() async {
|
Future<void> _startListening() async {
|
||||||
_dataController.addListener(
|
_dataController.addListener(
|
||||||
onRowChanged: (cells, reason) {
|
onRowChanged: (cells, reason) {
|
||||||
@ -72,7 +78,6 @@ class BoardCardBloc extends Bloc<BoardCardEvent, BoardCardState> {
|
|||||||
@freezed
|
@freezed
|
||||||
class BoardCardEvent with _$BoardCardEvent {
|
class BoardCardEvent with _$BoardCardEvent {
|
||||||
const factory BoardCardEvent.initial() = _InitialRow;
|
const factory BoardCardEvent.initial() = _InitialRow;
|
||||||
const factory BoardCardEvent.createRow() = _CreateRow;
|
|
||||||
const factory BoardCardEvent.didReceiveCells(
|
const factory BoardCardEvent.didReceiveCells(
|
||||||
GridCellMap gridCellMap, RowsChangedReason reason) = _DidReceiveCells;
|
GridCellMap gridCellMap, RowsChangedReason reason) = _DidReceiveCells;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,49 @@
|
|||||||
|
import 'package:flowy_sdk/log.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-grid/protobuf.dart';
|
||||||
|
|
||||||
|
import 'group_listener.dart';
|
||||||
|
|
||||||
|
abstract class GroupControllerDelegate {
|
||||||
|
void removeRow(String groupId, String rowId);
|
||||||
|
void insertRow(String groupId, RowPB row, int? index);
|
||||||
|
void updateRow(String groupId, RowPB row);
|
||||||
|
}
|
||||||
|
|
||||||
|
class GroupController {
|
||||||
|
final GroupPB group;
|
||||||
|
final GroupListener _listener;
|
||||||
|
final GroupControllerDelegate delegate;
|
||||||
|
|
||||||
|
GroupController({required this.group, required this.delegate})
|
||||||
|
: _listener = GroupListener(group);
|
||||||
|
|
||||||
|
void startListening() {
|
||||||
|
_listener.start(onGroupChanged: (result) {
|
||||||
|
result.fold(
|
||||||
|
(GroupRowsChangesetPB changeset) {
|
||||||
|
for (final insertedRow in changeset.insertedRows) {
|
||||||
|
final index = insertedRow.hasIndex() ? insertedRow.index : null;
|
||||||
|
delegate.insertRow(
|
||||||
|
group.groupId,
|
||||||
|
insertedRow.row,
|
||||||
|
index,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final deletedRow in changeset.deletedRows) {
|
||||||
|
delegate.removeRow(group.groupId, deletedRow);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final updatedRow in changeset.updatedRows) {
|
||||||
|
delegate.updateRow(group.groupId, updatedRow);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(err) => Log.error(err),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> dispose() async {
|
||||||
|
_listener.stop();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:app_flowy/core/grid_notification.dart';
|
||||||
|
import 'package:flowy_infra/notifier.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_sdk/protobuf/flowy-grid/group.pb.dart';
|
||||||
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-grid/group_changeset.pb.dart';
|
||||||
|
|
||||||
|
typedef UpdateGroupNotifiedValue = Either<GroupRowsChangesetPB, FlowyError>;
|
||||||
|
|
||||||
|
class GroupListener {
|
||||||
|
final GroupPB group;
|
||||||
|
PublishNotifier<UpdateGroupNotifiedValue>? _groupNotifier = PublishNotifier();
|
||||||
|
GridNotificationListener? _listener;
|
||||||
|
GroupListener(this.group);
|
||||||
|
|
||||||
|
void start({
|
||||||
|
required void Function(UpdateGroupNotifiedValue) onGroupChanged,
|
||||||
|
}) {
|
||||||
|
_groupNotifier?.addPublishListener(onGroupChanged);
|
||||||
|
_listener = GridNotificationListener(
|
||||||
|
objectId: group.groupId,
|
||||||
|
handler: _handler,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _handler(
|
||||||
|
GridNotification ty,
|
||||||
|
Either<Uint8List, FlowyError> result,
|
||||||
|
) {
|
||||||
|
switch (ty) {
|
||||||
|
case GridNotification.DidUpdateGroup:
|
||||||
|
result.fold(
|
||||||
|
(payload) => _groupNotifier?.value =
|
||||||
|
left(GroupRowsChangesetPB.fromBuffer(payload)),
|
||||||
|
(error) => _groupNotifier?.value = right(error),
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> stop() async {
|
||||||
|
await _listener?.stop();
|
||||||
|
_groupNotifier?.dispose();
|
||||||
|
_groupNotifier = null;
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,20 @@
|
|||||||
// ignore_for_file: unused_field
|
// ignore_for_file: unused_field
|
||||||
|
|
||||||
|
import 'dart:collection';
|
||||||
|
|
||||||
import 'package:app_flowy/plugins/board/application/card/card_data_controller.dart';
|
import 'package:app_flowy/plugins/board/application/card/card_data_controller.dart';
|
||||||
|
import 'package:app_flowy/plugins/grid/application/row/row_cache.dart';
|
||||||
|
import 'package:app_flowy/plugins/grid/application/field/field_cache.dart';
|
||||||
|
import 'package:app_flowy/plugins/grid/application/row/row_data_controller.dart';
|
||||||
|
import 'package:app_flowy/plugins/grid/presentation/widgets/cell/cell_builder.dart';
|
||||||
|
import 'package:app_flowy/plugins/grid/presentation/widgets/row/row_detail.dart';
|
||||||
import 'package:appflowy_board/appflowy_board.dart';
|
import 'package:appflowy_board/appflowy_board.dart';
|
||||||
import 'package:flowy_infra_ui/widget/error_page.dart';
|
import 'package:flowy_infra_ui/widget/error_page.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-grid/block_entities.pb.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import '../../grid/application/row/row_cache.dart';
|
||||||
import '../application/board_bloc.dart';
|
import '../application/board_bloc.dart';
|
||||||
import 'card/card.dart';
|
import 'card/card.dart';
|
||||||
import 'card/card_cell_builder.dart';
|
import 'card/card_cell_builder.dart';
|
||||||
@ -55,7 +64,7 @@ class BoardContent extends StatelessWidget {
|
|||||||
child: AFBoard(
|
child: AFBoard(
|
||||||
// key: UniqueKey(),
|
// key: UniqueKey(),
|
||||||
scrollController: ScrollController(),
|
scrollController: ScrollController(),
|
||||||
dataController: context.read<BoardBloc>().boardDataController,
|
dataController: context.read<BoardBloc>().afBoardDataController,
|
||||||
headerBuilder: _buildHeader,
|
headerBuilder: _buildHeader,
|
||||||
footBuilder: _buildFooter,
|
footBuilder: _buildFooter,
|
||||||
cardBuilder: (_, data) => _buildCard(context, data),
|
cardBuilder: (_, data) => _buildCard(context, data),
|
||||||
@ -123,9 +132,36 @@ class BoardContent extends StatelessWidget {
|
|||||||
onEditEditing: (rowId) {
|
onEditEditing: (rowId) {
|
||||||
context.read<BoardBloc>().add(BoardEvent.endEditRow(rowId));
|
context.read<BoardBloc>().add(BoardEvent.endEditRow(rowId));
|
||||||
},
|
},
|
||||||
|
openCard: (context) => _openCard(
|
||||||
|
gridId,
|
||||||
|
fieldCache,
|
||||||
|
rowPB,
|
||||||
|
rowCache,
|
||||||
|
context,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _openCard(String gridId, GridFieldCache fieldCache, RowPB rowPB,
|
||||||
|
GridRowCache rowCache, BuildContext context) {
|
||||||
|
final rowInfo = RowInfo(
|
||||||
|
gridId: gridId,
|
||||||
|
fields: UnmodifiableListView(fieldCache.fields),
|
||||||
|
rowPB: rowPB,
|
||||||
|
);
|
||||||
|
|
||||||
|
final dataController = GridRowDataController(
|
||||||
|
rowInfo: rowInfo,
|
||||||
|
fieldCache: fieldCache,
|
||||||
|
rowCache: rowCache,
|
||||||
|
);
|
||||||
|
|
||||||
|
RowDetailPage(
|
||||||
|
cellBuilder: GridCellBuilder(delegate: dataController),
|
||||||
|
dataController: dataController,
|
||||||
|
).show(context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension HexColor on Color {
|
extension HexColor on Color {
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import 'package:app_flowy/plugins/board/application/card/card_bloc.dart';
|
import 'package:app_flowy/plugins/board/application/card/card_bloc.dart';
|
||||||
import 'package:app_flowy/plugins/board/application/card/card_data_controller.dart';
|
import 'package:app_flowy/plugins/board/application/card/card_data_controller.dart';
|
||||||
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
|
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
|
||||||
|
import 'package:app_flowy/plugins/grid/presentation/widgets/row/row_action_sheet.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
import 'package:flowy_infra/theme.dart';
|
import 'package:flowy_infra/theme.dart';
|
||||||
import 'package:flowy_sdk/log.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui_web.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'card_cell_builder.dart';
|
import 'card_cell_builder.dart';
|
||||||
@ -17,6 +18,7 @@ class BoardCard extends StatefulWidget {
|
|||||||
final CardDataController dataController;
|
final CardDataController dataController;
|
||||||
final BoardCellBuilder cellBuilder;
|
final BoardCellBuilder cellBuilder;
|
||||||
final OnEndEditing onEditEditing;
|
final OnEndEditing onEditEditing;
|
||||||
|
final void Function(BuildContext) openCard;
|
||||||
|
|
||||||
const BoardCard({
|
const BoardCard({
|
||||||
required this.gridId,
|
required this.gridId,
|
||||||
@ -24,6 +26,7 @@ class BoardCard extends StatefulWidget {
|
|||||||
required this.dataController,
|
required this.dataController,
|
||||||
required this.cellBuilder,
|
required this.cellBuilder,
|
||||||
required this.onEditEditing,
|
required this.onEditEditing,
|
||||||
|
required this.openCard,
|
||||||
Key? key,
|
Key? key,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@ -53,6 +56,9 @@ class _BoardCardState extends State<BoardCard> {
|
|||||||
accessoryBuilder: (context) {
|
accessoryBuilder: (context) {
|
||||||
return [const _CardMoreOption()];
|
return [const _CardMoreOption()];
|
||||||
},
|
},
|
||||||
|
onTap: (context) {
|
||||||
|
widget.openCard(context);
|
||||||
|
},
|
||||||
child: Column(
|
child: Column(
|
||||||
children: _makeCells(context, state.gridCellMap),
|
children: _makeCells(context, state.gridCellMap),
|
||||||
),
|
),
|
||||||
@ -85,6 +91,8 @@ class _CardMoreOption extends StatelessWidget with CardAccessory {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void onTap(BuildContext context) {
|
void onTap(BuildContext context) {
|
||||||
Log.debug('show options');
|
GridRowActionSheet(
|
||||||
|
rowData: context.read<BoardCardBloc>().rowInfo(),
|
||||||
|
).show(context, direction: AnchorDirection.bottomWithCenterAligned);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,10 @@ import 'package:styled_widget/styled_widget.dart';
|
|||||||
class BoardCardContainer extends StatelessWidget {
|
class BoardCardContainer extends StatelessWidget {
|
||||||
final Widget child;
|
final Widget child;
|
||||||
final CardAccessoryBuilder? accessoryBuilder;
|
final CardAccessoryBuilder? accessoryBuilder;
|
||||||
|
final void Function(BuildContext) onTap;
|
||||||
const BoardCardContainer({
|
const BoardCardContainer({
|
||||||
required this.child,
|
required this.child,
|
||||||
|
required this.onTap,
|
||||||
this.accessoryBuilder,
|
this.accessoryBuilder,
|
||||||
Key? key,
|
Key? key,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
@ -30,11 +32,14 @@ class BoardCardContainer extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Padding(
|
return GestureDetector(
|
||||||
padding: const EdgeInsets.all(8),
|
onTap: () => onTap(context),
|
||||||
child: ConstrainedBox(
|
child: Padding(
|
||||||
constraints: const BoxConstraints(minHeight: 30),
|
padding: const EdgeInsets.all(8),
|
||||||
child: container,
|
child: ConstrainedBox(
|
||||||
|
constraints: const BoxConstraints(minHeight: 30),
|
||||||
|
child: container,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -18,14 +18,13 @@ class FieldService {
|
|||||||
FieldService({required this.gridId, required this.fieldId});
|
FieldService({required this.gridId, required this.fieldId});
|
||||||
|
|
||||||
Future<Either<Unit, FlowyError>> moveField(int fromIndex, int toIndex) {
|
Future<Either<Unit, FlowyError>> moveField(int fromIndex, int toIndex) {
|
||||||
final payload = MoveItemPayloadPB.create()
|
final payload = MoveFieldPayloadPB.create()
|
||||||
..gridId = gridId
|
..gridId = gridId
|
||||||
..itemId = fieldId
|
..fieldId = fieldId
|
||||||
..ty = MoveItemTypePB.MoveField
|
|
||||||
..fromIndex = fromIndex
|
..fromIndex = fromIndex
|
||||||
..toIndex = toIndex;
|
..toIndex = toIndex;
|
||||||
|
|
||||||
return GridEventMoveItem(payload).send();
|
return GridEventMoveField(payload).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Either<Unit, FlowyError>> updateField({
|
Future<Either<Unit, FlowyError>> updateField({
|
||||||
|
@ -23,9 +23,9 @@ class GridFFIService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<Either<RowPB, FlowyError>> createRow({Option<String>? startRowId}) {
|
Future<Either<RowPB, FlowyError>> createRow({Option<String>? startRowId}) {
|
||||||
CreateRowPayloadPB payload = CreateRowPayloadPB.create()..gridId = gridId;
|
var payload = CreateTableRowPayloadPB.create()..gridId = gridId;
|
||||||
startRowId?.fold(() => null, (id) => payload.startRowId = id);
|
startRowId?.fold(() => null, (id) => payload.startRowId = id);
|
||||||
return GridEventCreateRow(payload).send();
|
return GridEventCreateTableRow(payload).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Either<RowPB, FlowyError>> createBoardCard(String groupId) {
|
Future<Either<RowPB, FlowyError>> createBoardCard(String groupId) {
|
||||||
|
@ -17,19 +17,19 @@ class RowActionSheetBloc
|
|||||||
RowActionSheetBloc({required RowInfo rowInfo})
|
RowActionSheetBloc({required RowInfo rowInfo})
|
||||||
: _rowService = RowFFIService(
|
: _rowService = RowFFIService(
|
||||||
gridId: rowInfo.gridId,
|
gridId: rowInfo.gridId,
|
||||||
blockId: rowInfo.blockId,
|
blockId: rowInfo.rowPB.blockId,
|
||||||
rowId: rowInfo.rowPB.id,
|
|
||||||
),
|
),
|
||||||
super(RowActionSheetState.initial(rowInfo)) {
|
super(RowActionSheetState.initial(rowInfo)) {
|
||||||
on<RowActionSheetEvent>(
|
on<RowActionSheetEvent>(
|
||||||
(event, emit) async {
|
(event, emit) async {
|
||||||
await event.map(
|
await event.map(
|
||||||
deleteRow: (_DeleteRow value) async {
|
deleteRow: (_DeleteRow value) async {
|
||||||
final result = await _rowService.deleteRow();
|
final result = await _rowService.deleteRow(state.rowData.rowPB.id);
|
||||||
logResult(result);
|
logResult(result);
|
||||||
},
|
},
|
||||||
duplicateRow: (_DuplicateRow value) async {
|
duplicateRow: (_DuplicateRow value) async {
|
||||||
final result = await _rowService.duplicateRow();
|
final result =
|
||||||
|
await _rowService.duplicateRow(state.rowData.rowPB.id);
|
||||||
logResult(result);
|
logResult(result);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -20,8 +20,7 @@ class RowBloc extends Bloc<RowEvent, RowState> {
|
|||||||
required GridRowDataController dataController,
|
required GridRowDataController dataController,
|
||||||
}) : _rowService = RowFFIService(
|
}) : _rowService = RowFFIService(
|
||||||
gridId: rowInfo.gridId,
|
gridId: rowInfo.gridId,
|
||||||
blockId: rowInfo.blockId,
|
blockId: rowInfo.rowPB.blockId,
|
||||||
rowId: rowInfo.rowPB.id,
|
|
||||||
),
|
),
|
||||||
_dataController = dataController,
|
_dataController = dataController,
|
||||||
super(RowState.initial(rowInfo, dataController.loadData())) {
|
super(RowState.initial(rowInfo, dataController.loadData())) {
|
||||||
@ -32,7 +31,7 @@ class RowBloc extends Bloc<RowEvent, RowState> {
|
|||||||
await _startListening();
|
await _startListening();
|
||||||
},
|
},
|
||||||
createRow: (_CreateRow value) {
|
createRow: (_CreateRow value) {
|
||||||
_rowService.createRow();
|
_rowService.createRow(rowInfo.rowPB.id);
|
||||||
},
|
},
|
||||||
didReceiveCells: (_DidReceiveCells value) async {
|
didReceiveCells: (_DidReceiveCells value) async {
|
||||||
final cells = value.gridCellMap.values
|
final cells = value.gridCellMap.values
|
||||||
|
@ -255,7 +255,6 @@ class GridRowCache {
|
|||||||
RowInfo buildGridRow(RowPB rowPB) {
|
RowInfo buildGridRow(RowPB rowPB) {
|
||||||
return RowInfo(
|
return RowInfo(
|
||||||
gridId: gridId,
|
gridId: gridId,
|
||||||
blockId: block.id,
|
|
||||||
fields: _fieldNotifier.fields,
|
fields: _fieldNotifier.fields,
|
||||||
rowPB: rowPB,
|
rowPB: rowPB,
|
||||||
);
|
);
|
||||||
@ -283,7 +282,6 @@ class _RowChangesetNotifier extends ChangeNotifier {
|
|||||||
class RowInfo with _$RowInfo {
|
class RowInfo with _$RowInfo {
|
||||||
const factory RowInfo({
|
const factory RowInfo({
|
||||||
required String gridId,
|
required String gridId,
|
||||||
required String blockId,
|
|
||||||
required UnmodifiableListView<FieldPB> fields,
|
required UnmodifiableListView<FieldPB> fields,
|
||||||
required RowPB rowPB,
|
required RowPB rowPB,
|
||||||
}) = _RowInfo;
|
}) = _RowInfo;
|
||||||
|
@ -4,36 +4,47 @@ import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
|||||||
import 'package:flowy_sdk/protobuf/flowy-grid/block_entities.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/block_entities.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/grid_entities.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/grid_entities.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:flowy_sdk/protobuf/flowy-grid/setting_entities.pb.dart';
|
||||||
|
|
||||||
class RowFFIService {
|
class RowFFIService {
|
||||||
final String gridId;
|
final String gridId;
|
||||||
final String blockId;
|
final String blockId;
|
||||||
final String rowId;
|
|
||||||
|
|
||||||
RowFFIService(
|
RowFFIService({
|
||||||
{required this.gridId, required this.blockId, required this.rowId});
|
required this.gridId,
|
||||||
|
required this.blockId,
|
||||||
|
});
|
||||||
|
|
||||||
Future<Either<RowPB, FlowyError>> createRow() {
|
Future<Either<RowPB, FlowyError>> createRow(String rowId) {
|
||||||
CreateRowPayloadPB payload = CreateRowPayloadPB.create()
|
final payload = CreateTableRowPayloadPB.create()
|
||||||
..gridId = gridId
|
..gridId = gridId
|
||||||
..startRowId = rowId;
|
..startRowId = rowId;
|
||||||
|
|
||||||
return GridEventCreateRow(payload).send();
|
return GridEventCreateTableRow(payload).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Either<Unit, FlowyError>> moveRow(
|
Future<Either<Unit, FlowyError>> moveRow({
|
||||||
String rowId, int fromIndex, int toIndex) {
|
required String rowId,
|
||||||
final payload = MoveItemPayloadPB.create()
|
required int fromIndex,
|
||||||
..gridId = gridId
|
required int toIndex,
|
||||||
..itemId = rowId
|
required GridLayout layout,
|
||||||
..ty = MoveItemTypePB.MoveRow
|
String? upperRowId,
|
||||||
|
}) {
|
||||||
|
var payload = MoveRowPayloadPB.create()
|
||||||
|
..viewId = gridId
|
||||||
|
..rowId = rowId
|
||||||
|
..layout = layout
|
||||||
..fromIndex = fromIndex
|
..fromIndex = fromIndex
|
||||||
..toIndex = toIndex;
|
..toIndex = toIndex;
|
||||||
|
|
||||||
return GridEventMoveItem(payload).send();
|
if (upperRowId != null) {
|
||||||
|
payload.upperRowId = upperRowId;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GridEventMoveRow(payload).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Either<OptionalRowPB, FlowyError>> getRow() {
|
Future<Either<OptionalRowPB, FlowyError>> getRow(String rowId) {
|
||||||
final payload = RowIdPB.create()
|
final payload = RowIdPB.create()
|
||||||
..gridId = gridId
|
..gridId = gridId
|
||||||
..blockId = blockId
|
..blockId = blockId
|
||||||
@ -42,7 +53,7 @@ class RowFFIService {
|
|||||||
return GridEventGetRow(payload).send();
|
return GridEventGetRow(payload).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Either<Unit, FlowyError>> deleteRow() {
|
Future<Either<Unit, FlowyError>> deleteRow(String rowId) {
|
||||||
final payload = RowIdPB.create()
|
final payload = RowIdPB.create()
|
||||||
..gridId = gridId
|
..gridId = gridId
|
||||||
..blockId = blockId
|
..blockId = blockId
|
||||||
@ -51,7 +62,7 @@ class RowFFIService {
|
|||||||
return GridEventDeleteRow(payload).send();
|
return GridEventDeleteRow(payload).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Either<Unit, FlowyError>> duplicateRow() {
|
Future<Either<Unit, FlowyError>> duplicateRow(String rowId) {
|
||||||
final payload = RowIdPB.create()
|
final payload = RowIdPB.create()
|
||||||
..gridId = gridId
|
..gridId = gridId
|
||||||
..blockId = blockId
|
..blockId = blockId
|
||||||
|
@ -239,8 +239,10 @@ class _GridRowsState extends State<_GridRows> {
|
|||||||
RowInfo rowInfo,
|
RowInfo rowInfo,
|
||||||
Animation<double> animation,
|
Animation<double> animation,
|
||||||
) {
|
) {
|
||||||
final rowCache =
|
final rowCache = context.read<GridBloc>().getRowCache(
|
||||||
context.read<GridBloc>().getRowCache(rowInfo.blockId, rowInfo.rowPB.id);
|
rowInfo.rowPB.blockId,
|
||||||
|
rowInfo.rowPB.id,
|
||||||
|
);
|
||||||
|
|
||||||
/// Return placeholder widget if the rowCache is null.
|
/// Return placeholder widget if the rowCache is null.
|
||||||
if (rowCache == null) return const SizedBox();
|
if (rowCache == null) return const SizedBox();
|
||||||
|
@ -53,7 +53,10 @@ class GridRowActionSheet extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void show(BuildContext overlayContext) {
|
void show(
|
||||||
|
BuildContext overlayContext, {
|
||||||
|
AnchorDirection direction = AnchorDirection.leftWithCenterAligned,
|
||||||
|
}) {
|
||||||
FlowyOverlay.of(overlayContext).insertWithAnchor(
|
FlowyOverlay.of(overlayContext).insertWithAnchor(
|
||||||
widget: OverlayContainer(
|
widget: OverlayContainer(
|
||||||
child: this,
|
child: this,
|
||||||
@ -61,7 +64,7 @@ class GridRowActionSheet extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
identifier: GridRowActionSheet.identifier(),
|
identifier: GridRowActionSheet.identifier(),
|
||||||
anchorContext: overlayContext,
|
anchorContext: overlayContext,
|
||||||
anchorDirection: AnchorDirection.leftWithCenterAligned,
|
anchorDirection: direction,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ import 'package:provider/provider.dart';
|
|||||||
import 'board_column/board_column.dart';
|
import 'board_column/board_column.dart';
|
||||||
import 'board_column/board_column_data.dart';
|
import 'board_column/board_column_data.dart';
|
||||||
import 'board_data.dart';
|
import 'board_data.dart';
|
||||||
import 'reorder_flex/drag_target_inteceptor.dart';
|
import 'reorder_flex/drag_target_interceptor.dart';
|
||||||
import 'reorder_flex/reorder_flex.dart';
|
import 'reorder_flex/reorder_flex.dart';
|
||||||
import 'reorder_phantom/phantom_controller.dart';
|
import 'reorder_phantom/phantom_controller.dart';
|
||||||
import '../rendering/board_overlay.dart';
|
import '../rendering/board_overlay.dart';
|
||||||
@ -143,7 +143,7 @@ class _BoardContentState extends State<BoardContent> {
|
|||||||
void initState() {
|
void initState() {
|
||||||
_overlayEntry = BoardOverlayEntry(
|
_overlayEntry = BoardOverlayEntry(
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
final interceptor = OverlappingDragTargetInteceptor(
|
final interceptor = OverlappingDragTargetInterceptor(
|
||||||
reorderFlexId: widget.dataController.identifier,
|
reorderFlexId: widget.dataController.identifier,
|
||||||
acceptedReorderFlexId: widget.dataController.columnIds,
|
acceptedReorderFlexId: widget.dataController.columnIds,
|
||||||
delegate: widget.delegate,
|
delegate: widget.delegate,
|
||||||
|
@ -5,7 +5,7 @@ import '../../rendering/board_overlay.dart';
|
|||||||
import '../../utils/log.dart';
|
import '../../utils/log.dart';
|
||||||
import '../reorder_phantom/phantom_controller.dart';
|
import '../reorder_phantom/phantom_controller.dart';
|
||||||
import '../reorder_flex/reorder_flex.dart';
|
import '../reorder_flex/reorder_flex.dart';
|
||||||
import '../reorder_flex/drag_target_inteceptor.dart';
|
import '../reorder_flex/drag_target_interceptor.dart';
|
||||||
import 'board_column_data.dart';
|
import 'board_column_data.dart';
|
||||||
|
|
||||||
typedef OnColumnDragStarted = void Function(int index);
|
typedef OnColumnDragStarted = void Function(int index);
|
||||||
@ -37,7 +37,7 @@ typedef AFBoardColumnFooterBuilder = Widget Function(
|
|||||||
AFBoardColumnData columnData,
|
AFBoardColumnData columnData,
|
||||||
);
|
);
|
||||||
|
|
||||||
abstract class AFBoardColumnDataDataSource extends ReoderFlextDataSource {
|
abstract class AFBoardColumnDataDataSource extends ReoderFlexDataSource {
|
||||||
AFBoardColumnData get columnData;
|
AFBoardColumnData get columnData;
|
||||||
|
|
||||||
List<String> get acceptedColumnIds;
|
List<String> get acceptedColumnIds;
|
||||||
|
@ -51,8 +51,11 @@ class AFBoardColumnDataController extends ChangeNotifier with EquatableMixin {
|
|||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
int removeWhere(bool Function(AFColumnItem) condition) {
|
void removeWhere(bool Function(AFColumnItem) condition) {
|
||||||
return items.indexWhere(condition);
|
final index = items.indexWhere(condition);
|
||||||
|
if (index != -1) {
|
||||||
|
removeAt(index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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
|
||||||
|
@ -24,7 +24,7 @@ typedef OnMoveColumnItemToColumn = void Function(
|
|||||||
);
|
);
|
||||||
|
|
||||||
class AFBoardDataController extends ChangeNotifier
|
class AFBoardDataController extends ChangeNotifier
|
||||||
with EquatableMixin, BoardPhantomControllerDelegate, ReoderFlextDataSource {
|
with EquatableMixin, BoardPhantomControllerDelegate, ReoderFlexDataSource {
|
||||||
final List<AFBoardColumnData> _columnDatas = [];
|
final List<AFBoardColumnData> _columnDatas = [];
|
||||||
final OnMoveColumn? onMoveColumn;
|
final OnMoveColumn? onMoveColumn;
|
||||||
final OnMoveColumnItem? onMoveColumnItem;
|
final OnMoveColumnItem? onMoveColumnItem;
|
||||||
|
@ -13,14 +13,14 @@ abstract class ReorderFlexDraggableTargetBuilder {
|
|||||||
Widget child,
|
Widget child,
|
||||||
DragTargetOnStarted onDragStarted,
|
DragTargetOnStarted onDragStarted,
|
||||||
DragTargetOnEnded<T> onDragEnded,
|
DragTargetOnEnded<T> onDragEnded,
|
||||||
DragTargetWillAccpet<T> onWillAccept,
|
DragTargetWillAccepted<T> onWillAccept,
|
||||||
AnimationController insertAnimationController,
|
AnimationController insertAnimationController,
|
||||||
AnimationController deleteAnimationController,
|
AnimationController deleteAnimationController,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
typedef DragTargetWillAccpet<T extends DragTargetData> = bool Function(
|
typedef DragTargetWillAccepted<T extends DragTargetData> = bool Function(
|
||||||
T dragTargetData);
|
T dragTargetData);
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -51,7 +51,7 @@ class ReorderDragTarget<T extends DragTargetData> extends StatefulWidget {
|
|||||||
///
|
///
|
||||||
/// [toAccept] represents the dragTarget index, which is the value passed in
|
/// [toAccept] represents the dragTarget index, which is the value passed in
|
||||||
/// when creating the [ReorderDragTarget].
|
/// when creating the [ReorderDragTarget].
|
||||||
final DragTargetWillAccpet<T> onWillAccept;
|
final DragTargetWillAccepted<T> onWillAccept;
|
||||||
|
|
||||||
/// Called when an acceptable piece of data was dropped over this drag target.
|
/// Called when an acceptable piece of data was dropped over this drag target.
|
||||||
///
|
///
|
||||||
@ -228,7 +228,7 @@ class DragTargetAnimation {
|
|||||||
value: 0.0, vsync: vsync, duration: const Duration(milliseconds: 10));
|
value: 0.0, vsync: vsync, duration: const Duration(milliseconds: 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
void startDargging() {
|
void startDragging() {
|
||||||
entranceController.value = 1.0;
|
entranceController.value = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -386,7 +386,7 @@ class FakeDragTarget<T extends DragTargetData> extends StatefulWidget {
|
|||||||
final FakeDragTargetEventData eventData;
|
final FakeDragTargetEventData eventData;
|
||||||
final DragTargetOnStarted onDragStarted;
|
final DragTargetOnStarted onDragStarted;
|
||||||
final DragTargetOnEnded<T> onDragEnded;
|
final DragTargetOnEnded<T> onDragEnded;
|
||||||
final DragTargetWillAccpet<T> onWillAccept;
|
final DragTargetWillAccepted<T> onWillAccept;
|
||||||
final Widget child;
|
final Widget child;
|
||||||
final AnimationController insertAnimationController;
|
final AnimationController insertAnimationController;
|
||||||
final AnimationController deleteAnimationController;
|
final AnimationController deleteAnimationController;
|
||||||
|
@ -40,18 +40,18 @@ abstract class OverlapDragTargetDelegate {
|
|||||||
bool canMoveTo(String dragTargetId);
|
bool canMoveTo(String dragTargetId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [OverlappingDragTargetInteceptor] is used to receive the overlapping
|
/// [OverlappingDragTargetInterceptor] is used to receive the overlapping
|
||||||
/// [DragTarget] event. If a [DragTarget] child is [DragTarget], it will
|
/// [DragTarget] event. If a [DragTarget] child is [DragTarget], it will
|
||||||
/// receive the [DragTarget] event when being dragged.
|
/// receive the [DragTarget] event when being dragged.
|
||||||
///
|
///
|
||||||
/// Receive the [DragTarget] event if the [acceptedReorderFlexId] contains
|
/// Receive the [DragTarget] event if the [acceptedReorderFlexId] contains
|
||||||
/// the passed in dragTarget' reorderFlexId.
|
/// the passed in dragTarget' reorderFlexId.
|
||||||
class OverlappingDragTargetInteceptor extends DragTargetInterceptor {
|
class OverlappingDragTargetInterceptor extends DragTargetInterceptor {
|
||||||
final String reorderFlexId;
|
final String reorderFlexId;
|
||||||
final List<String> acceptedReorderFlexId;
|
final List<String> acceptedReorderFlexId;
|
||||||
final OverlapDragTargetDelegate delegate;
|
final OverlapDragTargetDelegate delegate;
|
||||||
|
|
||||||
OverlappingDragTargetInteceptor({
|
OverlappingDragTargetInterceptor({
|
||||||
required this.delegate,
|
required this.delegate,
|
||||||
required this.reorderFlexId,
|
required this.reorderFlexId,
|
||||||
required this.acceptedReorderFlexId,
|
required this.acceptedReorderFlexId,
|
@ -7,25 +7,25 @@ import '../../utils/log.dart';
|
|||||||
import 'reorder_mixin.dart';
|
import 'reorder_mixin.dart';
|
||||||
import 'drag_target.dart';
|
import 'drag_target.dart';
|
||||||
import 'drag_state.dart';
|
import 'drag_state.dart';
|
||||||
import 'drag_target_inteceptor.dart';
|
import 'drag_target_interceptor.dart';
|
||||||
|
|
||||||
typedef OnDragStarted = void Function(int index);
|
typedef OnDragStarted = void Function(int index);
|
||||||
typedef OnDragEnded = void Function();
|
typedef OnDragEnded = void Function();
|
||||||
typedef OnReorder = void Function(int fromIndex, int toIndex);
|
typedef OnReorder = void Function(int fromIndex, int toIndex);
|
||||||
typedef OnDeleted = void Function(int deletedIndex);
|
typedef OnDeleted = void Function(int deletedIndex);
|
||||||
typedef OnInserted = void Function(int insertedIndex);
|
typedef OnInserted = void Function(int insertedIndex);
|
||||||
typedef OnReveivePassedInPhantom = void Function(
|
typedef OnReceivePassedInPhantom = void Function(
|
||||||
FlexDragTargetData dragTargetData, int phantomIndex);
|
FlexDragTargetData dragTargetData, int phantomIndex);
|
||||||
|
|
||||||
abstract class ReoderFlextDataSource {
|
abstract class ReoderFlexDataSource {
|
||||||
/// [identifier] represents the id the [ReorderFlex]. It must be unique.
|
/// [identifier] represents the id the [ReorderFlex]. It must be unique.
|
||||||
String get identifier;
|
String get identifier;
|
||||||
|
|
||||||
/// The number of [ReoderFlexItem]s will be displaied in the [ReorderFlex].
|
/// The number of [ReoderFlexItem]s will be displayed in the [ReorderFlex].
|
||||||
UnmodifiableListView<ReoderFlexItem> get items;
|
UnmodifiableListView<ReoderFlexItem> get items;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Each item displaied in the [ReorderFlex] required to implement the [ReoderFlexItem].
|
/// Each item displayed in the [ReorderFlex] required to implement the [ReoderFlexItem].
|
||||||
abstract class ReoderFlexItem {
|
abstract class ReoderFlexItem {
|
||||||
/// [id] is used to identify the item. It must be unique.
|
/// [id] is used to identify the item. It must be unique.
|
||||||
String get id;
|
String get id;
|
||||||
@ -70,7 +70,7 @@ class ReorderFlex extends StatefulWidget {
|
|||||||
/// [onDragEnded] is called when dragTarget did end dragging
|
/// [onDragEnded] is called when dragTarget did end dragging
|
||||||
final OnDragEnded? onDragEnded;
|
final OnDragEnded? onDragEnded;
|
||||||
|
|
||||||
final ReoderFlextDataSource dataSource;
|
final ReoderFlexDataSource dataSource;
|
||||||
|
|
||||||
final DragTargetInterceptor? interceptor;
|
final DragTargetInterceptor? interceptor;
|
||||||
|
|
||||||
@ -187,7 +187,7 @@ class ReorderFlexState extends State<ReorderFlex>
|
|||||||
void _requestAnimationToNextIndex({bool isAcceptingNewTarget = false}) {
|
void _requestAnimationToNextIndex({bool isAcceptingNewTarget = false}) {
|
||||||
/// Update the dragState and animate to the next index if the current
|
/// Update the dragState and animate to the next index if the current
|
||||||
/// dragging animation is completed. Otherwise, it will get called again
|
/// dragging animation is completed. Otherwise, it will get called again
|
||||||
/// when the animation finishs.
|
/// when the animation finish.
|
||||||
|
|
||||||
if (_animation.entranceController.isCompleted) {
|
if (_animation.entranceController.isCompleted) {
|
||||||
dragState.removePhantom();
|
dragState.removePhantom();
|
||||||
@ -425,7 +425,7 @@ class ReorderFlexState extends State<ReorderFlex>
|
|||||||
) {
|
) {
|
||||||
setState(() {
|
setState(() {
|
||||||
dragState.startDragging(draggingWidget, dragIndex, feedbackSize);
|
dragState.startDragging(draggingWidget, dragIndex, feedbackSize);
|
||||||
_animation.startDargging();
|
_animation.startDragging();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
import '../../utils/log.dart';
|
import '../../utils/log.dart';
|
||||||
import '../board_column/board_column_data.dart';
|
import '../board_column/board_column_data.dart';
|
||||||
import '../reorder_flex/drag_state.dart';
|
import '../reorder_flex/drag_state.dart';
|
||||||
import '../reorder_flex/drag_target.dart';
|
import '../reorder_flex/drag_target.dart';
|
||||||
import '../reorder_flex/drag_target_inteceptor.dart';
|
import '../reorder_flex/drag_target_interceptor.dart';
|
||||||
import 'phantom_state.dart';
|
import 'phantom_state.dart';
|
||||||
|
|
||||||
abstract class BoardPhantomControllerDelegate {
|
abstract class BoardPhantomControllerDelegate {
|
||||||
@ -61,7 +62,7 @@ class BoardPhantomController extends OverlapDragTargetDelegate
|
|||||||
columnsState.setColumnIsDragging(columnId, false);
|
columnsState.setColumnIsDragging(columnId, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove the phanton in the column when the column is end dragging.
|
/// Remove the phantom in the column when the column is end dragging.
|
||||||
void columnEndDragging(String columnId) {
|
void columnEndDragging(String columnId) {
|
||||||
columnsState.setColumnIsDragging(columnId, true);
|
columnsState.setColumnIsDragging(columnId, true);
|
||||||
if (phantomRecord == null) return;
|
if (phantomRecord == null) return;
|
||||||
@ -331,7 +332,7 @@ class PhantomDraggableBuilder extends ReorderFlexDraggableTargetBuilder {
|
|||||||
Widget child,
|
Widget child,
|
||||||
DragTargetOnStarted onDragStarted,
|
DragTargetOnStarted onDragStarted,
|
||||||
DragTargetOnEnded<T> onDragEnded,
|
DragTargetOnEnded<T> onDragEnded,
|
||||||
DragTargetWillAccpet<T> onWillAccept,
|
DragTargetWillAccepted<T> onWillAccept,
|
||||||
AnimationController insertAnimationController,
|
AnimationController insertAnimationController,
|
||||||
AnimationController deleteAnimationController,
|
AnimationController deleteAnimationController,
|
||||||
) {
|
) {
|
||||||
|
@ -11,7 +11,7 @@ pub enum GridNotification {
|
|||||||
DidUpdateRow = 30,
|
DidUpdateRow = 30,
|
||||||
DidUpdateCell = 40,
|
DidUpdateCell = 40,
|
||||||
DidUpdateField = 50,
|
DidUpdateField = 50,
|
||||||
DidUpdateBoard = 60,
|
DidUpdateGroup = 60,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::default::Default for GridNotification {
|
impl std::default::Default for GridNotification {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::entities::{BlockPB, FieldIdPB};
|
use crate::entities::{BlockPB, FieldIdPB, GridLayout};
|
||||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
use flowy_derive::ProtoBuf;
|
||||||
use flowy_error::ErrorCode;
|
use flowy_error::ErrorCode;
|
||||||
use flowy_grid_data_model::parser::NotEmptyStr;
|
use flowy_grid_data_model::parser::NotEmptyStr;
|
||||||
|
|
||||||
@ -52,25 +52,51 @@ impl std::convert::From<&str> for GridBlockIdPB {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, ProtoBuf_Enum)]
|
|
||||||
pub enum MoveItemTypePB {
|
|
||||||
MoveField = 0,
|
|
||||||
MoveRow = 1,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::default::Default for MoveItemTypePB {
|
|
||||||
fn default() -> Self {
|
|
||||||
MoveItemTypePB::MoveField
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, ProtoBuf)]
|
#[derive(Debug, Clone, Default, ProtoBuf)]
|
||||||
pub struct MoveItemPayloadPB {
|
pub struct MoveFieldPayloadPB {
|
||||||
#[pb(index = 1)]
|
#[pb(index = 1)]
|
||||||
pub grid_id: String,
|
pub grid_id: String,
|
||||||
|
|
||||||
#[pb(index = 2)]
|
#[pb(index = 2)]
|
||||||
pub item_id: String,
|
pub field_id: String,
|
||||||
|
|
||||||
|
#[pb(index = 3)]
|
||||||
|
pub from_index: i32,
|
||||||
|
|
||||||
|
#[pb(index = 4)]
|
||||||
|
pub to_index: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct MoveFieldParams {
|
||||||
|
pub grid_id: String,
|
||||||
|
pub field_id: String,
|
||||||
|
pub from_index: i32,
|
||||||
|
pub to_index: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryInto<MoveFieldParams> for MoveFieldPayloadPB {
|
||||||
|
type Error = ErrorCode;
|
||||||
|
|
||||||
|
fn try_into(self) -> Result<MoveFieldParams, Self::Error> {
|
||||||
|
let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
|
||||||
|
let item_id = NotEmptyStr::parse(self.field_id).map_err(|_| ErrorCode::InvalidData)?;
|
||||||
|
Ok(MoveFieldParams {
|
||||||
|
grid_id: grid_id.0,
|
||||||
|
field_id: item_id.0,
|
||||||
|
from_index: self.from_index,
|
||||||
|
to_index: self.to_index,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, ProtoBuf)]
|
||||||
|
pub struct MoveRowPayloadPB {
|
||||||
|
#[pb(index = 1)]
|
||||||
|
pub view_id: String,
|
||||||
|
|
||||||
|
#[pb(index = 2)]
|
||||||
|
pub row_id: String,
|
||||||
|
|
||||||
#[pb(index = 3)]
|
#[pb(index = 3)]
|
||||||
pub from_index: i32,
|
pub from_index: i32,
|
||||||
@ -79,30 +105,38 @@ pub struct MoveItemPayloadPB {
|
|||||||
pub to_index: i32,
|
pub to_index: i32,
|
||||||
|
|
||||||
#[pb(index = 5)]
|
#[pb(index = 5)]
|
||||||
pub ty: MoveItemTypePB,
|
pub layout: GridLayout,
|
||||||
|
|
||||||
|
#[pb(index = 6, one_of)]
|
||||||
|
pub upper_row_id: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
pub struct MoveRowParams {
|
||||||
pub struct MoveItemParams {
|
pub view_id: String,
|
||||||
pub grid_id: String,
|
pub row_id: String,
|
||||||
pub item_id: String,
|
|
||||||
pub from_index: i32,
|
pub from_index: i32,
|
||||||
pub to_index: i32,
|
pub to_index: i32,
|
||||||
pub ty: MoveItemTypePB,
|
pub layout: GridLayout,
|
||||||
|
pub upper_row_id: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryInto<MoveItemParams> for MoveItemPayloadPB {
|
impl TryInto<MoveRowParams> for MoveRowPayloadPB {
|
||||||
type Error = ErrorCode;
|
type Error = ErrorCode;
|
||||||
|
|
||||||
fn try_into(self) -> Result<MoveItemParams, Self::Error> {
|
fn try_into(self) -> Result<MoveRowParams, Self::Error> {
|
||||||
let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
|
let view_id = NotEmptyStr::parse(self.view_id).map_err(|_| ErrorCode::GridViewIdIsEmpty)?;
|
||||||
let item_id = NotEmptyStr::parse(self.item_id).map_err(|_| ErrorCode::InvalidData)?;
|
let row_id = NotEmptyStr::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?;
|
||||||
Ok(MoveItemParams {
|
let upper_row_id = match self.upper_row_id {
|
||||||
grid_id: grid_id.0,
|
None => None,
|
||||||
item_id: item_id.0,
|
Some(upper_row_id) => Some(NotEmptyStr::parse(upper_row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?.0),
|
||||||
|
};
|
||||||
|
Ok(MoveRowParams {
|
||||||
|
view_id: view_id.0,
|
||||||
|
row_id: row_id.0,
|
||||||
from_index: self.from_index,
|
from_index: self.from_index,
|
||||||
to_index: self.to_index,
|
to_index: self.to_index,
|
||||||
ty: self.ty,
|
layout: self.layout,
|
||||||
|
upper_row_id,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::entities::{CreateRowParams, RowPB};
|
use crate::entities::{CreateRowParams, GridLayout};
|
||||||
use flowy_derive::ProtoBuf;
|
use flowy_derive::ProtoBuf;
|
||||||
use flowy_error::ErrorCode;
|
use flowy_error::ErrorCode;
|
||||||
use flowy_grid_data_model::parser::NotEmptyStr;
|
use flowy_grid_data_model::parser::NotEmptyStr;
|
||||||
@ -22,46 +22,7 @@ impl TryInto<CreateRowParams> for CreateBoardCardPayloadPB {
|
|||||||
grid_id: grid_id.0,
|
grid_id: grid_id.0,
|
||||||
start_row_id: None,
|
start_row_id: None,
|
||||||
group_id: Some(group_id.0),
|
group_id: Some(group_id.0),
|
||||||
|
layout: GridLayout::Board,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, ProtoBuf)]
|
|
||||||
pub struct BoardCardChangesetPB {
|
|
||||||
#[pb(index = 1)]
|
|
||||||
pub group_id: String,
|
|
||||||
|
|
||||||
#[pb(index = 2)]
|
|
||||||
pub inserted_cards: Vec<RowPB>,
|
|
||||||
|
|
||||||
#[pb(index = 3)]
|
|
||||||
pub deleted_cards: Vec<String>,
|
|
||||||
|
|
||||||
#[pb(index = 4)]
|
|
||||||
pub updated_cards: Vec<RowPB>,
|
|
||||||
}
|
|
||||||
impl BoardCardChangesetPB {
|
|
||||||
pub fn insert(group_id: String, inserted_cards: Vec<RowPB>) -> Self {
|
|
||||||
Self {
|
|
||||||
group_id,
|
|
||||||
inserted_cards,
|
|
||||||
..Default::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn delete(group_id: String, deleted_cards: Vec<String>) -> Self {
|
|
||||||
Self {
|
|
||||||
group_id,
|
|
||||||
deleted_cards,
|
|
||||||
..Default::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn update(group_id: String, updated_cards: Vec<RowPB>) -> Self {
|
|
||||||
Self {
|
|
||||||
group_id,
|
|
||||||
updated_cards,
|
|
||||||
..Default::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
use crate::entities::{InsertedRowPB, RowPB};
|
||||||
|
use flowy_derive::ProtoBuf;
|
||||||
|
|
||||||
|
#[derive(Debug, Default, ProtoBuf)]
|
||||||
|
pub struct GroupRowsChangesetPB {
|
||||||
|
#[pb(index = 1)]
|
||||||
|
pub group_id: String,
|
||||||
|
|
||||||
|
#[pb(index = 2)]
|
||||||
|
pub inserted_rows: Vec<InsertedRowPB>,
|
||||||
|
|
||||||
|
#[pb(index = 3)]
|
||||||
|
pub deleted_rows: Vec<String>,
|
||||||
|
|
||||||
|
#[pb(index = 4)]
|
||||||
|
pub updated_rows: Vec<RowPB>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GroupRowsChangesetPB {
|
||||||
|
pub fn insert(group_id: String, inserted_rows: Vec<InsertedRowPB>) -> Self {
|
||||||
|
Self {
|
||||||
|
group_id,
|
||||||
|
inserted_rows,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn delete(group_id: String, deleted_rows: Vec<String>) -> Self {
|
||||||
|
Self {
|
||||||
|
group_id,
|
||||||
|
deleted_rows,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update(group_id: String, updated_rows: Vec<RowPB>) -> Self {
|
||||||
|
Self {
|
||||||
|
group_id,
|
||||||
|
updated_rows,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,9 @@
|
|||||||
mod board_card;
|
mod board_card;
|
||||||
mod configuration;
|
mod configuration;
|
||||||
mod group;
|
mod group;
|
||||||
|
mod group_changeset;
|
||||||
|
|
||||||
pub use board_card::*;
|
pub use board_card::*;
|
||||||
pub use configuration::*;
|
pub use configuration::*;
|
||||||
pub use group::*;
|
pub use group::*;
|
||||||
|
pub use group_changeset::*;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use crate::entities::GridLayout;
|
||||||
use flowy_derive::ProtoBuf;
|
use flowy_derive::ProtoBuf;
|
||||||
use flowy_error::ErrorCode;
|
use flowy_error::ErrorCode;
|
||||||
use flowy_grid_data_model::parser::NotEmptyStr;
|
use flowy_grid_data_model::parser::NotEmptyStr;
|
||||||
@ -46,7 +47,7 @@ pub struct BlockRowIdPB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(ProtoBuf, Default)]
|
#[derive(ProtoBuf, Default)]
|
||||||
pub struct CreateRowPayloadPB {
|
pub struct CreateTableRowPayloadPB {
|
||||||
#[pb(index = 1)]
|
#[pb(index = 1)]
|
||||||
pub grid_id: String,
|
pub grid_id: String,
|
||||||
|
|
||||||
@ -59,17 +60,20 @@ pub struct CreateRowParams {
|
|||||||
pub grid_id: String,
|
pub grid_id: String,
|
||||||
pub start_row_id: Option<String>,
|
pub start_row_id: Option<String>,
|
||||||
pub group_id: Option<String>,
|
pub group_id: Option<String>,
|
||||||
|
pub layout: GridLayout,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryInto<CreateRowParams> for CreateRowPayloadPB {
|
impl TryInto<CreateRowParams> for CreateTableRowPayloadPB {
|
||||||
type Error = ErrorCode;
|
type Error = ErrorCode;
|
||||||
|
|
||||||
fn try_into(self) -> Result<CreateRowParams, Self::Error> {
|
fn try_into(self) -> Result<CreateRowParams, Self::Error> {
|
||||||
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(CreateRowParams {
|
Ok(CreateRowParams {
|
||||||
grid_id: grid_id.0,
|
grid_id: grid_id.0,
|
||||||
start_row_id: self.start_row_id,
|
start_row_id: self.start_row_id,
|
||||||
group_id: None,
|
group_id: None,
|
||||||
|
layout: GridLayout::Table,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ pub struct GridSettingPB {
|
|||||||
pub layouts: Vec<GridLayoutPB>,
|
pub layouts: Vec<GridLayoutPB>,
|
||||||
|
|
||||||
#[pb(index = 2)]
|
#[pb(index = 2)]
|
||||||
pub current_layout_type: Layout,
|
pub current_layout_type: GridLayout,
|
||||||
|
|
||||||
#[pb(index = 3)]
|
#[pb(index = 3)]
|
||||||
pub filter_configuration_by_field_id: HashMap<String, RepeatedGridConfigurationFilterPB>,
|
pub filter_configuration_by_field_id: HashMap<String, RepeatedGridConfigurationFilterPB>,
|
||||||
@ -34,13 +34,13 @@ pub struct GridSettingPB {
|
|||||||
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
|
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
|
||||||
pub struct GridLayoutPB {
|
pub struct GridLayoutPB {
|
||||||
#[pb(index = 1)]
|
#[pb(index = 1)]
|
||||||
ty: Layout,
|
ty: GridLayout,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GridLayoutPB {
|
impl GridLayoutPB {
|
||||||
pub fn all() -> Vec<GridLayoutPB> {
|
pub fn all() -> Vec<GridLayoutPB> {
|
||||||
let mut layouts = vec![];
|
let mut layouts = vec![];
|
||||||
for layout_ty in Layout::iter() {
|
for layout_ty in GridLayout::iter() {
|
||||||
layouts.push(GridLayoutPB { ty: layout_ty })
|
layouts.push(GridLayoutPB { ty: layout_ty })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,31 +50,31 @@ impl GridLayoutPB {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum, EnumIter)]
|
#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum, EnumIter)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
pub enum Layout {
|
pub enum GridLayout {
|
||||||
Table = 0,
|
Table = 0,
|
||||||
Board = 1,
|
Board = 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::default::Default for Layout {
|
impl std::default::Default for GridLayout {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Layout::Table
|
GridLayout::Table
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::convert::From<LayoutRevision> for Layout {
|
impl std::convert::From<LayoutRevision> for GridLayout {
|
||||||
fn from(rev: LayoutRevision) -> Self {
|
fn from(rev: LayoutRevision) -> Self {
|
||||||
match rev {
|
match rev {
|
||||||
LayoutRevision::Table => Layout::Table,
|
LayoutRevision::Table => GridLayout::Table,
|
||||||
LayoutRevision::Board => Layout::Board,
|
LayoutRevision::Board => GridLayout::Board,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::convert::From<Layout> for LayoutRevision {
|
impl std::convert::From<GridLayout> for LayoutRevision {
|
||||||
fn from(layout: Layout) -> Self {
|
fn from(layout: GridLayout) -> Self {
|
||||||
match layout {
|
match layout {
|
||||||
Layout::Table => LayoutRevision::Table,
|
GridLayout::Table => LayoutRevision::Table,
|
||||||
Layout::Board => LayoutRevision::Board,
|
GridLayout::Board => LayoutRevision::Board,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -85,7 +85,7 @@ pub struct GridSettingChangesetPayloadPB {
|
|||||||
pub grid_id: String,
|
pub grid_id: String,
|
||||||
|
|
||||||
#[pb(index = 2)]
|
#[pb(index = 2)]
|
||||||
pub layout_type: Layout,
|
pub layout_type: GridLayout,
|
||||||
|
|
||||||
#[pb(index = 3, one_of)]
|
#[pb(index = 3, one_of)]
|
||||||
pub insert_filter: Option<CreateGridFilterPayloadPB>,
|
pub insert_filter: Option<CreateGridFilterPayloadPB>,
|
||||||
|
@ -203,13 +203,13 @@ pub(crate) async fn create_field_type_option_data_handler(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "trace", skip(data, manager), err)]
|
#[tracing::instrument(level = "trace", skip(data, manager), err)]
|
||||||
pub(crate) async fn move_item_handler(
|
pub(crate) async fn move_field_handler(
|
||||||
data: Data<MoveItemPayloadPB>,
|
data: Data<MoveFieldPayloadPB>,
|
||||||
manager: AppData<Arc<GridManager>>,
|
manager: AppData<Arc<GridManager>>,
|
||||||
) -> Result<(), FlowyError> {
|
) -> Result<(), FlowyError> {
|
||||||
let params: MoveItemParams = data.into_inner().try_into()?;
|
let params: MoveFieldParams = data.into_inner().try_into()?;
|
||||||
let editor = manager.get_grid_editor(¶ms.grid_id)?;
|
let editor = manager.get_grid_editor(¶ms.grid_id)?;
|
||||||
let _ = editor.move_item(params).await?;
|
let _ = editor.move_field(params).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,8 +260,19 @@ pub(crate) async fn duplicate_row_handler(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip(data, manager), err)]
|
#[tracing::instrument(level = "debug", skip(data, manager), err)]
|
||||||
pub(crate) async fn create_row_handler(
|
pub(crate) async fn move_row_handler(
|
||||||
data: Data<CreateRowPayloadPB>,
|
data: Data<MoveRowPayloadPB>,
|
||||||
|
manager: AppData<Arc<GridManager>>,
|
||||||
|
) -> Result<(), FlowyError> {
|
||||||
|
let params: MoveRowParams = data.into_inner().try_into()?;
|
||||||
|
let editor = manager.get_grid_editor(¶ms.view_id)?;
|
||||||
|
let _ = editor.move_row(params).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(level = "debug", skip(data, manager), err)]
|
||||||
|
pub(crate) async fn create_table_row_handler(
|
||||||
|
data: Data<CreateTableRowPayloadPB>,
|
||||||
manager: AppData<Arc<GridManager>>,
|
manager: AppData<Arc<GridManager>>,
|
||||||
) -> DataResult<RowPB, FlowyError> {
|
) -> DataResult<RowPB, FlowyError> {
|
||||||
let params: CreateRowParams = data.into_inner().try_into()?;
|
let params: CreateRowParams = data.into_inner().try_into()?;
|
||||||
|
@ -20,14 +20,15 @@ pub fn create(grid_manager: Arc<GridManager>) -> Module {
|
|||||||
.event(GridEvent::DeleteField, delete_field_handler)
|
.event(GridEvent::DeleteField, delete_field_handler)
|
||||||
.event(GridEvent::SwitchToField, switch_to_field_handler)
|
.event(GridEvent::SwitchToField, switch_to_field_handler)
|
||||||
.event(GridEvent::DuplicateField, duplicate_field_handler)
|
.event(GridEvent::DuplicateField, duplicate_field_handler)
|
||||||
.event(GridEvent::MoveItem, move_item_handler)
|
.event(GridEvent::MoveField, move_field_handler)
|
||||||
.event(GridEvent::GetFieldTypeOption, get_field_type_option_data_handler)
|
.event(GridEvent::GetFieldTypeOption, get_field_type_option_data_handler)
|
||||||
.event(GridEvent::CreateFieldTypeOption, create_field_type_option_data_handler)
|
.event(GridEvent::CreateFieldTypeOption, create_field_type_option_data_handler)
|
||||||
// Row
|
// Row
|
||||||
.event(GridEvent::CreateRow, create_row_handler)
|
.event(GridEvent::CreateTableRow, create_table_row_handler)
|
||||||
.event(GridEvent::GetRow, get_row_handler)
|
.event(GridEvent::GetRow, get_row_handler)
|
||||||
.event(GridEvent::DeleteRow, delete_row_handler)
|
.event(GridEvent::DeleteRow, delete_row_handler)
|
||||||
.event(GridEvent::DuplicateRow, duplicate_row_handler)
|
.event(GridEvent::DuplicateRow, duplicate_row_handler)
|
||||||
|
.event(GridEvent::MoveRow, move_row_handler)
|
||||||
// Cell
|
// Cell
|
||||||
.event(GridEvent::GetCell, get_cell_handler)
|
.event(GridEvent::GetCell, get_cell_handler)
|
||||||
.event(GridEvent::UpdateCell, update_cell_handler)
|
.event(GridEvent::UpdateCell, update_cell_handler)
|
||||||
@ -130,8 +131,8 @@ pub enum GridEvent {
|
|||||||
|
|
||||||
/// [MoveItem] event is used to move an item. For the moment, Item has two types defined in
|
/// [MoveItem] event is used to move an item. For the moment, Item has two types defined in
|
||||||
/// [MoveItemTypePB].
|
/// [MoveItemTypePB].
|
||||||
#[event(input = "MoveItemPayloadPB")]
|
#[event(input = "MoveFieldPayloadPB")]
|
||||||
MoveItem = 22,
|
MoveField = 22,
|
||||||
|
|
||||||
/// [FieldTypeOptionIdPB] event is used to get the FieldTypeOption data for a specific field type.
|
/// [FieldTypeOptionIdPB] event is used to get the FieldTypeOption data for a specific field type.
|
||||||
///
|
///
|
||||||
@ -166,8 +167,8 @@ pub enum GridEvent {
|
|||||||
#[event(input = "SelectOptionChangesetPayloadPB")]
|
#[event(input = "SelectOptionChangesetPayloadPB")]
|
||||||
UpdateSelectOption = 32,
|
UpdateSelectOption = 32,
|
||||||
|
|
||||||
#[event(input = "CreateRowPayloadPB", output = "RowPB")]
|
#[event(input = "CreateTableRowPayloadPB", output = "RowPB")]
|
||||||
CreateRow = 50,
|
CreateTableRow = 50,
|
||||||
|
|
||||||
/// [GetRow] event is used to get the row data,[RowPB]. [OptionalRowPB] is a wrapper that enables
|
/// [GetRow] event is used to get the row data,[RowPB]. [OptionalRowPB] is a wrapper that enables
|
||||||
/// to return a nullable row data.
|
/// to return a nullable row data.
|
||||||
@ -180,6 +181,9 @@ pub enum GridEvent {
|
|||||||
#[event(input = "RowIdPB")]
|
#[event(input = "RowIdPB")]
|
||||||
DuplicateRow = 53,
|
DuplicateRow = 53,
|
||||||
|
|
||||||
|
#[event(input = "MoveRowPayloadPB")]
|
||||||
|
MoveRow = 54,
|
||||||
|
|
||||||
#[event(input = "GridCellIdPB", output = "GridCellPB")]
|
#[event(input = "GridCellIdPB", output = "GridCellPB")]
|
||||||
GetCell = 70,
|
GetCell = 70,
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ impl GridBlockRevisionEditor {
|
|||||||
if let Some(start_row_id) = prev_row_id.as_ref() {
|
if let Some(start_row_id) = prev_row_id.as_ref() {
|
||||||
match block_pad.index_of_row(start_row_id) {
|
match block_pad.index_of_row(start_row_id) {
|
||||||
None => {}
|
None => {}
|
||||||
Some(index) => row_index = Some(index + 1),
|
Some(index) => row_index = Some(index as i32 + 1),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,6 +100,10 @@ impl GridBlockRevisionEditor {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn index_of_row(&self, row_id: &str) -> Option<usize> {
|
||||||
|
self.pad.read().await.index_of_row(row_id)
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn get_row_rev(&self, row_id: &str) -> FlowyResult<Option<Arc<RowRevision>>> {
|
pub async fn get_row_rev(&self, row_id: &str) -> FlowyResult<Option<Arc<RowRevision>>> {
|
||||||
let row_ids = vec![Cow::Borrowed(row_id)];
|
let row_ids = vec![Cow::Borrowed(row_id)];
|
||||||
let row_rev = self.get_row_revs(Some(row_ids)).await?.pop();
|
let row_rev = self.get_row_revs(Some(row_ids)).await?.pop();
|
||||||
|
@ -52,7 +52,7 @@ impl GridBlockManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_editor_from_row_id(&self, row_id: &str) -> FlowyResult<Arc<GridBlockRevisionEditor>> {
|
pub(crate) async fn get_editor_from_row_id(&self, row_id: &str) -> FlowyResult<Arc<GridBlockRevisionEditor>> {
|
||||||
let block_id = self.persistence.get_block_id(row_id)?;
|
let block_id = self.persistence.get_block_id(row_id)?;
|
||||||
Ok(self.get_block_editor(&block_id).await?)
|
Ok(self.get_block_editor(&block_id).await?)
|
||||||
}
|
}
|
||||||
@ -122,6 +122,7 @@ impl GridBlockManager {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(level = "trace", skip_all, err)]
|
||||||
pub async fn delete_row(&self, row_id: &str) -> FlowyResult<()> {
|
pub async fn delete_row(&self, row_id: &str) -> FlowyResult<()> {
|
||||||
let row_id = row_id.to_owned();
|
let row_id = row_id.to_owned();
|
||||||
let block_id = self.persistence.get_block_id(&row_id)?;
|
let block_id = self.persistence.get_block_id(&row_id)?;
|
||||||
@ -155,7 +156,7 @@ impl GridBlockManager {
|
|||||||
|
|
||||||
Ok(changesets)
|
Ok(changesets)
|
||||||
}
|
}
|
||||||
|
// This function will be moved to GridViewRevisionEditor
|
||||||
pub(crate) async fn move_row(&self, row_rev: Arc<RowRevision>, from: usize, to: usize) -> FlowyResult<()> {
|
pub(crate) async fn move_row(&self, row_rev: Arc<RowRevision>, from: usize, to: usize) -> FlowyResult<()> {
|
||||||
let editor = self.get_editor_from_row_id(&row_rev.id).await?;
|
let editor = self.get_editor_from_row_id(&row_rev.id).await?;
|
||||||
let _ = editor.move_row(&row_rev.id, from, to).await?;
|
let _ = editor.move_row(&row_rev.id, from, to).await?;
|
||||||
@ -180,6 +181,14 @@ impl GridBlockManager {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This function will be moved to GridViewRevisionEditor.
|
||||||
|
pub async fn index_of_row(&self, row_id: &str) -> Option<usize> {
|
||||||
|
match self.get_editor_from_row_id(row_id).await {
|
||||||
|
Ok(editor) => editor.index_of_row(row_id).await,
|
||||||
|
Err(_) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn update_cell<F>(&self, changeset: CellChangesetPB, row_builder: F) -> FlowyResult<()>
|
pub async fn update_cell<F>(&self, changeset: CellChangesetPB, row_builder: F) -> FlowyResult<()>
|
||||||
where
|
where
|
||||||
F: FnOnce(Arc<RowRevision>) -> RowPB,
|
F: FnOnce(Arc<RowRevision>) -> RowPB,
|
||||||
|
@ -342,7 +342,7 @@ impl GridRevisionEditor {
|
|||||||
|
|
||||||
pub async fn delete_row(&self, row_id: &str) -> FlowyResult<()> {
|
pub async fn delete_row(&self, row_id: &str) -> FlowyResult<()> {
|
||||||
let _ = self.block_manager.delete_row(row_id).await?;
|
let _ = self.block_manager.delete_row(row_id).await?;
|
||||||
self.view_manager.delete_row(row_id).await;
|
self.view_manager.did_delete_row(row_id).await;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -484,21 +484,22 @@ impl GridRevisionEditor {
|
|||||||
Ok(snapshots)
|
Ok(snapshots)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn move_item(&self, params: MoveItemParams) -> FlowyResult<()> {
|
pub async fn move_row(&self, params: MoveRowParams) -> FlowyResult<()> {
|
||||||
match params.ty {
|
self.view_manager.move_row(params).await
|
||||||
MoveItemTypePB::MoveField => {
|
|
||||||
self.move_field(¶ms.item_id, params.from_index, params.to_index)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
MoveItemTypePB::MoveRow => self.move_row(¶ms.item_id, params.from_index, params.to_index).await,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn move_field(&self, field_id: &str, from: i32, to: i32) -> FlowyResult<()> {
|
pub async fn move_field(&self, params: MoveFieldParams) -> FlowyResult<()> {
|
||||||
|
let MoveFieldParams {
|
||||||
|
grid_id: _,
|
||||||
|
field_id,
|
||||||
|
from_index,
|
||||||
|
to_index,
|
||||||
|
} = params;
|
||||||
|
|
||||||
let _ = self
|
let _ = self
|
||||||
.modify(|grid_pad| Ok(grid_pad.move_field(field_id, from as usize, to as usize)?))
|
.modify(|grid_pad| Ok(grid_pad.move_field(&field_id, from_index as usize, to_index as usize)?))
|
||||||
.await?;
|
.await?;
|
||||||
if let Some((index, field_rev)) = self.grid_pad.read().await.get_field_rev(field_id) {
|
if let Some((index, field_rev)) = self.grid_pad.read().await.get_field_rev(&field_id) {
|
||||||
let delete_field_order = FieldIdPB::from(field_id);
|
let delete_field_order = FieldIdPB::from(field_id);
|
||||||
let insert_field = IndexFieldPB::from_field_rev(field_rev, index);
|
let insert_field = IndexFieldPB::from_field_rev(field_rev, index);
|
||||||
let notified_changeset = FieldChangesetPB {
|
let notified_changeset = FieldChangesetPB {
|
||||||
@ -513,10 +514,6 @@ impl GridRevisionEditor {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn move_row(&self, row_id: &str, from: i32, to: i32) -> FlowyResult<()> {
|
|
||||||
self.view_manager.move_row(row_id, from, to).await
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn delta_bytes(&self) -> Bytes {
|
pub async fn delta_bytes(&self) -> Bytes {
|
||||||
self.grid_pad.read().await.delta_bytes()
|
self.grid_pad.read().await.delta_bytes()
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,17 @@
|
|||||||
use flowy_error::{FlowyError, FlowyResult};
|
use flowy_error::{FlowyError, FlowyResult};
|
||||||
|
|
||||||
use crate::entities::{CreateRowParams, GridFilterConfiguration, GridSettingPB, GroupPB, RowPB};
|
use crate::entities::{
|
||||||
|
CreateRowParams, GridFilterConfiguration, GridLayout, GridSettingPB, GroupPB, GroupRowsChangesetPB, InsertedRowPB,
|
||||||
|
RowPB,
|
||||||
|
};
|
||||||
use crate::services::grid_editor_task::GridServiceTaskScheduler;
|
use crate::services::grid_editor_task::GridServiceTaskScheduler;
|
||||||
use crate::services::group::{default_group_configuration, GroupConfigurationDelegate, GroupService};
|
use crate::services::group::{default_group_configuration, Group, GroupConfigurationDelegate, GroupService};
|
||||||
use flowy_grid_data_model::revision::{FieldRevision, GroupConfigurationRevision, RowRevision};
|
use flowy_grid_data_model::revision::{FieldRevision, GroupConfigurationRevision, RowRevision};
|
||||||
use flowy_revision::{RevisionCloudService, RevisionManager, RevisionObjectBuilder};
|
use flowy_revision::{RevisionCloudService, RevisionManager, RevisionObjectBuilder};
|
||||||
use flowy_sync::client_grid::{GridViewRevisionChangeset, GridViewRevisionPad};
|
use flowy_sync::client_grid::{GridViewRevisionChangeset, GridViewRevisionPad};
|
||||||
use flowy_sync::entities::revision::Revision;
|
use flowy_sync::entities::revision::Revision;
|
||||||
|
|
||||||
|
use crate::dart_notification::{send_dart_notification, GridNotification};
|
||||||
use crate::services::setting::make_grid_setting;
|
use crate::services::setting::make_grid_setting;
|
||||||
use flowy_sync::entities::grid::GridSettingChangesetParams;
|
use flowy_sync::entities::grid::GridSettingChangesetParams;
|
||||||
use lib_infra::future::{wrap_future, AFFuture, FutureResult};
|
use lib_infra::future::{wrap_future, AFFuture, FutureResult};
|
||||||
@ -19,7 +23,7 @@ pub trait GridViewRevisionDelegate: Send + Sync + 'static {
|
|||||||
fn get_field_rev(&self, field_id: &str) -> AFFuture<Option<Arc<FieldRevision>>>;
|
fn get_field_rev(&self, field_id: &str) -> AFFuture<Option<Arc<FieldRevision>>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait GridViewRevisionDataSource: Send + Sync + 'static {
|
pub trait GridViewRevisionRowDataSource: Send + Sync + 'static {
|
||||||
fn row_revs(&self) -> AFFuture<Vec<Arc<RowRevision>>>;
|
fn row_revs(&self) -> AFFuture<Vec<Arc<RowRevision>>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,8 +34,9 @@ pub struct GridViewRevisionEditor {
|
|||||||
pad: Arc<RwLock<GridViewRevisionPad>>,
|
pad: Arc<RwLock<GridViewRevisionPad>>,
|
||||||
rev_manager: Arc<RevisionManager>,
|
rev_manager: Arc<RevisionManager>,
|
||||||
delegate: Arc<dyn GridViewRevisionDelegate>,
|
delegate: Arc<dyn GridViewRevisionDelegate>,
|
||||||
data_source: Arc<dyn GridViewRevisionDataSource>,
|
data_source: Arc<dyn GridViewRevisionRowDataSource>,
|
||||||
group_service: Arc<RwLock<GroupService>>,
|
group_service: Arc<RwLock<GroupService>>,
|
||||||
|
groups: Arc<RwLock<Vec<Group>>>,
|
||||||
scheduler: Arc<dyn GridServiceTaskScheduler>,
|
scheduler: Arc<dyn GridServiceTaskScheduler>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,7 +52,7 @@ impl GridViewRevisionEditor {
|
|||||||
) -> FlowyResult<Self>
|
) -> FlowyResult<Self>
|
||||||
where
|
where
|
||||||
Delegate: GridViewRevisionDelegate,
|
Delegate: GridViewRevisionDelegate,
|
||||||
DataSource: GridViewRevisionDataSource,
|
DataSource: GridViewRevisionRowDataSource,
|
||||||
{
|
{
|
||||||
let cloud = Arc::new(GridViewRevisionCloudService {
|
let cloud = Arc::new(GridViewRevisionCloudService {
|
||||||
token: token.to_owned(),
|
token: token.to_owned(),
|
||||||
@ -57,52 +62,87 @@ impl GridViewRevisionEditor {
|
|||||||
let rev_manager = Arc::new(rev_manager);
|
let rev_manager = Arc::new(rev_manager);
|
||||||
let group_service = GroupService::new(Box::new(pad.clone())).await;
|
let group_service = GroupService::new(Box::new(pad.clone())).await;
|
||||||
let user_id = user_id.to_owned();
|
let user_id = user_id.to_owned();
|
||||||
|
let groups = Arc::new(RwLock::new(vec![]));
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
pad,
|
pad,
|
||||||
user_id,
|
user_id,
|
||||||
view_id,
|
view_id,
|
||||||
rev_manager,
|
rev_manager,
|
||||||
scheduler,
|
scheduler,
|
||||||
|
groups,
|
||||||
delegate: Arc::new(delegate),
|
delegate: Arc::new(delegate),
|
||||||
data_source: Arc::new(data_source),
|
data_source: Arc::new(data_source),
|
||||||
group_service: Arc::new(RwLock::new(group_service)),
|
group_service: Arc::new(RwLock::new(group_service)),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn create_row(&self, row_rev: &mut RowRevision, params: &CreateRowParams) {
|
pub(crate) async fn update_row(&self, row_rev: &mut RowRevision, params: &CreateRowParams) {
|
||||||
match params.group_id.as_ref() {
|
match params.layout {
|
||||||
None => {}
|
GridLayout::Table => {
|
||||||
Some(group_id) => {
|
// Table can be grouped too
|
||||||
self.group_service
|
|
||||||
.read()
|
|
||||||
.await
|
|
||||||
.update_row(row_rev, group_id, |field_id| self.delegate.get_field_rev(&field_id))
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
|
GridLayout::Board => match params.group_id.as_ref() {
|
||||||
|
None => {}
|
||||||
|
Some(group_id) => {
|
||||||
|
self.group_service
|
||||||
|
.read()
|
||||||
|
.await
|
||||||
|
.update_row(row_rev, group_id, |field_id| self.delegate.get_field_rev(&field_id))
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
todo!()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
|
// Send the group notification if the current view has groups
|
||||||
match params.group_id.as_ref() {
|
match params.group_id.as_ref() {
|
||||||
None => {}
|
None => {}
|
||||||
Some(group_id) => {
|
Some(group_id) => {
|
||||||
self.group_service.read().await.did_create_row(group_id, row_pb).await;
|
let inserted_row = InsertedRowPB {
|
||||||
|
row: row_pb.clone(),
|
||||||
|
index: None,
|
||||||
|
};
|
||||||
|
let changeset = GroupRowsChangesetPB::insert(group_id.clone(), vec![inserted_row]);
|
||||||
|
self.notify_did_update_group(changeset).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn delete_row(&self, row_id: &str) {
|
pub(crate) async fn did_delete_row(&self, row_id: &str) {
|
||||||
self.group_service.read().await.did_delete_card(row_id.to_owned()).await;
|
// Send the group notification if the current view has groups;
|
||||||
|
match self.group_id_of_row(row_id).await {
|
||||||
|
None => {}
|
||||||
|
Some(group_id) => {
|
||||||
|
let changeset = GroupRowsChangesetPB::delete(group_id, vec![row_id.to_owned()]);
|
||||||
|
self.notify_did_update_group(changeset).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn group_id_of_row(&self, row_id: &str) -> Option<String> {
|
||||||
|
let read_guard = self.groups.read().await;
|
||||||
|
for group in read_guard.iter() {
|
||||||
|
if group.rows.iter().any(|row| row.id == row_id) {
|
||||||
|
return Some(group.id.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn load_groups(&self) -> FlowyResult<Vec<GroupPB>> {
|
pub(crate) async fn load_groups(&self) -> FlowyResult<Vec<GroupPB>> {
|
||||||
let field_revs = self.delegate.get_field_revs().await;
|
let field_revs = self.delegate.get_field_revs().await;
|
||||||
let row_revs = self.data_source.row_revs().await;
|
let row_revs = self.data_source.row_revs().await;
|
||||||
|
|
||||||
|
//
|
||||||
let mut write_guard = self.group_service.write().await;
|
let mut write_guard = self.group_service.write().await;
|
||||||
match write_guard.load_groups(&field_revs, row_revs).await {
|
match write_guard.load_groups(&field_revs, row_revs).await {
|
||||||
None => Ok(vec![]),
|
None => Ok(vec![]),
|
||||||
Some(groups) => Ok(groups),
|
Some(groups) => {
|
||||||
|
*self.groups.write().await = groups.clone();
|
||||||
|
Ok(groups.into_iter().map(GroupPB::from).collect())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,6 +169,12 @@ impl GridViewRevisionEditor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn notify_did_update_group(&self, changeset: GroupRowsChangesetPB) {
|
||||||
|
send_dart_notification(&changeset.group_id, GridNotification::DidUpdateGroup)
|
||||||
|
.payload(changeset)
|
||||||
|
.send();
|
||||||
|
}
|
||||||
|
|
||||||
async fn modify<F>(&self, f: F) -> FlowyResult<()>
|
async fn modify<F>(&self, f: F) -> FlowyResult<()>
|
||||||
where
|
where
|
||||||
F: for<'a> FnOnce(&'a mut GridViewRevisionPad) -> FlowyResult<Option<GridViewRevisionChangeset>>,
|
F: for<'a> FnOnce(&'a mut GridViewRevisionPad) -> FlowyResult<Option<GridViewRevisionChangeset>>,
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
use crate::entities::{CreateRowParams, GridFilterConfiguration, GridSettingPB, RepeatedGridGroupPB, RowPB};
|
use crate::entities::{
|
||||||
|
CreateRowParams, GridFilterConfiguration, GridLayout, GridSettingPB, MoveRowParams, RepeatedGridGroupPB, RowPB,
|
||||||
|
};
|
||||||
use crate::manager::GridUser;
|
use crate::manager::GridUser;
|
||||||
use crate::services::block_manager::GridBlockManager;
|
use crate::services::block_manager::GridBlockManager;
|
||||||
use crate::services::grid_editor_task::GridServiceTaskScheduler;
|
use crate::services::grid_editor_task::GridServiceTaskScheduler;
|
||||||
use crate::services::grid_view_editor::{GridViewRevisionDataSource, GridViewRevisionDelegate, GridViewRevisionEditor};
|
use crate::services::grid_view_editor::{
|
||||||
|
GridViewRevisionDelegate, GridViewRevisionEditor, GridViewRevisionRowDataSource,
|
||||||
|
};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use dashmap::DashMap;
|
use dashmap::DashMap;
|
||||||
use flowy_error::FlowyResult;
|
use flowy_error::FlowyResult;
|
||||||
@ -45,7 +49,7 @@ impl GridViewManager {
|
|||||||
|
|
||||||
pub(crate) async fn update_row(&self, row_rev: &mut RowRevision, params: &CreateRowParams) {
|
pub(crate) async fn update_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.create_row(row_rev, params).await;
|
view_editor.update_row(row_rev, params).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,9 +59,9 @@ impl GridViewManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn delete_row(&self, row_id: &str) {
|
pub(crate) async fn did_delete_row(&self, row_id: &str) {
|
||||||
for view_editor in self.view_editors.iter() {
|
for view_editor in self.view_editors.iter() {
|
||||||
view_editor.delete_row(row_id).await;
|
view_editor.did_delete_row(row_id).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,15 +87,35 @@ impl GridViewManager {
|
|||||||
Ok(RepeatedGridGroupPB { items: groups })
|
Ok(RepeatedGridGroupPB { items: groups })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn move_row(&self, row_id: &str, from: i32, to: i32) -> FlowyResult<()> {
|
pub(crate) async fn move_row(&self, params: MoveRowParams) -> FlowyResult<()> {
|
||||||
match self.block_manager.get_row_rev(row_id).await? {
|
let MoveRowParams {
|
||||||
|
view_id: _,
|
||||||
|
row_id,
|
||||||
|
from_index,
|
||||||
|
to_index,
|
||||||
|
layout,
|
||||||
|
upper_row_id,
|
||||||
|
} = params;
|
||||||
|
|
||||||
|
let from_index = from_index as usize;
|
||||||
|
|
||||||
|
match self.block_manager.get_row_rev(&row_id).await? {
|
||||||
None => tracing::warn!("Move row failed, can not find the row:{}", row_id),
|
None => tracing::warn!("Move row failed, can not find the row:{}", row_id),
|
||||||
Some(row_rev) => {
|
Some(row_rev) => match layout {
|
||||||
let _ = self
|
GridLayout::Table => {
|
||||||
.block_manager
|
tracing::trace!("Move row from {} to {}", from_index, to_index);
|
||||||
.move_row(row_rev.clone(), from as usize, to as usize)
|
let to_index = to_index as usize;
|
||||||
.await?;
|
let _ = self.block_manager.move_row(row_rev, from_index, to_index).await?;
|
||||||
}
|
}
|
||||||
|
GridLayout::Board => {
|
||||||
|
if let Some(upper_row_id) = upper_row_id {
|
||||||
|
if let Some(to_index) = self.block_manager.index_of_row(&upper_row_id).await {
|
||||||
|
tracing::trace!("Move row from {} to {}", from_index, to_index);
|
||||||
|
let _ = self.block_manager.move_row(row_rev, from_index, to_index).await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -132,7 +156,7 @@ async fn make_view_editor<Delegate, DataSource>(
|
|||||||
) -> FlowyResult<GridViewRevisionEditor>
|
) -> FlowyResult<GridViewRevisionEditor>
|
||||||
where
|
where
|
||||||
Delegate: GridViewRevisionDelegate,
|
Delegate: GridViewRevisionDelegate,
|
||||||
DataSource: GridViewRevisionDataSource,
|
DataSource: GridViewRevisionRowDataSource,
|
||||||
{
|
{
|
||||||
tracing::trace!("Open view:{} editor", view_id);
|
tracing::trace!("Open view:{} editor", view_id);
|
||||||
|
|
||||||
@ -170,7 +194,7 @@ impl RevisionCompactor for GridViewRevisionCompactor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GridViewRevisionDataSource for Arc<GridBlockManager> {
|
impl GridViewRevisionRowDataSource for Arc<GridBlockManager> {
|
||||||
fn row_revs(&self) -> AFFuture<Vec<Arc<RowRevision>>> {
|
fn row_revs(&self) -> AFFuture<Vec<Arc<RowRevision>>> {
|
||||||
let block_manager = self.clone();
|
let block_manager = self.clone();
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ impl GroupActionHandler for CheckboxGroupController {
|
|||||||
&self.field_id
|
&self.field_id
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_groups(&self) -> Vec<Group> {
|
fn build_groups(&self) -> Vec<Group> {
|
||||||
self.make_groups()
|
self.make_groups()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ pub trait Groupable {
|
|||||||
|
|
||||||
pub trait GroupActionHandler: Send + Sync {
|
pub trait GroupActionHandler: Send + Sync {
|
||||||
fn field_id(&self) -> &str;
|
fn field_id(&self) -> &str;
|
||||||
fn get_groups(&self) -> Vec<Group>;
|
fn build_groups(&self) -> Vec<Group>;
|
||||||
fn group_rows(&mut self, row_revs: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<()>;
|
fn group_rows(&mut self, row_revs: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<()>;
|
||||||
fn update_card(&self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str);
|
fn update_card(&self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str);
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ impl GroupActionHandler for SingleSelectGroupController {
|
|||||||
&self.field_id
|
&self.field_id
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_groups(&self) -> Vec<Group> {
|
fn build_groups(&self) -> Vec<Group> {
|
||||||
self.make_groups()
|
self.make_groups()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,7 +94,7 @@ impl GroupActionHandler for MultiSelectGroupController {
|
|||||||
&self.field_id
|
&self.field_id
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_groups(&self) -> Vec<Group> {
|
fn build_groups(&self) -> Vec<Group> {
|
||||||
self.make_groups()
|
self.make_groups()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
use crate::dart_notification::{send_dart_notification, GridNotification};
|
|
||||||
use crate::entities::{
|
use crate::entities::{
|
||||||
BoardCardChangesetPB, CheckboxGroupConfigurationPB, DateGroupConfigurationPB, FieldType, GroupPB,
|
CheckboxGroupConfigurationPB, DateGroupConfigurationPB, FieldType, NumberGroupConfigurationPB,
|
||||||
NumberGroupConfigurationPB, RowPB, SelectOptionGroupConfigurationPB, TextGroupConfigurationPB,
|
SelectOptionGroupConfigurationPB, TextGroupConfigurationPB, UrlGroupConfigurationPB,
|
||||||
UrlGroupConfigurationPB,
|
|
||||||
};
|
};
|
||||||
use crate::services::group::{
|
use crate::services::group::{
|
||||||
CheckboxGroupController, GroupActionHandler, MultiSelectGroupController, SingleSelectGroupController,
|
CheckboxGroupController, Group, GroupActionHandler, MultiSelectGroupController, SingleSelectGroupController,
|
||||||
};
|
};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use flowy_error::FlowyResult;
|
use flowy_error::FlowyResult;
|
||||||
@ -36,7 +34,7 @@ impl GroupService {
|
|||||||
&mut self,
|
&mut self,
|
||||||
field_revs: &[Arc<FieldRevision>],
|
field_revs: &[Arc<FieldRevision>],
|
||||||
row_revs: Vec<Arc<RowRevision>>,
|
row_revs: Vec<Arc<RowRevision>>,
|
||||||
) -> Option<Vec<GroupPB>> {
|
) -> Option<Vec<Group>> {
|
||||||
let field_rev = find_group_field(field_revs).unwrap();
|
let field_rev = find_group_field(field_revs).unwrap();
|
||||||
let field_type: FieldType = field_rev.field_type_rev.into();
|
let field_type: FieldType = field_rev.field_type_rev.into();
|
||||||
let configuration = self.delegate.get_group_configuration(field_rev.clone()).await;
|
let configuration = self.delegate.get_group_configuration(field_rev.clone()).await;
|
||||||
@ -79,26 +77,6 @@ impl GroupService {
|
|||||||
// let row_pb = make_row_from_row_rev(row_rev);
|
// let row_pb = make_row_from_row_rev(row_rev);
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
#[allow(dead_code)]
|
|
||||||
pub async fn did_delete_card(&self, _row_id: String) {
|
|
||||||
// let changeset = BoardCardChangesetPB::delete(group_id.to_owned(), vec![row_id]);
|
|
||||||
// self.notify_did_update_board(changeset).await;
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn did_create_row(&self, group_id: &str, row_pb: &RowPB) {
|
|
||||||
let changeset = BoardCardChangesetPB::insert(group_id.to_owned(), vec![row_pb.clone()]);
|
|
||||||
self.notify_did_update_board(changeset).await;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn notify_did_update_board(&self, changeset: BoardCardChangesetPB) {
|
|
||||||
if self.action_handler.is_none() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
send_dart_notification(&changeset.group_id, GridNotification::DidUpdateBoard)
|
|
||||||
.payload(changeset)
|
|
||||||
.send();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tracing::instrument(level = "trace", skip_all, err)]
|
#[tracing::instrument(level = "trace", skip_all, err)]
|
||||||
async fn build_groups(
|
async fn build_groups(
|
||||||
@ -107,7 +85,7 @@ impl GroupService {
|
|||||||
field_rev: &Arc<FieldRevision>,
|
field_rev: &Arc<FieldRevision>,
|
||||||
row_revs: Vec<Arc<RowRevision>>,
|
row_revs: Vec<Arc<RowRevision>>,
|
||||||
configuration: GroupConfigurationRevision,
|
configuration: GroupConfigurationRevision,
|
||||||
) -> FlowyResult<Vec<GroupPB>> {
|
) -> FlowyResult<Vec<Group>> {
|
||||||
match field_type {
|
match field_type {
|
||||||
FieldType::RichText => {
|
FieldType::RichText => {
|
||||||
// let generator = GroupGenerator::<TextGroupConfigurationPB>::from_configuration(configuration);
|
// let generator = GroupGenerator::<TextGroupConfigurationPB>::from_configuration(configuration);
|
||||||
@ -139,11 +117,11 @@ impl GroupService {
|
|||||||
if let Some(group_action_handler) = self.action_handler.as_ref() {
|
if let Some(group_action_handler) = self.action_handler.as_ref() {
|
||||||
let mut write_guard = group_action_handler.write().await;
|
let mut write_guard = group_action_handler.write().await;
|
||||||
let _ = write_guard.group_rows(&row_revs, field_rev)?;
|
let _ = write_guard.group_rows(&row_revs, field_rev)?;
|
||||||
groups = write_guard.get_groups();
|
groups = write_guard.build_groups();
|
||||||
drop(write_guard);
|
drop(write_guard);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(groups.into_iter().map(GroupPB::from).collect())
|
Ok(groups)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::entities::{
|
use crate::entities::{
|
||||||
GridLayoutPB, GridSettingPB, Layout, RepeatedGridConfigurationFilterPB, RepeatedGridGroupConfigurationPB,
|
GridLayout, GridLayoutPB, GridSettingPB, RepeatedGridConfigurationFilterPB, RepeatedGridGroupConfigurationPB,
|
||||||
RepeatedGridSortPB,
|
RepeatedGridSortPB,
|
||||||
};
|
};
|
||||||
use flowy_grid_data_model::revision::{FieldRevision, SettingRevision};
|
use flowy_grid_data_model::revision::{FieldRevision, SettingRevision};
|
||||||
@ -12,7 +12,7 @@ pub struct GridSettingChangesetBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl GridSettingChangesetBuilder {
|
impl GridSettingChangesetBuilder {
|
||||||
pub fn new(grid_id: &str, layout_type: &Layout) -> Self {
|
pub fn new(grid_id: &str, layout_type: &GridLayout) -> Self {
|
||||||
let params = GridSettingChangesetParams {
|
let params = GridSettingChangesetParams {
|
||||||
grid_id: grid_id.to_string(),
|
grid_id: grid_id.to_string(),
|
||||||
layout_type: layout_type.clone().into(),
|
layout_type: layout_type.clone().into(),
|
||||||
@ -42,7 +42,7 @@ impl GridSettingChangesetBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn make_grid_setting(grid_setting_rev: &SettingRevision, field_revs: &[Arc<FieldRevision>]) -> GridSettingPB {
|
pub fn make_grid_setting(grid_setting_rev: &SettingRevision, field_revs: &[Arc<FieldRevision>]) -> GridSettingPB {
|
||||||
let current_layout_type: Layout = grid_setting_rev.layout.clone().into();
|
let current_layout_type: GridLayout = grid_setting_rev.layout.clone().into();
|
||||||
let filters_by_field_id = grid_setting_rev
|
let filters_by_field_id = grid_setting_rev
|
||||||
.get_all_filters(field_revs)
|
.get_all_filters(field_revs)
|
||||||
.map(|filters_by_field_id| {
|
.map(|filters_by_field_id| {
|
||||||
|
@ -2,7 +2,7 @@ use crate::grid::block_test::script::RowScript::{AssertCell, CreateRow};
|
|||||||
use crate::grid::block_test::util::GridRowTestBuilder;
|
use crate::grid::block_test::util::GridRowTestBuilder;
|
||||||
use crate::grid::grid_editor::GridEditorTest;
|
use crate::grid::grid_editor::GridEditorTest;
|
||||||
|
|
||||||
use flowy_grid::entities::{CreateRowParams, FieldType, GridCellIdParams, RowPB};
|
use flowy_grid::entities::{CreateRowParams, FieldType, GridCellIdParams, GridLayout, RowPB};
|
||||||
use flowy_grid::services::field::*;
|
use flowy_grid::services::field::*;
|
||||||
use flowy_grid_data_model::revision::{
|
use flowy_grid_data_model::revision::{
|
||||||
GridBlockMetaRevision, GridBlockMetaRevisionChangeset, RowMetaChangeset, RowRevision,
|
GridBlockMetaRevision, GridBlockMetaRevisionChangeset, RowMetaChangeset, RowRevision,
|
||||||
@ -81,6 +81,7 @@ impl GridRowTest {
|
|||||||
grid_id: self.editor.grid_id.clone(),
|
grid_id: self.editor.grid_id.clone(),
|
||||||
start_row_id: None,
|
start_row_id: None,
|
||||||
group_id: None,
|
group_id: None,
|
||||||
|
layout: GridLayout::Table,
|
||||||
};
|
};
|
||||||
let row_order = self.editor.create_row(params).await.unwrap();
|
let row_order = self.editor.create_row(params).await.unwrap();
|
||||||
self.row_order_by_row_id
|
self.row_order_by_row_id
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
#![allow(unused_imports)]
|
#![allow(unused_imports)]
|
||||||
|
|
||||||
use flowy_grid::entities::{CreateGridFilterPayloadPB, Layout, GridSettingPB};
|
use flowy_grid::entities::{CreateGridFilterPayloadPB, GridLayout, GridSettingPB};
|
||||||
use flowy_grid::services::setting::GridSettingChangesetBuilder;
|
use flowy_grid::services::setting::GridSettingChangesetBuilder;
|
||||||
use flowy_grid_data_model::revision::{FieldRevision, FieldTypeRevision};
|
use flowy_grid_data_model::revision::{FieldRevision, FieldTypeRevision};
|
||||||
use flowy_sync::entities::grid::{CreateGridFilterParams, DeleteFilterParams, GridSettingChangesetParams};
|
use flowy_sync::entities::grid::{CreateGridFilterParams, DeleteFilterParams, GridSettingChangesetParams};
|
||||||
@ -55,7 +55,7 @@ impl GridFilterTest {
|
|||||||
}
|
}
|
||||||
FilterScript::InsertGridTableFilter { payload } => {
|
FilterScript::InsertGridTableFilter { payload } => {
|
||||||
let params: CreateGridFilterParams = payload.try_into().unwrap();
|
let params: CreateGridFilterParams = payload.try_into().unwrap();
|
||||||
let layout_type = Layout::Table;
|
let layout_type = GridLayout::Table;
|
||||||
let params = GridSettingChangesetBuilder::new(&self.grid_id, &layout_type)
|
let params = GridSettingChangesetBuilder::new(&self.grid_id, &layout_type)
|
||||||
.insert_filter(params)
|
.insert_filter(params)
|
||||||
.build();
|
.build();
|
||||||
@ -66,7 +66,7 @@ impl GridFilterTest {
|
|||||||
assert_eq!(count as usize, filters.len());
|
assert_eq!(count as usize, filters.len());
|
||||||
}
|
}
|
||||||
FilterScript::DeleteGridTableFilter { filter_id, field_rev} => {
|
FilterScript::DeleteGridTableFilter { filter_id, field_rev} => {
|
||||||
let layout_type = Layout::Table;
|
let layout_type = GridLayout::Table;
|
||||||
let params = GridSettingChangesetBuilder::new(&self.grid_id, &layout_type)
|
let params = GridSettingChangesetBuilder::new(&self.grid_id, &layout_type)
|
||||||
.delete_filter(DeleteFilterParams { field_id: field_rev.id, filter_id, field_type_rev: field_rev.field_type_rev })
|
.delete_filter(DeleteFilterParams { field_id: field_rev.id, filter_id, field_type_rev: field_rev.field_type_rev })
|
||||||
.build();
|
.build();
|
||||||
|
@ -91,6 +91,9 @@ pub enum ErrorCode {
|
|||||||
|
|
||||||
#[display(fmt = "Grid id is empty")]
|
#[display(fmt = "Grid id is empty")]
|
||||||
GridIdIsEmpty = 410,
|
GridIdIsEmpty = 410,
|
||||||
|
#[display(fmt = "Grid view id is empty")]
|
||||||
|
GridViewIdIsEmpty = 411,
|
||||||
|
|
||||||
#[display(fmt = "Grid block id is empty")]
|
#[display(fmt = "Grid block id is empty")]
|
||||||
BlockIdIsEmpty = 420,
|
BlockIdIsEmpty = 420,
|
||||||
#[display(fmt = "Row id is empty")]
|
#[display(fmt = "Row id is empty")]
|
||||||
|
@ -139,12 +139,8 @@ impl GridBlockRevisionPad {
|
|||||||
self.block.rows.len() as i32
|
self.block.rows.len() as i32
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn index_of_row(&self, row_id: &str) -> Option<i32> {
|
pub fn index_of_row(&self, row_id: &str) -> Option<usize> {
|
||||||
self.block
|
self.block.rows.iter().position(|row| row.id == row_id)
|
||||||
.rows
|
|
||||||
.iter()
|
|
||||||
.position(|row| row.id == row_id)
|
|
||||||
.map(|index| index as i32)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_row(&mut self, changeset: RowMetaChangeset) -> CollaborateResult<Option<GridBlockRevisionChangeset>> {
|
pub fn update_row(&mut self, changeset: RowMetaChangeset) -> CollaborateResult<Option<GridBlockRevisionChangeset>> {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user