feat: support multi-select option filter (#1501)

Co-authored-by: nathan <nathan@appflowy.io>
This commit is contained in:
Nathan.fooo 2022-11-28 22:49:13 +08:00 committed by GitHub
parent bc70b04110
commit 80d1cbabe0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 147 additions and 85 deletions

View file

@ -529,7 +529,7 @@ class FieldInfo {
switch (_field.fieldType) { switch (_field.fieldType) {
case FieldType.Checkbox: case FieldType.Checkbox:
// case FieldType.MultiSelect: case FieldType.MultiSelect:
case FieldType.RichText: case FieldType.RichText:
case FieldType.SingleSelect: case FieldType.SingleSelect:
return true; return true;

View file

@ -109,15 +109,16 @@ class TypeOptionContext<T extends GeneratedMessage> {
String get fieldId => _dataController.field.id; String get fieldId => _dataController.field.id;
Future<void> loadTypeOptionData({ Future<T> loadTypeOptionData({
required void Function(T) onCompleted, void Function(T)? onCompleted,
required void Function(FlowyError) onError, required void Function(FlowyError) onError,
}) async { }) async {
await _dataController.loadTypeOptionData().then((result) { await _dataController.loadTypeOptionData().then((result) {
result.fold((l) => null, (err) => onError(err)); result.fold((l) => null, (err) => onError(err));
}); });
onCompleted(typeOption); onCompleted?.call(typeOption);
return typeOption;
} }
T get typeOption { T get typeOption {

View file

@ -33,14 +33,14 @@ class TypeOptionDataController {
} }
} }
Future<Either<Unit, FlowyError>> loadTypeOptionData() async { Future<Either<TypeOptionPB, FlowyError>> loadTypeOptionData() async {
final result = await loader.load(); final result = await loader.load();
return result.fold( return result.fold(
(data) { (data) {
data.freeze(); data.freeze();
_data = data; _data = data;
_fieldNotifier.value = data.field_2; _fieldNotifier.value = data.field_2;
return left(unit); return left(data);
}, },
(err) { (err) {
Log.error(err); Log.error(err);

View file

@ -31,15 +31,15 @@ class CheckboxFilterEditorBloc
updateCondition: (CheckboxFilterCondition condition) { updateCondition: (CheckboxFilterCondition condition) {
_ffiService.insertCheckboxFilter( _ffiService.insertCheckboxFilter(
filterId: filterInfo.filter.id, filterId: filterInfo.filter.id,
fieldId: filterInfo.field.id, fieldId: filterInfo.fieldInfo.id,
condition: condition, condition: condition,
); );
}, },
delete: () { delete: () {
_ffiService.deleteFilter( _ffiService.deleteFilter(
fieldId: filterInfo.field.id, fieldId: filterInfo.fieldInfo.id,
filterId: filterInfo.filter.id, filterId: filterInfo.filter.id,
fieldType: filterInfo.field.fieldType, fieldType: filterInfo.fieldInfo.fieldType,
); );
}, },
didReceiveFilter: (FilterPB filter) { didReceiveFilter: (FilterPB filter) {

View file

@ -1,7 +1,5 @@
import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart'; import 'package:app_flowy/plugins/grid/presentation/widgets/filter/choicechip/select_option/select_option_loader.dart';
import 'package:app_flowy/plugins/grid/presentation/widgets/filter/filter_info.dart'; import 'package:app_flowy/plugins/grid/presentation/widgets/filter/filter_info.dart';
import 'package:app_flowy/plugins/grid/presentation/widgets/header/type_option/builder.dart';
import 'package:flowy_sdk/log.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/select_option_filter.pbserver.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/select_option_filter.pbserver.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/util.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/util.pb.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
@ -17,18 +15,16 @@ class SelectOptionFilterEditorBloc
final FilterInfo filterInfo; final FilterInfo filterInfo;
final FilterFFIService _ffiService; final FilterFFIService _ffiService;
final FilterListener _listener; final FilterListener _listener;
final SingleSelectTypeOptionContext typeOptionContext; final SelectOptionFilterDelegate delegate;
SelectOptionFilterEditorBloc({required this.filterInfo}) SelectOptionFilterEditorBloc({
: _ffiService = FilterFFIService(viewId: filterInfo.viewId), required this.filterInfo,
required this.delegate,
}) : _ffiService = FilterFFIService(viewId: filterInfo.viewId),
_listener = FilterListener( _listener = FilterListener(
viewId: filterInfo.viewId, viewId: filterInfo.viewId,
filterId: filterInfo.filter.id, filterId: filterInfo.filter.id,
), ),
typeOptionContext = makeSingleSelectTypeOptionContext(
gridId: filterInfo.viewId,
fieldPB: filterInfo.field.field,
),
super(SelectOptionFilterEditorState.initial(filterInfo)) { super(SelectOptionFilterEditorState.initial(filterInfo)) {
on<SelectOptionFilterEditorEvent>( on<SelectOptionFilterEditorEvent>(
(event, emit) async { (event, emit) async {
@ -40,26 +36,26 @@ class SelectOptionFilterEditorBloc
updateCondition: (SelectOptionCondition condition) { updateCondition: (SelectOptionCondition condition) {
_ffiService.insertSelectOptionFilter( _ffiService.insertSelectOptionFilter(
filterId: filterInfo.filter.id, filterId: filterInfo.filter.id,
fieldId: filterInfo.field.id, fieldId: filterInfo.fieldInfo.id,
condition: condition, condition: condition,
optionIds: state.filter.optionIds, optionIds: state.filter.optionIds,
fieldType: state.filterInfo.field.fieldType, fieldType: state.filterInfo.fieldInfo.fieldType,
); );
}, },
updateContent: (List<String> optionIds) { updateContent: (List<String> optionIds) {
_ffiService.insertSelectOptionFilter( _ffiService.insertSelectOptionFilter(
filterId: filterInfo.filter.id, filterId: filterInfo.filter.id,
fieldId: filterInfo.field.id, fieldId: filterInfo.fieldInfo.id,
condition: state.filter.condition, condition: state.filter.condition,
optionIds: optionIds, optionIds: optionIds,
fieldType: state.filterInfo.field.fieldType, fieldType: state.filterInfo.fieldInfo.fieldType,
); );
}, },
delete: () { delete: () {
_ffiService.deleteFilter( _ffiService.deleteFilter(
fieldId: filterInfo.field.id, fieldId: filterInfo.fieldInfo.id,
filterId: filterInfo.filter.id, filterId: filterInfo.filter.id,
fieldType: filterInfo.field.fieldType, fieldType: filterInfo.fieldInfo.fieldType,
); );
}, },
didReceiveFilter: (FilterPB filter) { didReceiveFilter: (FilterPB filter) {
@ -92,21 +88,17 @@ class SelectOptionFilterEditorBloc
} }
void _loadOptions() { void _loadOptions() {
typeOptionContext.loadTypeOptionData( delegate.loadOptions().then((options) {
onCompleted: (value) { if (!isClosed) {
if (!isClosed) { String filterDesc = '';
String filterDesc = ''; for (final option in options) {
for (final option in value.options) { if (state.filter.optionIds.contains(option.id)) {
if (state.filter.optionIds.contains(option.id)) { filterDesc += "${option.name} ";
filterDesc += "${option.name} ";
}
} }
add(SelectOptionFilterEditorEvent.updateFilterDescription(
filterDesc));
} }
}, add(SelectOptionFilterEditorEvent.updateFilterDescription(filterDesc));
onError: (error) => Log.error(error), }
); });
} }
@override @override

View file

@ -1,8 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart'; import 'package:app_flowy/plugins/grid/presentation/widgets/filter/choicechip/select_option/select_option_loader.dart';
import 'package:app_flowy/plugins/grid/presentation/widgets/header/type_option/builder.dart';
import 'package:flowy_sdk/log.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
@ -12,16 +10,13 @@ part 'select_option_filter_list_bloc.freezed.dart';
class SelectOptionFilterListBloc<T> class SelectOptionFilterListBloc<T>
extends Bloc<SelectOptionFilterListEvent, SelectOptionFilterListState> { extends Bloc<SelectOptionFilterListEvent, SelectOptionFilterListState> {
final SingleSelectTypeOptionContext typeOptionContext; final SelectOptionFilterDelegate delegate;
SelectOptionFilterListBloc({ SelectOptionFilterListBloc({
required String viewId, required String viewId,
required FieldPB fieldPB, required FieldPB fieldPB,
required this.delegate,
required List<String> selectedOptionIds, required List<String> selectedOptionIds,
}) : typeOptionContext = makeSingleSelectTypeOptionContext( }) : super(SelectOptionFilterListState.initial(selectedOptionIds)) {
gridId: viewId,
fieldPB: fieldPB,
),
super(SelectOptionFilterListState.initial(selectedOptionIds)) {
on<SelectOptionFilterListEvent>( on<SelectOptionFilterListEvent>(
(event, emit) async { (event, emit) async {
await event.when( await event.when(
@ -103,14 +98,11 @@ class SelectOptionFilterListBloc<T>
} }
void _loadOptions() { void _loadOptions() {
typeOptionContext.loadTypeOptionData( delegate.loadOptions().then((options) {
onCompleted: (value) { if (!isClosed) {
if (!isClosed) { add(SelectOptionFilterListEvent.didReceiveOptions(options));
add(SelectOptionFilterListEvent.didReceiveOptions(value.options)); }
} });
},
onError: (error) => Log.error(error),
);
} }
void _startListening() {} void _startListening() {}

View file

@ -31,7 +31,7 @@ class TextFilterEditorBloc
updateCondition: (TextFilterCondition condition) { updateCondition: (TextFilterCondition condition) {
_ffiService.insertTextFilter( _ffiService.insertTextFilter(
filterId: filterInfo.filter.id, filterId: filterInfo.filter.id,
fieldId: filterInfo.field.id, fieldId: filterInfo.fieldInfo.id,
condition: condition, condition: condition,
content: state.filter.content, content: state.filter.content,
); );
@ -39,16 +39,16 @@ class TextFilterEditorBloc
updateContent: (content) { updateContent: (content) {
_ffiService.insertTextFilter( _ffiService.insertTextFilter(
filterId: filterInfo.filter.id, filterId: filterInfo.filter.id,
fieldId: filterInfo.field.id, fieldId: filterInfo.fieldInfo.id,
condition: state.filter.condition, condition: state.filter.condition,
content: content, content: content,
); );
}, },
delete: () { delete: () {
_ffiService.deleteFilter( _ffiService.deleteFilter(
fieldId: filterInfo.field.id, fieldId: filterInfo.fieldInfo.id,
filterId: filterInfo.filter.id, filterId: filterInfo.filter.id,
fieldType: filterInfo.field.fieldType, fieldType: filterInfo.fieldInfo.fieldType,
); );
}, },
didReceiveFilter: (FilterPB filter) { didReceiveFilter: (FilterPB filter) {

View file

@ -107,7 +107,7 @@ class _CheckboxFilterEditorState extends State<CheckboxFilterEditor> {
height: 20, height: 20,
child: Row( child: Row(
children: [ children: [
FlowyText(state.filterInfo.field.name), FlowyText(state.filterInfo.fieldInfo.name),
const HSpace(4), const HSpace(4),
CheckboxFilterConditionList( CheckboxFilterConditionList(
filterInfo: state.filterInfo, filterInfo: state.filterInfo,

View file

@ -37,11 +37,11 @@ class ChoiceChipButton extends StatelessWidget {
child: FlowyButton( child: FlowyButton(
decoration: decoration, decoration: decoration,
useIntrinsicWidth: true, useIntrinsicWidth: true,
text: FlowyText(filterInfo.field.name, fontSize: 12), text: FlowyText(filterInfo.fieldInfo.name, fontSize: 12),
margin: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), margin: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
radius: const BorderRadius.all(Radius.circular(14)), radius: const BorderRadius.all(Radius.circular(14)),
leftIcon: svgWidget( leftIcon: svgWidget(
filterInfo.field.fieldType.iconName(), filterInfo.fieldInfo.fieldType.iconName(),
color: Theme.of(context).colorScheme.onSurface, color: Theme.of(context).colorScheme.onSurface,
), ),
rightIcon: _ChoicechipFilterDesc(filterDesc: filterDesc), rightIcon: _ChoicechipFilterDesc(filterDesc: filterDesc),

View file

@ -32,7 +32,7 @@ class SelectOptionFilterConditionList extends StatelessWidget {
(action) => ConditionWrapper( (action) => ConditionWrapper(
action, action,
selectOptionFilter.condition == action, selectOptionFilter.condition == action,
filterInfo.field.fieldType, filterInfo.fieldInfo.fieldType,
), ),
) )
.toList(), .toList(),
@ -50,7 +50,7 @@ class SelectOptionFilterConditionList extends StatelessWidget {
} }
String filterName(SelectOptionFilterPB filter) { String filterName(SelectOptionFilterPB filter) {
if (filterInfo.field.fieldType == FieldType.SingleSelect) { if (filterInfo.fieldInfo.fieldType == FieldType.SingleSelect) {
return filter.condition.singleSelectFilterName; return filter.condition.singleSelectFilterName;
} else { } else {
return filter.condition.multiSelectFilterName; return filter.condition.multiSelectFilterName;

View file

@ -1,22 +1,23 @@
import 'package:app_flowy/plugins/grid/application/field/field_controller.dart';
import 'package:app_flowy/plugins/grid/application/filter/select_option_filter_list_bloc.dart'; import 'package:app_flowy/plugins/grid/application/filter/select_option_filter_list_bloc.dart';
import 'package:app_flowy/plugins/grid/presentation/layout/sizes.dart'; import 'package:app_flowy/plugins/grid/presentation/layout/sizes.dart';
import 'package:app_flowy/plugins/grid/presentation/widgets/cell/select_option_cell/extension.dart'; import 'package:app_flowy/plugins/grid/presentation/widgets/cell/select_option_cell/extension.dart';
import 'package:app_flowy/plugins/grid/presentation/widgets/filter/filter_info.dart';
import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/image.dart';
import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart'; import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pbenum.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.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 'select_option_loader.dart';
class SelectOptionFilterList extends StatelessWidget { class SelectOptionFilterList extends StatelessWidget {
final String viewId; final FilterInfo filterInfo;
final FieldInfo fieldInfo;
final List<String> selectedOptionIds; final List<String> selectedOptionIds;
final Function(List<String>) onSelectedOptions; final Function(List<String>) onSelectedOptions;
const SelectOptionFilterList({ const SelectOptionFilterList({
required this.viewId, required this.filterInfo,
required this.fieldInfo,
required this.selectedOptionIds, required this.selectedOptionIds,
required this.onSelectedOptions, required this.onSelectedOptions,
Key? key, Key? key,
@ -25,11 +26,27 @@ class SelectOptionFilterList extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider( return BlocProvider(
create: (context) => SelectOptionFilterListBloc( create: (context) {
viewId: viewId, late SelectOptionFilterListBloc bloc;
fieldPB: fieldInfo.field, if (filterInfo.fieldInfo.fieldType == FieldType.SingleSelect) {
selectedOptionIds: selectedOptionIds, bloc = SelectOptionFilterListBloc(
)..add(const SelectOptionFilterListEvent.initial()), viewId: filterInfo.viewId,
fieldPB: filterInfo.fieldInfo.field,
selectedOptionIds: selectedOptionIds,
delegate: SingleSelectOptionFilterDelegateImpl(filterInfo),
);
} else {
bloc = SelectOptionFilterListBloc(
viewId: filterInfo.viewId,
fieldPB: filterInfo.fieldInfo.field,
selectedOptionIds: selectedOptionIds,
delegate: MultiSelectOptionFilterDelegateImpl(filterInfo),
);
}
bloc.add(const SelectOptionFilterListEvent.initial());
return bloc;
},
child: child:
BlocListener<SelectOptionFilterListBloc, SelectOptionFilterListState>( BlocListener<SelectOptionFilterListBloc, SelectOptionFilterListState>(
listenWhen: (previous, current) => listenWhen: (previous, current) =>

View file

@ -6,6 +6,7 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart'; import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/select_option_filter.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/select_option_filter.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';
@ -13,6 +14,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import '../choicechip.dart'; import '../choicechip.dart';
import 'condition_list.dart'; import 'condition_list.dart';
import 'option_list.dart'; import 'option_list.dart';
import 'select_option_loader.dart';
class SelectOptionFilterChoicechip extends StatefulWidget { class SelectOptionFilterChoicechip extends StatefulWidget {
final FilterInfo filterInfo; final FilterInfo filterInfo;
@ -30,8 +32,18 @@ class _SelectOptionFilterChoicechipState
@override @override
void initState() { void initState() {
bloc = SelectOptionFilterEditorBloc(filterInfo: widget.filterInfo) if (widget.filterInfo.fieldInfo.fieldType == FieldType.SingleSelect) {
..add(const SelectOptionFilterEditorEvent.initial()); bloc = SelectOptionFilterEditorBloc(
filterInfo: widget.filterInfo,
delegate: SingleSelectOptionFilterDelegateImpl(widget.filterInfo),
);
} else {
bloc = SelectOptionFilterEditorBloc(
filterInfo: widget.filterInfo,
delegate: MultiSelectOptionFilterDelegateImpl(widget.filterInfo),
);
}
bloc.add(const SelectOptionFilterEditorEvent.initial());
super.initState(); super.initState();
} }
@ -97,8 +109,7 @@ class _SelectOptionFilterEditorState extends State<SelectOptionFilterEditor> {
slivers.add( slivers.add(
SliverToBoxAdapter( SliverToBoxAdapter(
child: SelectOptionFilterList( child: SelectOptionFilterList(
viewId: state.filterInfo.viewId, filterInfo: state.filterInfo,
fieldInfo: state.filterInfo.field,
selectedOptionIds: state.filter.optionIds, selectedOptionIds: state.filter.optionIds,
onSelectedOptions: (optionIds) { onSelectedOptions: (optionIds) {
context.read<SelectOptionFilterEditorBloc>().add( context.read<SelectOptionFilterEditorBloc>().add(
@ -129,7 +140,7 @@ class _SelectOptionFilterEditorState extends State<SelectOptionFilterEditor> {
height: 20, height: 20,
child: Row( child: Row(
children: [ children: [
FlowyText(state.filterInfo.field.name), FlowyText(state.filterInfo.fieldInfo.name),
const HSpace(4), const HSpace(4),
SelectOptionFilterConditionList( SelectOptionFilterConditionList(
filterInfo: state.filterInfo, filterInfo: state.filterInfo,

View file

@ -0,0 +1,49 @@
import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart';
import 'package:app_flowy/plugins/grid/presentation/widgets/filter/filter_info.dart';
import 'package:app_flowy/plugins/grid/presentation/widgets/header/type_option/builder.dart';
import 'package:flowy_sdk/log.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
abstract class SelectOptionFilterDelegate {
Future<List<SelectOptionPB>> loadOptions();
}
class SingleSelectOptionFilterDelegateImpl
implements SelectOptionFilterDelegate {
final SingleSelectTypeOptionContext typeOptionContext;
SingleSelectOptionFilterDelegateImpl(FilterInfo filterInfo)
: typeOptionContext = makeSingleSelectTypeOptionContext(
gridId: filterInfo.viewId,
fieldPB: filterInfo.fieldInfo.field,
);
@override
Future<List<SelectOptionPB>> loadOptions() {
return typeOptionContext
.loadTypeOptionData(
onError: (error) => Log.error(error),
)
.then((value) => value.options);
}
}
class MultiSelectOptionFilterDelegateImpl
implements SelectOptionFilterDelegate {
final MultiSelectTypeOptionContext typeOptionContext;
MultiSelectOptionFilterDelegateImpl(FilterInfo filterInfo)
: typeOptionContext = makeMultiSelectTypeOptionContext(
gridId: filterInfo.viewId,
fieldPB: filterInfo.fieldInfo.field,
);
@override
Future<List<SelectOptionPB>> loadOptions() {
return typeOptionContext
.loadTypeOptionData(
onError: (error) => Log.error(error),
)
.then((value) => value.options);
}
}

View file

@ -120,7 +120,7 @@ class _TextFilterEditorState extends State<TextFilterEditor> {
height: 20, height: 20,
child: Row( child: Row(
children: [ children: [
FlowyText(state.filterInfo.field.name), FlowyText(state.filterInfo.fieldInfo.name),
const HSpace(4), const HSpace(4),
TextFilterConditionList( TextFilterConditionList(
filterInfo: state.filterInfo, filterInfo: state.filterInfo,

View file

@ -9,15 +9,15 @@ import 'package:flowy_sdk/protobuf/flowy-grid/util.pb.dart';
class FilterInfo { class FilterInfo {
final String viewId; final String viewId;
final FilterPB filter; final FilterPB filter;
final FieldInfo field; final FieldInfo fieldInfo;
FilterInfo(this.viewId, this.filter, this.field); FilterInfo(this.viewId, this.filter, this.fieldInfo);
FilterInfo copyWith({FilterPB? filter, FieldInfo? field}) { FilterInfo copyWith({FilterPB? filter, FieldInfo? fieldInfo}) {
return FilterInfo( return FilterInfo(
viewId, viewId,
filter ?? this.filter, filter ?? this.filter,
field ?? this.field, fieldInfo ?? this.fieldInfo,
); );
} }

View file

@ -20,7 +20,7 @@ class FilterMenuItem extends StatelessWidget {
} }
Widget buildFilterChoicechip(FilterInfo filterInfo) { Widget buildFilterChoicechip(FilterInfo filterInfo) {
switch (filterInfo.field.fieldType) { switch (filterInfo.fieldInfo.fieldType) {
case FieldType.Checkbox: case FieldType.Checkbox:
return CheckboxFilterChoicechip(filterInfo: filterInfo); return CheckboxFilterChoicechip(filterInfo: filterInfo);
case FieldType.DateTime: case FieldType.DateTime: