Skip to content

Commit c8b9097

Browse files
authored
Feat: support new column type, Checklist.
Feat/support checklist type
2 parents aa85970 + d89a891 commit c8b9097

File tree

75 files changed

+1295
-85
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+1295
-85
lines changed

frontend/app_flowy/assets/translations/en.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@
222222
"singleSelectFieldName": "Select",
223223
"multiSelectFieldName": "Multiselect",
224224
"urlFieldName": "URL",
225+
"checklistFieldName": "Checklist",
225226
"numberFormat": " Number format",
226227
"dateFormat": " Date format",
227228
"includeTime": " Include time",
@@ -264,6 +265,9 @@
264265
"panelTitle": "Select an option or create one",
265266
"searchOption": "Search for an option"
266267
},
268+
"checklist": {
269+
"panelTitle": "Search an option or create one"
270+
},
267271
"menuName": "Grid"
268272
},
269273
"document": {

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

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,3 @@ class BoardGroupService {
1010
groupField = field;
1111
}
1212
}
13-
14-
abstract class CanBeGroupField {
15-
String get groupContent;
16-
}
17-
18-
// class SingleSelectGroup extends CanBeGroupField {
19-
// final SingleSelectTypeOptionContext typeOptionContext;
20-
// }

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,8 @@ Widget? _buildHeaderIcon(GroupData customData) {
358358
break;
359359
case FieldType.URL:
360360
break;
361+
case FieldType.Checklist:
362+
break;
361363
}
362364

