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