Skip to content

Commit d9aba78

Browse files
authored
Merge pull request #978 from AppFlowy-IO/feat/support_group_checkbox
chore: support group by checkbox field
2 parents 60c8ec1 + 5b92805 commit d9aba78

File tree

12 files changed

+247
-107
lines changed

12 files changed

+247
-107
lines changed

frontend/app_flowy/lib/plugins/board/application/board_bloc.dart

Lines changed: 62 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import 'dart:async';
2+
import 'dart:collection';
3+
24
import 'package:app_flowy/plugins/grid/application/block/block_cache.dart';
35
import 'package:app_flowy/plugins/grid/application/field/field_controller.dart';
46
import 'package:app_flowy/plugins/grid/application/row/row_cache.dart';
@@ -12,7 +14,6 @@ import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
1214
import 'package:flowy_sdk/protobuf/flowy-grid/protobuf.dart';
1315
import 'package:flutter_bloc/flutter_bloc.dart';
1416
import 'package:freezed_annotation/freezed_annotation.dart';
15-
import 'dart:collection';
1617

1718
import 'board_data_controller.dart';
1819
import 'group_controller.dart';
@@ -164,19 +165,25 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
164165
boardController.clear();
165166

166167
//
167-
List<AFBoardColumnData> columns = groups.map((group) {
168+
List<AFBoardColumnData> columns = groups
169+
.where((group) => fieldController.getField(group.fieldId) != null)
170+
.map((group) {
168171
return AFBoardColumnData(
169172
id: group.groupId,
170173
name: group.desc,
171174
items: _buildRows(group),
172-
customData: group,
175+
customData: BoardCustomData(
176+
group: group,
177+
fieldContext: fieldController.getField(group.fieldId)!,
178+
),
173179
);
174180
}).toList();
175181
boardController.addColumns(columns);
176182

177183
for (final group in groups) {
178184
final delegate = GroupControllerDelegateImpl(
179185
controller: boardController,
186+
fieldController: fieldController,
180187
onNewColumnItem: (groupId, row, index) {
181188
add(BoardEvent.didCreateRow(groupId, row, index));
182189
},
@@ -238,10 +245,8 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
238245

239246
List<AFColumnItem> _buildRows(GroupPB group) {
240247
final items = group.rows.map((row) {
241-
return BoardColumnItem(
242-
row: row,
243-
fieldId: group.fieldId,
244-
);
248+
final fieldContext = fieldController.getField(group.fieldId);
249+
return BoardColumnItem(row: row, fieldContext: fieldContext!);
245250
}).toList();
246251

247252
return <AFColumnItem>[...items];
@@ -332,40 +337,41 @@ class GridFieldEquatable extends Equatable {
332337

333338
class BoardColumnItem extends AFColumnItem {
334339
final RowPB row;
335-
336-
final String fieldId;
337-
338-
final bool requestFocus;
340+
final GridFieldContext fieldContext;
339341

340342
BoardColumnItem({
341343
required this.row,
342-
required this.fieldId,
343-
this.requestFocus = false,
344+
required this.fieldContext,
344345
});
345346

346347
@override
347348
String get id => row.id;
348349
}
349350

350351
class GroupControllerDelegateImpl extends GroupControllerDelegate {
352+
final GridFieldController fieldController;
351353
final AFBoardDataController controller;
352354
final void Function(String, RowPB, int?) onNewColumnItem;
353355

354356
GroupControllerDelegateImpl({
355357
required this.controller,
358+
required this.fieldController,
356359
required this.onNewColumnItem,
357360
});
358361

359362
@override
360363
void insertRow(GroupPB group, RowPB row, int? index) {
364+
final fieldContext = fieldController.getField(group.fieldId);
365+
if (fieldContext == null) {
366+
Log.warn("FieldContext should not be null");
367+
return;
368+
}
369+
361370
if (index != null) {
362-
final item = BoardColumnItem(row: row, fieldId: group.fieldId);
371+
final item = BoardColumnItem(row: row, fieldContext: fieldContext);
363372
controller.insertColumnItem(group.groupId, index, item);
364373
} else {
365-
final item = BoardColumnItem(
366-
row: row,
367-
fieldId: group.fieldId,
368-
);
374+
final item = BoardColumnItem(row: row, fieldContext: fieldContext);
369375
controller.addColumnItem(group.groupId, item);
370376
}
371377
}
@@ -377,22 +383,25 @@ class GroupControllerDelegateImpl extends GroupControllerDelegate {
377383

378384
@override
379385
void updateRow(GroupPB group, RowPB row) {
386+
final fieldContext = fieldController.getField(group.fieldId);
387+
if (fieldContext == null) {
388+
Log.warn("FieldContext should not be null");
389+
return;
390+
}
380391
controller.updateColumnItem(
381392
group.groupId,
382-
BoardColumnItem(
383-
row: row,
384-
fieldId: group.fieldId,
385-
),
393+
BoardColumnItem(row: row, fieldContext: fieldContext),
386394
);
387395
}
388396

389397
@override
390398
void addNewRow(GroupPB group, RowPB row, int? index) {
391-
final item = BoardColumnItem(
392-
row: row,
393-
fieldId: group.fieldId,
394-
requestFocus: true,
395-
);
399+
final fieldContext = fieldController.getField(group.fieldId);
400+
if (fieldContext == null) {
401+
Log.warn("FieldContext should not be null");
402+
return;
403+
}
404+
final item = BoardColumnItem(row: row, fieldContext: fieldContext);
396405

397406
if (index != null) {
398407
controller.insertColumnItem(group.groupId, index, item);
@@ -414,3 +423,29 @@ class BoardEditingRow {
414423
required this.index,
415424
});
416425
}
426+
427+
class BoardCustomData {
428+
final GroupPB group;
429+
final GridFieldContext fieldContext;
430+
BoardCustomData({
431+
required this.group,
432+
required this.fieldContext,
433+
});
434+
435+
CheckboxGroup? asCheckboxGroup() {
436+
if (fieldType != FieldType.Checkbox) return null;
437+
return CheckboxGroup(group);
438+
}
439+
440+
FieldType get fieldType => fieldContext.fieldType;
441+
}
442+
443+
class CheckboxGroup {
444+
final GroupPB group;
445+
446+
CheckboxGroup(this.group);
447+
448+
// Hardcode value: "Yes" that equal to the value defined in Rust
449+
// pub const CHECK: &str = "Yes";
450+
bool get isCheck => group.groupId == "Yes";
451+
}

frontend/app_flowy/lib/plugins/board/presentation/board_page.dart

Lines changed: 70 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import 'package:flowy_infra_ui/style_widget/text.dart';
1717
import 'package:flowy_infra_ui/widget/error_page.dart';
1818
import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
1919
import 'package:flowy_sdk/protobuf/flowy-grid/block_entities.pb.dart';
20-
import 'package:flowy_sdk/protobuf/flowy-grid/group.pbserver.dart';
20+
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
2121
import 'package:flutter/material.dart';
2222
import 'package:flutter_bloc/flutter_bloc.dart';
2323
import '../../grid/application/row/row_cache.dart';
@@ -36,8 +36,7 @@ class BoardPage extends StatelessWidget {
3636
create: (context) =>
3737
BoardBloc(view: view)..add(const BoardEvent.initial()),
3838
child: BlocBuilder<BoardBloc, BoardState>(
39-
buildWhen: (previous, current) =>
40-
previous.loadingState != current.loadingState,
39+
buildWhen: (p, c) => p.loadingState != c.loadingState,
4140
builder: (context, state) {
4241
return state.loadingState.map(
4342
loading: (_) =>
@@ -84,43 +83,43 @@ class _BoardContentState extends State<BoardContent> {
8483
child: BlocBuilder<BoardBloc, BoardState>(
8584
buildWhen: (previous, current) => previous.groupIds != current.groupIds,
8685
builder: (context, state) {
87-
final theme = context.read<AppTheme>();
86+
final column = Column(
87+
children: [const _ToolbarBlocAdaptor(), _buildBoard(context)],
88+
);
89+
8890
return Container(
89-
color: theme.surface,
91+
color: context.read<AppTheme>().surface,
9092
child: Padding(
9193
padding: const EdgeInsets.symmetric(horizontal: 20),
92-
child: Column(
93-
children: [
94-
const _ToolbarBlocAdaptor(),
95-
Expanded(
96-
child: AFBoard(
97-
key: UniqueKey(),
98-
scrollManager: scrollManager,
99-
scrollController: scrollController,
100-
dataController: context.read<BoardBloc>().boardController,
101-
headerBuilder: _buildHeader,
102-
footBuilder: _buildFooter,
103-
cardBuilder: (_, column, columnItem) => _buildCard(
104-
context,
105-
column,
106-
columnItem,
107-
),
108-
columnConstraints:
109-
const BoxConstraints.tightFor(width: 300),
110-
config: AFBoardConfig(
111-
columnBackgroundColor: HexColor.fromHex('#F7F8FC'),
112-
),
113-
),
114-
),
115-
],
116-
),
94+
child: column,
11795
),
11896
);
11997
},
12098
),
12199
);
122100
}
123101

102+
Expanded _buildBoard(BuildContext context) {
103+
return Expanded(
104+
child: AFBoard(
105+
scrollManager: scrollManager,
106+
scrollController: scrollController,
107+
dataController: context.read<BoardBloc>().boardController,
108+
headerBuilder: _buildHeader,
109+
footBuilder: _buildFooter,
110+
cardBuilder: (_, column, columnItem) => _buildCard(
111+
context,
112+
column,
113+
columnItem,
114+
),
115+
columnConstraints: const BoxConstraints.tightFor(width: 300),
116+
config: AFBoardConfig(
117+
columnBackgroundColor: HexColor.fromHex('#F7F8FC'),
118+
),
119+
),
120+
);
121+
}
122+
124123
void _handleEditState(BoardState state, BuildContext context) {
125124
state.editingRow.fold(
126125
() => null,
@@ -152,6 +151,7 @@ class _BoardContentState extends State<BoardContent> {
152151
BuildContext context,
153152
AFBoardColumnData columnData,
154153
) {
154+
final boardCustomData = columnData.customData as BoardCustomData;
155155
return AppFlowyColumnHeader(
156156
title: Flexible(
157157
fit: FlexFit.tight,
@@ -162,6 +162,7 @@ class _BoardContentState extends State<BoardContent> {
162162
color: context.read<AppTheme>().textColor,
163163
),
164164
),
165+
icon: _buildHeaderIcon(boardCustomData),
165166
addIcon: SizedBox(
166167
height: 20,
167168
width: 20,
@@ -181,7 +182,9 @@ class _BoardContentState extends State<BoardContent> {
181182
}
182183

183184
Widget _buildFooter(BuildContext context, AFBoardColumnData columnData) {
184-
final group = columnData.customData as GroupPB;
185+
final boardCustomData = columnData.customData as BoardCustomData;
186+
final group = boardCustomData.group;
187+
185188
if (group.isDefault) {
186189
return const SizedBox();
187190
} else {
@@ -246,7 +249,7 @@ class _BoardContentState extends State<BoardContent> {
246249
child: BoardCard(
247250
gridId: gridId,
248251
groupId: column.id,
249-
fieldId: boardColumnItem.fieldId,
252+
fieldId: boardColumnItem.fieldContext.id,
250253
isEditing: isEditing,
251254
cellBuilder: cellBuilder,
252255
dataController: cardController,
@@ -319,3 +322,38 @@ extension HexColor on Color {
319322
return Color(int.parse(buffer.toString(), radix: 16));
320323
}
321324
}
325+
326+
Widget? _buildHeaderIcon(BoardCustomData customData) {
327+
Widget? widget;
328+
switch (customData.fieldType) {
329+
case FieldType.Checkbox:
330+
final group = customData.asCheckboxGroup()!;
331+
if (group.isCheck) {
332+
widget = svgWidget('editor/editor_check');
333+
} else {
334+
widget = svgWidget('editor/editor_uncheck');
335+
}
336+
break;
337+
case FieldType.DateTime:
338+
break;
339+
case FieldType.MultiSelect:
340+
break;
341+
case FieldType.Number:
342+
break;
343+
case FieldType.RichText:
344+
break;
345+
case FieldType.SingleSelect:
346+
break;
347+
case FieldType.URL:
348+
break;
349+
}
350+
351+
if (widget != null) {
352+
widget = SizedBox(
353+
width: 20,
354+
height: 20,
355+
child: widget,
356+
);
357+
}
358+
return widget;
359+
}

0 commit comments

Comments
 (0)