363365
if (widget != null) {
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
2+
import 'package:app_flowy/plugins/grid/application/cell/checklist_cell_bloc.dart';
3+
import 'package:app_flowy/plugins/grid/presentation/widgets/cell/checklist_cell/checklist_cell.dart';
4+
import 'package:flutter/material.dart';
5+
import 'package:flutter_bloc/flutter_bloc.dart';
6+
7+
class BoardChecklistCell extends StatefulWidget {
8+
final GridCellControllerBuilder cellControllerBuilder;
9+
const BoardChecklistCell({required this.cellControllerBuilder, Key? key})
10+
: super(key: key);
11+
12+
@override
13+
State<BoardChecklistCell> createState() => _BoardChecklistCellState();
14+
}
15+
16+
class _BoardChecklistCellState extends State<BoardChecklistCell> {
17+
late ChecklistCellBloc _cellBloc;
18+
19+
@override
20+
void initState() {
21+
final cellController =
22+
widget.cellControllerBuilder.build() as GridChecklistCellController;
23+
_cellBloc = ChecklistCellBloc(cellController: cellController);
24+
_cellBloc.add(const ChecklistCellEvent.initial());
25+
super.initState();
26+
}
27+
28+
@override
29+
Widget build(BuildContext context) {
30+
return BlocProvider.value(
31+
value: _cellBloc,
32+
child: const ChecklistProgressBar(),
33+
);
34+
}
35+
}

frontend/app_flowy/lib/plugins/board/presentation/card/card_cell_builder.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
44

55
import 'board_cell.dart';
66
import 'board_checkbox_cell.dart';
7+
import 'board_checklist_cell.dart';
78
import 'board_date_cell.dart';
89
import 'board_number_cell.dart';
910
import 'board_select_option_cell.dart';
@@ -58,6 +59,11 @@ class BoardCellBuilder {
5859
editableNotifier: cellNotifier,
5960
key: key,
6061
);
62+
case FieldType.Checklist:
63+
return BoardChecklistCell(
64+
cellControllerBuilder: cellControllerBuilder,
65+
key: key,
66+
);
6167
case FieldType.Number:
6268
return BoardNumberCell(
6369
groupId: groupId,

frontend/app_flowy/lib/plugins/grid/application/cell/cell_service/cell_controller.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ typedef GridCheckboxCellController = IGridCellController<String, String>;
55
typedef GridNumberCellController = IGridCellController<String, String>;
66
typedef GridSelectOptionCellController
77
= IGridCellController<SelectOptionCellDataPB, String>;
8+
typedef GridChecklistCellController
9+
= IGridCellController<SelectOptionCellDataPB, String>;
810
typedef GridDateCellController
911
= IGridCellController<DateCellDataPB, CalendarData>;
1012
typedef GridURLCellController = IGridCellController<URLCellDataPB, String>;
@@ -81,6 +83,7 @@ class GridCellControllerBuilder {
8183
);
8284
case FieldType.MultiSelect:
8385
case FieldType.SingleSelect:
86+
case FieldType.Checklist:
8487
final cellDataLoader = GridCellDataLoader(
8588
cellId: _cellId,
8689
parser: SelectOptionCellDataParser(),
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import 'package:flowy_sdk/log.dart';
2+
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
3+
import 'package:flutter_bloc/flutter_bloc.dart';
4+
import 'package:freezed_annotation/freezed_annotation.dart';
5+
import 'dart:async';
6+
import 'cell_service/cell_service.dart';
7+
import 'checklist_cell_editor_bloc.dart';
8+
import 'select_option_service.dart';
9+
part 'checklist_cell_bloc.freezed.dart';
10+
11+
class ChecklistCellBloc extends Bloc<ChecklistCellEvent, ChecklistCellState> {
12+
final GridChecklistCellController cellController;
13+
final SelectOptionFFIService _selectOptionService;
14+
void Function()? _onCellChangedFn;
15+
ChecklistCellBloc({
16+
required this.cellController,
17+
}) : _selectOptionService =
18+
SelectOptionFFIService(cellId: cellController.cellId),
19+
super(ChecklistCellState.initial(cellController)) {
20+
on<ChecklistCellEvent>(
21+
(event, emit) async {
22+
await event.when(
23+
initial: () async {
24+
_startListening();
25+
_loadOptions();
26+
},
27+
didReceiveOptions: (data) {
28+
emit(state.copyWith(
29+
allOptions: data.options,
30+
selectedOptions: data.selectOptions,
31+
percent: percentFromSelectOptionCellData(data),
32+
));
33+
},
34+
);
35+
},
36+
);
37+
}
38+
39+
@override
40+
Future<void> close() async {
41+
if (_onCellChangedFn != null) {
42+
cellController.removeListener(_onCellChangedFn!);
43+
_onCellChangedFn = null;
44+
}
45+
await cellController.dispose();
46+
return super.close();
47+
}
48+
49+
void _startListening() {
50+
_onCellChangedFn = cellController.startListening(
51+
onCellFieldChanged: () {
52+
_loadOptions();
53+
},
54+
onCellChanged: (data) {
55+
if (!isClosed && data != null) {
56+
add(ChecklistCellEvent.didReceiveOptions(data));
57+
}
58+
},
59+
);
60+
}
61+
62+
void _loadOptions() {
63+
_selectOptionService.getOptionContext().then((result) {
64+
if (isClosed) return;
65+
66+
return result.fold(
67+
(data) => add(ChecklistCellEvent.didReceiveOptions(data)),
68+
(err) => Log.error(err),
69+
);
70+
});
71+
}
72+
}
73+
74+
@freezed
75+
class ChecklistCellEvent with _$ChecklistCellEvent {
76+
const factory ChecklistCellEvent.initial() = _InitialCell;
77+
const factory ChecklistCellEvent.didReceiveOptions(
78+
SelectOptionCellDataPB data) = _DidReceiveCellUpdate;
79+
}
80+
81+
@freezed
82+
class ChecklistCellState with _$ChecklistCellState {
83+
const factory ChecklistCellState({
84+
required List<SelectOptionPB> allOptions,
85+
required List<SelectOptionPB> selectedOptions,
86+
required double percent,
87+
}) = _ChecklistCellState;
88+
89+
factory ChecklistCellState.initial(
90+
GridChecklistCellController cellController) {
91+
return const ChecklistCellState(
92+
allOptions: [],
93+
selectedOptions: [],
94+
percent: 0,
95+
);
96+
}
97+
}

0 commit comments

Comments
 (0)