chore: multi select

This commit is contained in:
appflowy 2022-03-31 14:59:57 +08:00
parent 4b27fef76e
commit 7c6a857a69
5 changed files with 92 additions and 18 deletions

View File

@ -0,0 +1,3 @@
<svg width="10" height="8" viewBox="0 0 10 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 5.2L2.84615 7L9 1" stroke="#00BCF0" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 198 B

View File

@ -221,8 +221,8 @@ void _resolveGridDeps(GetIt getIt) {
(typeOption, fieldId) => SingleSelectTypeOptionBloc(typeOption, fieldId),
);
getIt.registerFactoryParam<MultiSelectTypeOptionBloc, MultiSelectTypeOption, void>(
(typeOption, _) => MultiSelectTypeOptionBloc(typeOption),
getIt.registerFactoryParam<MultiSelectTypeOptionBloc, MultiSelectTypeOption, String>(
(typeOption, fieldId) => MultiSelectTypeOptionBloc(typeOption, fieldId),
);
getIt.registerFactoryParam<DateTypeOptionBloc, DateTypeOption, void>(

View File

@ -1,18 +1,37 @@
import 'dart:typed_data';
import 'package:flowy_sdk/log.dart';
import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'dart:async';
import 'package:protobuf/protobuf.dart';
import 'type_option_service.dart';
part 'multi_select_bloc.freezed.dart';
class MultiSelectTypeOptionBloc extends Bloc<MultiSelectTypeOptionEvent, MultiSelectTypeOptionState> {
MultiSelectTypeOptionBloc(MultiSelectTypeOption typeOption) : super(MultiSelectTypeOptionState.initial(typeOption)) {
final TypeOptionService service;
MultiSelectTypeOptionBloc(MultiSelectTypeOption typeOption, String fieldId)
: service = TypeOptionService(fieldId: fieldId),
super(MultiSelectTypeOptionState.initial(typeOption)) {
on<MultiSelectTypeOptionEvent>(
(event, emit) async {
await event.map(
createOption: (_CreateOption value) {},
updateOptions: (_UpdateOptions value) async {},
createOption: (_CreateOption value) async {
final result = await service.createOption(value.optionName);
result.fold(
(option) {
emit(state.copyWith(typeOption: _insertOption(option)));
},
(err) => Log.error(err),
);
},
updateOption: (_UpdateOption value) async {
emit(state.copyWith(typeOption: _updateOption(value.option)));
},
deleteOption: (_DeleteOption value) {
emit(state.copyWith(typeOption: _deleteOption(value.option)));
},
);
},
);
@ -22,12 +41,40 @@ class MultiSelectTypeOptionBloc extends Bloc<MultiSelectTypeOptionEvent, MultiSe
Future<void> close() async {
return super.close();
}
MultiSelectTypeOption _insertOption(SelectOption option) {
state.typeOption.freeze();
return state.typeOption.rebuild((typeOption) {
typeOption.options.insert(0, option);
});
}
MultiSelectTypeOption _updateOption(SelectOption option) {
state.typeOption.freeze();
return state.typeOption.rebuild((typeOption) {
final index = typeOption.options.indexWhere((element) => element.id == option.id);
if (index != -1) {
typeOption.options[index] = option;
}
});
}
MultiSelectTypeOption _deleteOption(SelectOption option) {
state.typeOption.freeze();
return state.typeOption.rebuild((typeOption) {
final index = typeOption.options.indexWhere((element) => element.id == option.id);
if (index != -1) {
typeOption.options.removeAt(index);
}
});
}
}
@freezed
class MultiSelectTypeOptionEvent with _$MultiSelectTypeOptionEvent {
const factory MultiSelectTypeOptionEvent.createOption(String optionName) = _CreateOption;
const factory MultiSelectTypeOptionEvent.updateOptions(List<SelectOption> options) = _UpdateOptions;
const factory MultiSelectTypeOptionEvent.updateOption(SelectOption option) = _UpdateOption;
const factory MultiSelectTypeOptionEvent.deleteOption(SelectOption option) = _DeleteOption;
}
@freezed

View File

@ -156,7 +156,7 @@ TypeOptionBuilder _makeTypeOptionBuild({
case FieldType.SingleSelect:
return SingleSelectTypeOptionBuilder(field.id, data, overlayDelegate, dataDelegate);
case FieldType.MultiSelect:
return MultiSelectTypeOptionBuilder(data, overlayDelegate);
return MultiSelectTypeOptionBuilder(field.id, data, overlayDelegate, dataDelegate);
case FieldType.Number:
return NumberTypeOptionBuilder(data, overlayDelegate, dataDelegate);
case FieldType.RichText:

View File

@ -8,26 +8,45 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'option_pannel.dart';
class MultiSelectTypeOptionBuilder extends TypeOptionBuilder {
MultiSelectTypeOption typeOption;
TypeOptionOverlayDelegate delegate;
MultiSelectTypeOptionWidget _widget;
MultiSelectTypeOptionBuilder(TypeOptionData typeOptionData, this.delegate)
: typeOption = MultiSelectTypeOption.fromBuffer(typeOptionData);
MultiSelectTypeOptionBuilder(
String fieldId,
TypeOptionData typeOptionData,
TypeOptionOverlayDelegate overlayDelegate,
TypeOptionDataDelegate dataDelegate,
) : _widget = MultiSelectTypeOptionWidget(
fieldId: fieldId,
typeOption: MultiSelectTypeOption.fromBuffer(typeOptionData),
overlayDelegate: overlayDelegate,
dataDelegate: dataDelegate,
);
@override
Widget? get customWidget => MultiSelectTypeOptionWidget(typeOption, delegate);
Widget? get customWidget => _widget;
}
class MultiSelectTypeOptionWidget extends TypeOptionWidget {
final String fieldId;
final MultiSelectTypeOption typeOption;
final TypeOptionOverlayDelegate overlayDelegate;
const MultiSelectTypeOptionWidget(this.typeOption, this.overlayDelegate, {Key? key}) : super(key: key);
final TypeOptionDataDelegate dataDelegate;
const MultiSelectTypeOptionWidget({
required this.fieldId,
required this.typeOption,
required this.overlayDelegate,
required this.dataDelegate,
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => getIt<MultiSelectTypeOptionBloc>(param1: typeOption),
child: BlocBuilder<MultiSelectTypeOptionBloc, MultiSelectTypeOptionState>(
create: (context) => getIt<MultiSelectTypeOptionBloc>(param1: typeOption, param2: fieldId),
child: BlocConsumer<MultiSelectTypeOptionBloc, MultiSelectTypeOptionState>(
listener: (context, state) {
dataDelegate.didUpdateTypeOptionData(state.typeOption.writeToBuffer());
},
builder: (context, state) {
return OptionPannel(
options: state.typeOption.options,
@ -37,9 +56,14 @@ class MultiSelectTypeOptionWidget extends TypeOptionWidget {
createOptionCallback: (name) {
context.read<MultiSelectTypeOptionBloc>().add(MultiSelectTypeOptionEvent.createOption(name));
},
updateOptionCallback: (updateOption) {},
deleteOptionCallback: (deleteOption) {},
updateOptionCallback: (updateOption) {
context.read<MultiSelectTypeOptionBloc>().add(MultiSelectTypeOptionEvent.updateOption(updateOption));
},
deleteOptionCallback: (deleteOption) {
context.read<MultiSelectTypeOptionBloc>().add(MultiSelectTypeOptionEvent.deleteOption(deleteOption));
},
overlayDelegate: overlayDelegate,
key: ValueKey(state.typeOption.hashCode),
);
},
),