mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: enable create card from header button
This commit is contained in:
parent
8b7b18bfff
commit
cde8ad9084
@ -69,16 +69,31 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
|||||||
_startListening();
|
_startListening();
|
||||||
await _loadGrid(emit);
|
await _loadGrid(emit);
|
||||||
},
|
},
|
||||||
createRow: (groupId) async {
|
createBottomRow: (groupId) async {
|
||||||
|
final startRowId = groupControllers[groupId]?.lastRow()?.id;
|
||||||
|
final result = await _gridDataController.createBoardCard(
|
||||||
|
groupId,
|
||||||
|
startRowId: startRowId,
|
||||||
|
);
|
||||||
|
result.fold(
|
||||||
|
(_) {},
|
||||||
|
(err) => Log.error(err),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
createHeaderRow: (String groupId) async {
|
||||||
final result = await _gridDataController.createBoardCard(groupId);
|
final result = await _gridDataController.createBoardCard(groupId);
|
||||||
result.fold(
|
result.fold(
|
||||||
(_) {},
|
(_) {},
|
||||||
(err) => Log.error(err),
|
(err) => Log.error(err),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
didCreateRow: (String groupId, RowPB row) {
|
didCreateRow: (String groupId, RowPB row, int? index) {
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
editingRow: Some(BoardEditingRow(columnId: groupId, row: row)),
|
editingRow: Some(BoardEditingRow(
|
||||||
|
columnId: groupId,
|
||||||
|
row: row,
|
||||||
|
index: index,
|
||||||
|
)),
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
endEditRow: (rowId) {
|
endEditRow: (rowId) {
|
||||||
@ -142,8 +157,8 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
|||||||
for (final group in groups) {
|
for (final group in groups) {
|
||||||
final delegate = GroupControllerDelegateImpl(
|
final delegate = GroupControllerDelegateImpl(
|
||||||
controller: boardController,
|
controller: boardController,
|
||||||
onNewColumnItem: (groupId, row) {
|
onNewColumnItem: (groupId, row, index) {
|
||||||
add(BoardEvent.didCreateRow(groupId, row));
|
add(BoardEvent.didCreateRow(groupId, row, index));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
final controller = GroupController(
|
final controller = GroupController(
|
||||||
@ -231,9 +246,13 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
|||||||
@freezed
|
@freezed
|
||||||
class BoardEvent with _$BoardEvent {
|
class BoardEvent with _$BoardEvent {
|
||||||
const factory BoardEvent.initial() = _InitialBoard;
|
const factory BoardEvent.initial() = _InitialBoard;
|
||||||
const factory BoardEvent.createRow(String groupId) = _CreateRow;
|
const factory BoardEvent.createBottomRow(String groupId) = _CreateBottomRow;
|
||||||
const factory BoardEvent.didCreateRow(String groupId, RowPB row) =
|
const factory BoardEvent.createHeaderRow(String groupId) = _CreateHeaderRow;
|
||||||
_DidCreateRow;
|
const factory BoardEvent.didCreateRow(
|
||||||
|
String groupId,
|
||||||
|
RowPB row,
|
||||||
|
int? index,
|
||||||
|
) = _DidCreateRow;
|
||||||
const factory BoardEvent.endEditRow(String rowId) = _EndEditRow;
|
const factory BoardEvent.endEditRow(String rowId) = _EndEditRow;
|
||||||
const factory BoardEvent.didReceiveError(FlowyError error) = _DidReceiveError;
|
const factory BoardEvent.didReceiveError(FlowyError error) = _DidReceiveError;
|
||||||
const factory BoardEvent.didReceiveGridUpdate(
|
const factory BoardEvent.didReceiveGridUpdate(
|
||||||
@ -313,7 +332,7 @@ class BoardColumnItem extends AFColumnItem {
|
|||||||
|
|
||||||
class GroupControllerDelegateImpl extends GroupControllerDelegate {
|
class GroupControllerDelegateImpl extends GroupControllerDelegate {
|
||||||
final AFBoardDataController controller;
|
final AFBoardDataController controller;
|
||||||
final void Function(String, RowPB) onNewColumnItem;
|
final void Function(String, RowPB, int?) onNewColumnItem;
|
||||||
|
|
||||||
GroupControllerDelegateImpl({
|
GroupControllerDelegateImpl({
|
||||||
required this.controller,
|
required this.controller,
|
||||||
@ -351,23 +370,30 @@ class GroupControllerDelegateImpl extends GroupControllerDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void addNewRow(GroupPB group, RowPB row) {
|
void addNewRow(GroupPB group, RowPB row, int? index) {
|
||||||
final item = BoardColumnItem(
|
final item = BoardColumnItem(
|
||||||
row: row,
|
row: row,
|
||||||
fieldId: group.fieldId,
|
fieldId: group.fieldId,
|
||||||
requestFocus: true,
|
requestFocus: true,
|
||||||
);
|
);
|
||||||
controller.addColumnItem(group.groupId, item);
|
|
||||||
onNewColumnItem(group.groupId, row);
|
if (index != null) {
|
||||||
|
controller.insertColumnItem(group.groupId, index, item);
|
||||||
|
} else {
|
||||||
|
controller.addColumnItem(group.groupId, item);
|
||||||
|
}
|
||||||
|
onNewColumnItem(group.groupId, row, index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BoardEditingRow {
|
class BoardEditingRow {
|
||||||
String columnId;
|
String columnId;
|
||||||
RowPB row;
|
RowPB row;
|
||||||
|
int? index;
|
||||||
|
|
||||||
BoardEditingRow({
|
BoardEditingRow({
|
||||||
required this.columnId,
|
required this.columnId,
|
||||||
required this.row,
|
required this.row,
|
||||||
|
required this.index,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -118,8 +118,9 @@ class BoardDataController {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Either<RowPB, FlowyError>> createBoardCard(String groupId) {
|
Future<Either<RowPB, FlowyError>> createBoardCard(String groupId,
|
||||||
return _gridFFIService.createBoardCard(groupId);
|
{String? startRowId}) {
|
||||||
|
return _gridFFIService.createBoardCard(groupId, startRowId);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> dispose() async {
|
Future<void> dispose() async {
|
||||||
|
@ -9,7 +9,7 @@ abstract class GroupControllerDelegate {
|
|||||||
void removeRow(GroupPB group, String rowId);
|
void removeRow(GroupPB group, String rowId);
|
||||||
void insertRow(GroupPB group, RowPB row, int? index);
|
void insertRow(GroupPB group, RowPB row, int? index);
|
||||||
void updateRow(GroupPB group, RowPB row);
|
void updateRow(GroupPB group, RowPB row);
|
||||||
void addNewRow(GroupPB group, RowPB row);
|
void addNewRow(GroupPB group, RowPB row, int? index);
|
||||||
}
|
}
|
||||||
|
|
||||||
class GroupController {
|
class GroupController {
|
||||||
@ -31,6 +31,11 @@ class GroupController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RowPB? lastRow() {
|
||||||
|
if (group.rows.isEmpty) return null;
|
||||||
|
return group.rows.last;
|
||||||
|
}
|
||||||
|
|
||||||
void startListening() {
|
void startListening() {
|
||||||
_listener.start(onGroupChanged: (result) {
|
_listener.start(onGroupChanged: (result) {
|
||||||
result.fold(
|
result.fold(
|
||||||
@ -50,7 +55,7 @@ class GroupController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (insertedRow.isNew) {
|
if (insertedRow.isNew) {
|
||||||
delegate.addNewRow(group, insertedRow.row);
|
delegate.addNewRow(group, insertedRow.row, index);
|
||||||
} else {
|
} else {
|
||||||
delegate.insertRow(group, insertedRow.row, index);
|
delegate.insertRow(group, insertedRow.row, index);
|
||||||
}
|
}
|
||||||
|
@ -84,11 +84,14 @@ class _BoardContentState extends State<BoardContent> {
|
|||||||
() => null,
|
() => null,
|
||||||
(editingRow) {
|
(editingRow) {
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
scrollManager.scrollToBottom(editingRow.columnId, () {
|
if (editingRow.index != null) {
|
||||||
context
|
} else {
|
||||||
.read<BoardBloc>()
|
scrollManager.scrollToBottom(editingRow.columnId, () {
|
||||||
.add(BoardEvent.endEditRow(editingRow.row.id));
|
context
|
||||||
});
|
.read<BoardBloc>()
|
||||||
|
.add(BoardEvent.endEditRow(editingRow.row.id));
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -131,26 +134,32 @@ class _BoardContentState extends State<BoardContent> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildHeader(
|
Widget _buildHeader(
|
||||||
BuildContext context, AFBoardColumnHeaderData headerData) {
|
BuildContext context,
|
||||||
|
AFBoardColumnData columnData,
|
||||||
|
) {
|
||||||
return AppFlowyColumnHeader(
|
return AppFlowyColumnHeader(
|
||||||
title: Flexible(
|
title: Flexible(
|
||||||
fit: FlexFit.tight,
|
fit: FlexFit.tight,
|
||||||
child: FlowyText.medium(
|
child: FlowyText.medium(
|
||||||
headerData.columnName,
|
columnData.headerData.columnName,
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
overflow: TextOverflow.clip,
|
overflow: TextOverflow.clip,
|
||||||
color: context.read<AppTheme>().textColor,
|
color: context.read<AppTheme>().textColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// addIcon: const Icon(Icons.add, size: 20),
|
addIcon: SizedBox(
|
||||||
// moreIcon: SizedBox(
|
height: 20,
|
||||||
// width: 20,
|
width: 20,
|
||||||
// height: 20,
|
child: svgWidget(
|
||||||
// child: svgWidget(
|
"home/add",
|
||||||
// 'grid/details',
|
color: context.read<AppTheme>().iconColor,
|
||||||
// color: context.read<AppTheme>().iconColor,
|
),
|
||||||
// ),
|
),
|
||||||
// ),
|
onAddButtonClick: () {
|
||||||
|
context.read<BoardBloc>().add(
|
||||||
|
BoardEvent.createHeaderRow(columnData.id),
|
||||||
|
);
|
||||||
|
},
|
||||||
height: 50,
|
height: 50,
|
||||||
margin: config.headerPadding,
|
margin: config.headerPadding,
|
||||||
);
|
);
|
||||||
@ -178,7 +187,9 @@ class _BoardContentState extends State<BoardContent> {
|
|||||||
height: 50,
|
height: 50,
|
||||||
margin: config.footerPadding,
|
margin: config.footerPadding,
|
||||||
onAddButtonClick: () {
|
onAddButtonClick: () {
|
||||||
context.read<BoardBloc>().add(BoardEvent.createRow(columnData.id));
|
context.read<BoardBloc>().add(
|
||||||
|
BoardEvent.createBottomRow(columnData.id),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -205,8 +216,13 @@ class _BoardContentState extends State<BoardContent> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
final cellBuilder = BoardCellBuilder(cardController);
|
final cellBuilder = BoardCellBuilder(cardController);
|
||||||
|
bool isEditing = false;
|
||||||
final isEditing = context.read<BoardBloc>().state.editingRow.isSome();
|
context.read<BoardBloc>().state.editingRow.fold(
|
||||||
|
() => null,
|
||||||
|
(editingRow) {
|
||||||
|
isEditing = editingRow.row.id == columnItem.row.id;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
return AppFlowyColumnItemCard(
|
return AppFlowyColumnItemCard(
|
||||||
key: ValueKey(columnItem.id),
|
key: ValueKey(columnItem.id),
|
||||||
|
@ -27,10 +27,18 @@ class GridFFIService {
|
|||||||
return GridEventCreateTableRow(payload).send();
|
return GridEventCreateTableRow(payload).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Either<RowPB, FlowyError>> createBoardCard(String groupId) {
|
Future<Either<RowPB, FlowyError>> createBoardCard(
|
||||||
|
String groupId,
|
||||||
|
String? startRowId,
|
||||||
|
) {
|
||||||
CreateBoardCardPayloadPB payload = CreateBoardCardPayloadPB.create()
|
CreateBoardCardPayloadPB payload = CreateBoardCardPayloadPB.create()
|
||||||
..gridId = gridId
|
..gridId = gridId
|
||||||
..groupId = groupId;
|
..groupId = groupId;
|
||||||
|
|
||||||
|
if (startRowId != null) {
|
||||||
|
payload.startRowId = startRowId;
|
||||||
|
}
|
||||||
|
|
||||||
return GridEventCreateBoardCard(payload).send();
|
return GridEventCreateBoardCard(payload).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,17 +73,17 @@ class _MultiBoardListExampleState extends State<MultiBoardListExample> {
|
|||||||
margin: config.columnItemPadding,
|
margin: config.columnItemPadding,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
headerBuilder: (context, headerData) {
|
headerBuilder: (context, columnData) {
|
||||||
return AppFlowyColumnHeader(
|
return AppFlowyColumnHeader(
|
||||||
icon: const Icon(Icons.lightbulb_circle),
|
icon: const Icon(Icons.lightbulb_circle),
|
||||||
title: SizedBox(
|
title: SizedBox(
|
||||||
width: 60,
|
width: 60,
|
||||||
child: TextField(
|
child: TextField(
|
||||||
controller: TextEditingController()
|
controller: TextEditingController()
|
||||||
..text = headerData.columnName,
|
..text = columnData.headerData.columnName,
|
||||||
onSubmitted: (val) {
|
onSubmitted: (val) {
|
||||||
boardDataController
|
boardDataController
|
||||||
.getColumnController(headerData.columnId)!
|
.getColumnController(columnData.headerData.columnId)!
|
||||||
.updateColumnName(val);
|
.updateColumnName(val);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -282,14 +282,16 @@ class _AFBoardContentState extends State<AFBoardContent> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget? _buildHeader(
|
Widget? _buildHeader(
|
||||||
BuildContext context, AFBoardColumnHeaderData headerData) {
|
BuildContext context,
|
||||||
|
AFBoardColumnData columnData,
|
||||||
|
) {
|
||||||
if (widget.headerBuilder == null) {
|
if (widget.headerBuilder == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return Selector<AFBoardColumnDataController, AFBoardColumnHeaderData>(
|
return Selector<AFBoardColumnDataController, AFBoardColumnHeaderData>(
|
||||||
selector: (context, controller) => controller.columnData.headerData,
|
selector: (context, controller) => controller.columnData.headerData,
|
||||||
builder: (context, headerData, _) {
|
builder: (context, headerData, _) {
|
||||||
return widget.headerBuilder!(context, headerData)!;
|
return widget.headerBuilder!(context, columnData)!;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ typedef AFBoardColumnCardBuilder = Widget Function(
|
|||||||
|
|
||||||
typedef AFBoardColumnHeaderBuilder = Widget? Function(
|
typedef AFBoardColumnHeaderBuilder = Widget? Function(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
AFBoardColumnHeaderData headerData,
|
AFBoardColumnData headerData,
|
||||||
);
|
);
|
||||||
|
|
||||||
typedef AFBoardColumnFooterBuilder = Widget Function(
|
typedef AFBoardColumnFooterBuilder = Widget Function(
|
||||||
@ -132,8 +132,8 @@ class _AFBoardColumnWidgetState extends State<AFBoardColumnWidget> {
|
|||||||
.map((item) => _buildWidget(context, item))
|
.map((item) => _buildWidget(context, item))
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
final header = widget.headerBuilder
|
final header =
|
||||||
?.call(context, widget.dataSource.columnData.headerData);
|
widget.headerBuilder?.call(context, widget.dataSource.columnData);
|
||||||
|
|
||||||
final footer =
|
final footer =
|
||||||
widget.footBuilder?.call(context, widget.dataSource.columnData);
|
widget.footBuilder?.call(context, widget.dataSource.columnData);
|
||||||
|
@ -14,6 +14,9 @@ pub struct CreateBoardCardPayloadPB {
|
|||||||
|
|
||||||
#[pb(index = 2)]
|
#[pb(index = 2)]
|
||||||
pub group_id: String,
|
pub group_id: String,
|
||||||
|
|
||||||
|
#[pb(index = 3, one_of)]
|
||||||
|
pub start_row_id: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryInto<CreateRowParams> for CreateBoardCardPayloadPB {
|
impl TryInto<CreateRowParams> for CreateBoardCardPayloadPB {
|
||||||
@ -22,9 +25,13 @@ impl TryInto<CreateRowParams> for CreateBoardCardPayloadPB {
|
|||||||
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)?;
|
||||||
let group_id = NotEmptyStr::parse(self.group_id).map_err(|_| ErrorCode::GroupIdIsEmpty)?;
|
let group_id = NotEmptyStr::parse(self.group_id).map_err(|_| ErrorCode::GroupIdIsEmpty)?;
|
||||||
|
let start_row_id = match self.start_row_id {
|
||||||
|
None => None,
|
||||||
|
Some(start_row_id) => Some(NotEmptyStr::parse(start_row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?.0),
|
||||||
|
};
|
||||||
Ok(CreateRowParams {
|
Ok(CreateRowParams {
|
||||||
grid_id: grid_id.0,
|
grid_id: grid_id.0,
|
||||||
start_row_id: None,
|
start_row_id,
|
||||||
group_id: Some(group_id.0),
|
group_id: Some(group_id.0),
|
||||||
layout: GridLayout::Board,
|
layout: GridLayout::Board,
|
||||||
})
|
})
|
||||||
|
@ -95,9 +95,13 @@ impl GridViewRevisionEditor {
|
|||||||
match params.group_id.as_ref() {
|
match params.group_id.as_ref() {
|
||||||
None => {}
|
None => {}
|
||||||
Some(group_id) => {
|
Some(group_id) => {
|
||||||
|
let index = match params.start_row_id {
|
||||||
|
None => Some(0),
|
||||||
|
Some(_) => None,
|
||||||
|
};
|
||||||
let inserted_row = InsertedRowPB {
|
let inserted_row = InsertedRowPB {
|
||||||
row: row_pb.clone(),
|
row: row_pb.clone(),
|
||||||
index: None,
|
index,
|
||||||
is_new: true,
|
is_new: true,
|
||||||
};
|
};
|
||||||
let changeset = GroupChangesetPB::insert(group_id.clone(), vec![inserted_row]);
|
let changeset = GroupChangesetPB::insert(group_id.clone(), vec![inserted_row]);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user