mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: add option & color selection
This commit is contained in:
parent
55b888e364
commit
065a72a8da
4
frontend/app_flowy/assets/images/grid/details.svg
Normal file
4
frontend/app_flowy/assets/images/grid/details.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="8" cy="6" r="1" fill="#333333"/>
|
||||
<circle cx="8" cy="10" r="1" fill="#333333"/>
|
||||
</svg>
|
After Width: | Height: | Size: 194 B |
@ -167,6 +167,17 @@
|
||||
"addSelectOption": "Add an option",
|
||||
"optionTitle": "Options",
|
||||
"addOption": "Add option"
|
||||
},
|
||||
"selectOption": {
|
||||
"purpleColor": "Purple",
|
||||
"pinkColor": "Pink",
|
||||
"lightPinkColor": "Light Pink",
|
||||
"orangeColor": "Orange",
|
||||
"yellowColor": "Yellow",
|
||||
"limeColor": "Lime",
|
||||
"greenColor": "Green",
|
||||
"aquaColor": "Aqua",
|
||||
"blueColor": "Blue"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import 'package:app_flowy/user/application/user_listener.dart';
|
||||
import 'package:app_flowy/user/application/user_service.dart';
|
||||
import 'package:app_flowy/workspace/application/app/prelude.dart';
|
||||
import 'package:app_flowy/workspace/application/doc/prelude.dart';
|
||||
import 'package:app_flowy/workspace/application/grid/field/type_option/multi_select_bloc.dart';
|
||||
import 'package:app_flowy/workspace/application/grid/prelude.dart';
|
||||
import 'package:app_flowy/workspace/application/grid/row/row_listener.dart';
|
||||
import 'package:app_flowy/workspace/application/trash/prelude.dart';
|
||||
@ -20,6 +21,7 @@ import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/number_type_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
|
||||
@ -215,8 +217,12 @@ void _resolveGridDeps(GetIt getIt) {
|
||||
(context, _) => FieldTypeSwitchBloc(context),
|
||||
);
|
||||
|
||||
getIt.registerFactory<SelectionTypeOptionBloc>(
|
||||
() => SelectionTypeOptionBloc(),
|
||||
getIt.registerFactoryParam<SingleSelectTypeOptionBloc, SingleSelectTypeOption, String>(
|
||||
(typeOption, fieldId) => SingleSelectTypeOptionBloc(typeOption, fieldId),
|
||||
);
|
||||
|
||||
getIt.registerFactoryParam<MultiSelectTypeOptionBloc, MultiSelectTypeOption, void>(
|
||||
(typeOption, _) => MultiSelectTypeOptionBloc(typeOption),
|
||||
);
|
||||
|
||||
getIt.registerFactoryParam<DateTypeOptionBloc, DateTypeOption, void>(
|
||||
|
@ -1,5 +1,3 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||
|
@ -0,0 +1,42 @@
|
||||
import 'dart:typed_data';
|
||||
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';
|
||||
|
||||
part 'multi_select_bloc.freezed.dart';
|
||||
|
||||
class MultiSelectTypeOptionBloc extends Bloc<MultiSelectTypeOptionEvent, MultiSelectTypeOptionState> {
|
||||
MultiSelectTypeOptionBloc(MultiSelectTypeOption typeOption) : super(MultiSelectTypeOptionState.initial(typeOption)) {
|
||||
on<MultiSelectTypeOptionEvent>(
|
||||
(event, emit) async {
|
||||
await event.map(
|
||||
createOption: (_CreateOption value) {},
|
||||
updateOptions: (_UpdateOptions value) async {},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
return super.close();
|
||||
}
|
||||
}
|
||||
|
||||
@freezed
|
||||
class MultiSelectTypeOptionEvent with _$MultiSelectTypeOptionEvent {
|
||||
const factory MultiSelectTypeOptionEvent.createOption(String optionName) = _CreateOption;
|
||||
const factory MultiSelectTypeOptionEvent.updateOptions(List<SelectOption> options) = _UpdateOptions;
|
||||
}
|
||||
|
||||
@freezed
|
||||
class MultiSelectTypeOptionState with _$MultiSelectTypeOptionState {
|
||||
const factory MultiSelectTypeOptionState({
|
||||
required MultiSelectTypeOption typeOption,
|
||||
}) = _MultiSelectTypeOptionState;
|
||||
|
||||
factory MultiSelectTypeOptionState.initial(MultiSelectTypeOption typeOption) => MultiSelectTypeOptionState(
|
||||
typeOption: typeOption,
|
||||
);
|
||||
}
|
@ -1,13 +1,8 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.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:dartz/dartz.dart';
|
||||
|
||||
part 'option_pannel_bloc.freezed.dart';
|
||||
|
||||
class OptionPannelBloc extends Bloc<OptionPannelEvent, OptionPannelState> {
|
||||
@ -16,13 +11,13 @@ class OptionPannelBloc extends Bloc<OptionPannelEvent, OptionPannelState> {
|
||||
(event, emit) async {
|
||||
await event.map(
|
||||
createOption: (_CreateOption value) async {
|
||||
emit(state.copyWith(isAddingOption: false));
|
||||
emit(state.copyWith(isEditingOption: false, newOptionName: Some(value.optionName)));
|
||||
},
|
||||
beginAddingOption: (_BeginAddingOption value) {
|
||||
emit(state.copyWith(isAddingOption: true));
|
||||
emit(state.copyWith(isEditingOption: true, newOptionName: none()));
|
||||
},
|
||||
endAddingOption: (_EndAddingOption value) {
|
||||
emit(state.copyWith(isAddingOption: false));
|
||||
emit(state.copyWith(isEditingOption: false, newOptionName: none()));
|
||||
},
|
||||
);
|
||||
},
|
||||
@ -46,11 +41,13 @@ class OptionPannelEvent with _$OptionPannelEvent {
|
||||
class OptionPannelState with _$OptionPannelState {
|
||||
const factory OptionPannelState({
|
||||
required List<SelectOption> options,
|
||||
required bool isAddingOption,
|
||||
required bool isEditingOption,
|
||||
required Option<String> newOptionName,
|
||||
}) = _OptionPannelState;
|
||||
|
||||
factory OptionPannelState.initial(List<SelectOption> options) => OptionPannelState(
|
||||
options: options,
|
||||
isAddingOption: false,
|
||||
isEditingOption: false,
|
||||
newOptionName: none(),
|
||||
);
|
||||
}
|
||||
|
@ -1,39 +0,0 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
import 'package:dartz/dartz.dart';
|
||||
|
||||
part 'selection_bloc.freezed.dart';
|
||||
|
||||
class SelectionTypeOptionBloc extends Bloc<SelectionTypeOptionEvent, SelectionTypeOptionState> {
|
||||
SelectionTypeOptionBloc() : super(SelectionTypeOptionState.initial()) {
|
||||
on<SelectionTypeOptionEvent>(
|
||||
(event, emit) async {
|
||||
await event.map(
|
||||
initial: (_InitialField value) async {},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
return super.close();
|
||||
}
|
||||
}
|
||||
|
||||
@freezed
|
||||
class SelectionTypeOptionEvent with _$SelectionTypeOptionEvent {
|
||||
const factory SelectionTypeOptionEvent.initial(Uint8List? typeOptionData) = _InitialField;
|
||||
}
|
||||
|
||||
@freezed
|
||||
class SelectionTypeOptionState with _$SelectionTypeOptionState {
|
||||
const factory SelectionTypeOptionState() = _SelectionTypeOptionState;
|
||||
|
||||
factory SelectionTypeOptionState.initial() => SelectionTypeOptionState();
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
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 'type_option_service.dart';
|
||||
|
||||
part 'single_select_bloc.freezed.dart';
|
||||
|
||||
class SingleSelectTypeOptionBloc extends Bloc<SingleSelectTypeOptionEvent, SingleSelectTypeOptionState> {
|
||||
final TypeOptionService service;
|
||||
|
||||
SingleSelectTypeOptionBloc(SingleSelectTypeOption typeOption, String fieldId)
|
||||
: service = TypeOptionService(fieldId: fieldId),
|
||||
super(SingleSelectTypeOptionState.initial(typeOption)) {
|
||||
on<SingleSelectTypeOptionEvent>(
|
||||
(event, emit) async {
|
||||
await event.map(
|
||||
createOption: (_CreateOption value) async {
|
||||
final result = await service.createOption(value.optionName);
|
||||
result.fold(
|
||||
(option) {
|
||||
state.typeOption.options.insert(0, option);
|
||||
emit(state);
|
||||
},
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
},
|
||||
updateOptions: (_UpdateOptions value) async {},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
return super.close();
|
||||
}
|
||||
}
|
||||
|
||||
@freezed
|
||||
class SingleSelectTypeOptionEvent with _$SingleSelectTypeOptionEvent {
|
||||
const factory SingleSelectTypeOptionEvent.createOption(String optionName) = _CreateOption;
|
||||
const factory SingleSelectTypeOptionEvent.updateOptions(List<SelectOption> options) = _UpdateOptions;
|
||||
}
|
||||
|
||||
@freezed
|
||||
class SingleSelectTypeOptionState with _$SingleSelectTypeOptionState {
|
||||
const factory SingleSelectTypeOptionState({
|
||||
required SingleSelectTypeOption typeOption,
|
||||
}) = _SingleSelectTypeOptionState;
|
||||
|
||||
factory SingleSelectTypeOptionState.initial(SingleSelectTypeOption typeOption) => SingleSelectTypeOptionState(
|
||||
typeOption: typeOption,
|
||||
);
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart';
|
||||
|
||||
class TypeOptionService {
|
||||
String fieldId;
|
||||
TypeOptionService({
|
||||
required this.fieldId,
|
||||
});
|
||||
|
||||
Future<Either<SelectOption, FlowyError>> createOption(String name) {
|
||||
final payload = CreateSelectOptionPayload.create()..optionName = name;
|
||||
return GridEventCreateSelectOption(payload).send();
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@ export 'field/switch_field_type_bloc.dart';
|
||||
// Field Type Option
|
||||
export 'field/type_option/date_bloc.dart';
|
||||
export 'field/type_option/number_bloc.dart';
|
||||
export 'field/type_option/selection_bloc.dart';
|
||||
export 'field/type_option/single_select_bloc.dart';
|
||||
|
||||
// Cell
|
||||
export 'cell_bloc/text_cell_bloc.dart';
|
||||
|
@ -61,6 +61,7 @@ class _DocumentPageState extends State<DocumentPage> {
|
||||
@override
|
||||
Future<void> dispose() async {
|
||||
documentBloc.close();
|
||||
_focusNode.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@ class CreateFieldPannel extends FlowyOverlayDelegate {
|
||||
FlowyOverlay.of(context).insertWithAnchor(
|
||||
widget: OverlayContainer(
|
||||
child: _CreateFieldPannelWidget(_createFieldBloc),
|
||||
constraints: BoxConstraints.loose(const Size(220, 500)),
|
||||
constraints: BoxConstraints.loose(const Size(220, 400)),
|
||||
),
|
||||
identifier: identifier(),
|
||||
anchorContext: context,
|
||||
|
@ -2,7 +2,6 @@ import 'dart:typed_data';
|
||||
|
||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart';
|
||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart';
|
||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/type_option/selection.dart';
|
||||
import 'package:flowy_infra/image.dart';
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
@ -14,12 +13,13 @@ import 'package:flowy_sdk/protobuf/flowy-grid/checkbox_type_option.pbserver.dart
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/text_type_option.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:app_flowy/workspace/application/grid/prelude.dart';
|
||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_type_list.dart';
|
||||
|
||||
import 'type_option/multi_select.dart';
|
||||
import 'type_option/number.dart';
|
||||
import 'type_option/single_select.dart';
|
||||
|
||||
typedef SelectFieldCallback = void Function(Field, Uint8List);
|
||||
|
||||
@ -50,7 +50,7 @@ class _FieldTypeSwitcherState extends State<FieldTypeSwitcher> {
|
||||
|
||||
final typeOptionWidget = _typeOptionWidget(
|
||||
context: context,
|
||||
fieldType: state.field.fieldType,
|
||||
field: state.field,
|
||||
data: state.typeOptionData,
|
||||
);
|
||||
|
||||
@ -89,7 +89,7 @@ class _FieldTypeSwitcherState extends State<FieldTypeSwitcher> {
|
||||
|
||||
Widget? _typeOptionWidget({
|
||||
required BuildContext context,
|
||||
required FieldType fieldType,
|
||||
required Field field,
|
||||
required TypeOptionData data,
|
||||
}) {
|
||||
final delegate = TypeOptionOperationDelegate(
|
||||
@ -97,8 +97,9 @@ class _FieldTypeSwitcherState extends State<FieldTypeSwitcher> {
|
||||
context.read<FieldTypeSwitchBloc>().add(FieldTypeSwitchEvent.didUpdateTypeOptionData(data));
|
||||
},
|
||||
requireToShowOverlay: _showOverlay,
|
||||
hideOverlay: _hideOverlay,
|
||||
);
|
||||
final builder = _makeTypeOptionBuild(fieldType: fieldType, data: data, delegate: delegate);
|
||||
final builder = _makeTypeOptionBuild(field: field, data: data, delegate: delegate);
|
||||
return builder.customWidget;
|
||||
}
|
||||
|
||||
@ -120,6 +121,12 @@ class _FieldTypeSwitcherState extends State<FieldTypeSwitcher> {
|
||||
anchorOffset: const Offset(-20, 0),
|
||||
);
|
||||
}
|
||||
|
||||
void _hideOverlay(BuildContext context) {
|
||||
if (currentOverlayIdentifier != null) {
|
||||
FlowyOverlay.of(context).remove(currentOverlayIdentifier!);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract class TypeOptionBuilder {
|
||||
@ -127,23 +134,24 @@ abstract class TypeOptionBuilder {
|
||||
}
|
||||
|
||||
TypeOptionBuilder _makeTypeOptionBuild({
|
||||
required FieldType fieldType,
|
||||
required Field field,
|
||||
required TypeOptionData data,
|
||||
required TypeOptionOperationDelegate delegate,
|
||||
}) {
|
||||
switch (fieldType) {
|
||||
switch (field.fieldType) {
|
||||
case FieldType.Checkbox:
|
||||
return CheckboxTypeOptionBuilder(data);
|
||||
case FieldType.DateTime:
|
||||
return DateTypeOptionBuilder(data, delegate);
|
||||
case FieldType.SingleSelect:
|
||||
return SingleSelectTypeOptionBuilder(field.id, data, delegate);
|
||||
case FieldType.MultiSelect:
|
||||
return MultiSelectTypeOptionBuilder(data);
|
||||
return MultiSelectTypeOptionBuilder(data, delegate);
|
||||
case FieldType.Number:
|
||||
return NumberTypeOptionBuilder(data, delegate);
|
||||
case FieldType.RichText:
|
||||
return RichTextTypeOptionBuilder(data);
|
||||
case FieldType.SingleSelect:
|
||||
return SingleSelectTypeOptionBuilder(data);
|
||||
|
||||
default:
|
||||
throw UnimplementedError;
|
||||
}
|
||||
@ -156,13 +164,16 @@ abstract class TypeOptionWidget extends StatelessWidget {
|
||||
typedef TypeOptionData = Uint8List;
|
||||
typedef TypeOptionDataCallback = void Function(TypeOptionData typeOptionData);
|
||||
typedef ShowOverlayCallback = void Function(BuildContext anchorContext, String overlayIdentifier, Widget child);
|
||||
typedef HideOverlayCallback = void Function(BuildContext anchorContext);
|
||||
|
||||
class TypeOptionOperationDelegate {
|
||||
TypeOptionDataCallback didUpdateTypeOptionData;
|
||||
ShowOverlayCallback requireToShowOverlay;
|
||||
HideOverlayCallback hideOverlay;
|
||||
TypeOptionOperationDelegate({
|
||||
required this.didUpdateTypeOptionData,
|
||||
required this.requireToShowOverlay,
|
||||
required this.hideOverlay,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,115 @@
|
||||
import 'package:flowy_infra/image.dart';
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/button.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:app_flowy/generated/locale_keys.g.dart';
|
||||
|
||||
class SelectOptionColorList extends StatelessWidget {
|
||||
const SelectOptionColorList({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container();
|
||||
}
|
||||
}
|
||||
|
||||
class _SelectOptionColorItem extends StatelessWidget {
|
||||
final SelectOptionColor option;
|
||||
final bool isSelected;
|
||||
const _SelectOptionColorItem({required this.option, required this.isSelected, Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = context.watch<AppTheme>();
|
||||
|
||||
Widget? checkmark;
|
||||
if (isSelected) {
|
||||
checkmark = svg("grid/details", color: theme.iconColor);
|
||||
}
|
||||
|
||||
final colorIcon = SizedBox.square(
|
||||
dimension: 16,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: option.color(context),
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return FlowyButton(
|
||||
text: FlowyText.medium(
|
||||
option.name(),
|
||||
fontSize: 12,
|
||||
),
|
||||
hoverColor: theme.hover,
|
||||
leftIcon: colorIcon,
|
||||
rightIcon: checkmark,
|
||||
onTap: () {},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
enum SelectOptionColor {
|
||||
purple,
|
||||
pink,
|
||||
lightPink,
|
||||
orange,
|
||||
yellow,
|
||||
lime,
|
||||
green,
|
||||
aqua,
|
||||
blue,
|
||||
}
|
||||
|
||||
extension SelectOptionColorExtension on SelectOptionColor {
|
||||
Color color(BuildContext context) {
|
||||
final theme = context.watch<AppTheme>();
|
||||
switch (this) {
|
||||
case SelectOptionColor.purple:
|
||||
return theme.tint1;
|
||||
case SelectOptionColor.pink:
|
||||
return theme.tint2;
|
||||
case SelectOptionColor.lightPink:
|
||||
return theme.tint3;
|
||||
case SelectOptionColor.orange:
|
||||
return theme.tint4;
|
||||
case SelectOptionColor.yellow:
|
||||
return theme.tint5;
|
||||
case SelectOptionColor.lime:
|
||||
return theme.tint6;
|
||||
case SelectOptionColor.green:
|
||||
return theme.tint7;
|
||||
case SelectOptionColor.aqua:
|
||||
return theme.tint8;
|
||||
case SelectOptionColor.blue:
|
||||
return theme.tint9;
|
||||
}
|
||||
}
|
||||
|
||||
String name() {
|
||||
switch (this) {
|
||||
case SelectOptionColor.purple:
|
||||
return LocaleKeys.grid_selectOption_purpleColor.tr();
|
||||
case SelectOptionColor.pink:
|
||||
return LocaleKeys.grid_selectOption_pinkColor.tr();
|
||||
case SelectOptionColor.lightPink:
|
||||
return LocaleKeys.grid_selectOption_lightPinkColor.tr();
|
||||
case SelectOptionColor.orange:
|
||||
return LocaleKeys.grid_selectOption_orangeColor.tr();
|
||||
case SelectOptionColor.yellow:
|
||||
return LocaleKeys.grid_selectOption_yellowColor.tr();
|
||||
case SelectOptionColor.lime:
|
||||
return LocaleKeys.grid_selectOption_limeColor.tr();
|
||||
case SelectOptionColor.green:
|
||||
return LocaleKeys.grid_selectOption_greenColor.tr();
|
||||
case SelectOptionColor.aqua:
|
||||
return LocaleKeys.grid_selectOption_aquaColor.tr();
|
||||
case SelectOptionColor.blue:
|
||||
return LocaleKeys.grid_selectOption_blueColor.tr();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:app_flowy/workspace/application/grid/field/type_option/multi_select_bloc.dart';
|
||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import 'option_pannel.dart';
|
||||
|
||||
class MultiSelectTypeOptionBuilder extends TypeOptionBuilder {
|
||||
MultiSelectTypeOption typeOption;
|
||||
TypeOptionOperationDelegate delegate;
|
||||
|
||||
MultiSelectTypeOptionBuilder(TypeOptionData typeOptionData, this.delegate)
|
||||
: typeOption = MultiSelectTypeOption.fromBuffer(typeOptionData);
|
||||
|
||||
@override
|
||||
Widget? get customWidget => MultiSelectTypeOptionWidget(typeOption, delegate);
|
||||
}
|
||||
|
||||
class MultiSelectTypeOptionWidget extends TypeOptionWidget {
|
||||
final MultiSelectTypeOption typeOption;
|
||||
final TypeOptionOperationDelegate delegate;
|
||||
const MultiSelectTypeOptionWidget(this.typeOption, this.delegate, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => getIt<MultiSelectTypeOptionBloc>(param1: typeOption),
|
||||
child: BlocBuilder<MultiSelectTypeOptionBloc, MultiSelectTypeOptionState>(
|
||||
builder: (context, state) {
|
||||
return OptionPannel(
|
||||
options: state.typeOption.options,
|
||||
beginEdit: () {
|
||||
delegate.hideOverlay(context);
|
||||
},
|
||||
createOptionCallback: (name) {
|
||||
context.read<MultiSelectTypeOptionBloc>().add(MultiSelectTypeOptionEvent.createOption(name));
|
||||
},
|
||||
updateOptionsCallback: (options) {
|
||||
context.read<MultiSelectTypeOptionBloc>().add(MultiSelectTypeOptionEvent.updateOptions(options));
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,8 +1,5 @@
|
||||
import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:app_flowy/workspace/application/grid/field/type_option/option_pannel_bloc.dart';
|
||||
import 'package:app_flowy/workspace/application/grid/field/type_option/selection_bloc.dart';
|
||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart';
|
||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart';
|
||||
import 'package:flowy_infra/image.dart';
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/button.dart';
|
||||
@ -16,73 +13,48 @@ import 'package:app_flowy/generated/locale_keys.g.dart';
|
||||
|
||||
import 'widget.dart';
|
||||
|
||||
class SingleSelectTypeOptionBuilder extends TypeOptionBuilder {
|
||||
SingleSelectTypeOption typeOption;
|
||||
|
||||
SingleSelectTypeOptionBuilder(TypeOptionData typeOptionData)
|
||||
: typeOption = SingleSelectTypeOption.fromBuffer(typeOptionData);
|
||||
|
||||
@override
|
||||
Widget? get customWidget => SingleSelectTypeOptionWidget(typeOption);
|
||||
}
|
||||
|
||||
class SingleSelectTypeOptionWidget extends TypeOptionWidget {
|
||||
final SingleSelectTypeOption typeOption;
|
||||
const SingleSelectTypeOptionWidget(this.typeOption, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => getIt<SelectionTypeOptionBloc>(),
|
||||
child: OptionPannel(options: typeOption.options),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class MultiSelectTypeOptionBuilder extends TypeOptionBuilder {
|
||||
MultiSelectTypeOption typeOption;
|
||||
|
||||
MultiSelectTypeOptionBuilder(TypeOptionData typeOptionData)
|
||||
: typeOption = MultiSelectTypeOption.fromBuffer(typeOptionData);
|
||||
|
||||
@override
|
||||
Widget? get customWidget => MultiSelectTypeOptionWidget(typeOption);
|
||||
}
|
||||
|
||||
class MultiSelectTypeOptionWidget extends TypeOptionWidget {
|
||||
final MultiSelectTypeOption typeOption;
|
||||
const MultiSelectTypeOptionWidget(this.typeOption, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => getIt<SelectionTypeOptionBloc>(),
|
||||
child: OptionPannel(options: typeOption.options),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class OptionPannel extends StatelessWidget {
|
||||
final List<SelectOption> options;
|
||||
const OptionPannel({required this.options, Key? key}) : super(key: key);
|
||||
final VoidCallback beginEdit;
|
||||
final Function(String optionName) createOptionCallback;
|
||||
final Function(List<SelectOption>) updateOptionsCallback;
|
||||
const OptionPannel({
|
||||
required this.options,
|
||||
required this.beginEdit,
|
||||
required this.createOptionCallback,
|
||||
required this.updateOptionsCallback,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => OptionPannelBloc(options: options),
|
||||
child: BlocBuilder<OptionPannelBloc, OptionPannelState>(
|
||||
child: BlocConsumer<OptionPannelBloc, OptionPannelState>(
|
||||
listener: (context, state) {
|
||||
if (state.isEditingOption) {
|
||||
beginEdit();
|
||||
}
|
||||
state.newOptionName.fold(
|
||||
() => null,
|
||||
(optionName) => createOptionCallback(optionName),
|
||||
);
|
||||
},
|
||||
builder: (context, state) {
|
||||
List<Widget> children = [const OptionTitle()];
|
||||
if (state.isAddingOption) {
|
||||
List<Widget> children = [
|
||||
const TypeOptionSeparator(),
|
||||
const OptionTitle(),
|
||||
];
|
||||
if (state.isEditingOption) {
|
||||
children.add(const _AddOptionTextField());
|
||||
}
|
||||
|
||||
if (state.options.isEmpty && !state.isAddingOption) {
|
||||
if (state.options.isEmpty && !state.isEditingOption) {
|
||||
children.add(const _AddOptionButton());
|
||||
}
|
||||
|
||||
if (state.options.isNotEmpty) {
|
||||
children.add(const _OptionList());
|
||||
children.add(_OptionList(key: ObjectKey(state.options)));
|
||||
}
|
||||
|
||||
return Column(children: children);
|
||||
@ -100,19 +72,27 @@ class OptionTitle extends StatelessWidget {
|
||||
final theme = context.watch<AppTheme>();
|
||||
|
||||
return BlocBuilder<OptionPannelBloc, OptionPannelState>(
|
||||
buildWhen: (previous, current) => previous.options.length != current.options.length,
|
||||
builder: (context, state) {
|
||||
List<Widget> children = [FlowyText.medium(LocaleKeys.grid_field_optionTitle.tr(), fontSize: 12)];
|
||||
|
||||
if (state.options.isNotEmpty && state.isAddingOption == false) {
|
||||
children.add(FlowyButton(
|
||||
text: FlowyText.medium(LocaleKeys.grid_field_addOption.tr(), fontSize: 12),
|
||||
hoverColor: theme.hover,
|
||||
onTap: () {
|
||||
context.read<OptionPannelBloc>().add(const OptionPannelEvent.beginAddingOption());
|
||||
},
|
||||
rightIcon: svg("grid/more", color: theme.iconColor),
|
||||
));
|
||||
if (state.options.isNotEmpty) {
|
||||
children.add(const Spacer());
|
||||
children.add(
|
||||
SizedBox(
|
||||
width: 100,
|
||||
height: 26,
|
||||
child: FlowyButton(
|
||||
text: FlowyText.medium(
|
||||
LocaleKeys.grid_field_addOption.tr(),
|
||||
fontSize: 12,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
hoverColor: theme.hover,
|
||||
onTap: () {
|
||||
context.read<OptionPannelBloc>().add(const OptionPannelEvent.beginAddingOption());
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return SizedBox(
|
||||
@ -135,19 +115,16 @@ class _OptionList extends StatelessWidget {
|
||||
return _OptionItem(option: option);
|
||||
}).toList();
|
||||
|
||||
return SizedBox(
|
||||
width: 120,
|
||||
child: ListView.separated(
|
||||
shrinkWrap: true,
|
||||
controller: ScrollController(),
|
||||
separatorBuilder: (context, index) {
|
||||
return VSpace(GridSize.typeOptionSeparatorHeight);
|
||||
},
|
||||
itemCount: optionItems.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return optionItems[index];
|
||||
},
|
||||
),
|
||||
return ListView.separated(
|
||||
shrinkWrap: true,
|
||||
controller: ScrollController(),
|
||||
separatorBuilder: (context, index) {
|
||||
return VSpace(GridSize.typeOptionSeparatorHeight);
|
||||
},
|
||||
itemCount: optionItems.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return optionItems[index];
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
@ -167,7 +144,7 @@ class _OptionItem extends StatelessWidget {
|
||||
text: FlowyText.medium(option.name, fontSize: 12),
|
||||
hoverColor: theme.hover,
|
||||
onTap: () {},
|
||||
rightIcon: svg("grid/more", color: theme.iconColor),
|
||||
rightIcon: svg("grid/details", color: theme.iconColor),
|
||||
),
|
||||
);
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:app_flowy/workspace/application/grid/field/type_option/single_select_bloc.dart';
|
||||
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_tyep_switcher.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'option_pannel.dart';
|
||||
|
||||
class SingleSelectTypeOptionBuilder extends TypeOptionBuilder {
|
||||
final SingleSelectTypeOptionWidget _widget;
|
||||
|
||||
SingleSelectTypeOptionBuilder(
|
||||
String fieldId,
|
||||
TypeOptionData typeOptionData,
|
||||
TypeOptionOperationDelegate delegate,
|
||||
) : _widget = SingleSelectTypeOptionWidget(
|
||||
fieldId,
|
||||
SingleSelectTypeOption.fromBuffer(typeOptionData),
|
||||
delegate,
|
||||
);
|
||||
|
||||
@override
|
||||
Widget? get customWidget => _widget;
|
||||
}
|
||||
|
||||
class SingleSelectTypeOptionWidget extends TypeOptionWidget {
|
||||
final String fieldId;
|
||||
final SingleSelectTypeOption typeOption;
|
||||
final TypeOptionOperationDelegate delegate;
|
||||
const SingleSelectTypeOptionWidget(this.fieldId, this.typeOption, this.delegate, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => getIt<SingleSelectTypeOptionBloc>(param1: typeOption, param2: fieldId),
|
||||
child: BlocConsumer<SingleSelectTypeOptionBloc, SingleSelectTypeOptionState>(
|
||||
listener: (context, state) => delegate.didUpdateTypeOptionData(state.typeOption.writeToBuffer()),
|
||||
builder: (context, state) {
|
||||
return OptionPannel(
|
||||
options: state.typeOption.options,
|
||||
beginEdit: () {
|
||||
delegate.hideOverlay(context);
|
||||
},
|
||||
createOptionCallback: (name) {
|
||||
context.read<SingleSelectTypeOptionBloc>().add(SingleSelectTypeOptionEvent.createOption(name));
|
||||
},
|
||||
updateOptionsCallback: (options) {
|
||||
context.read<SingleSelectTypeOptionBloc>().add(SingleSelectTypeOptionEvent.updateOptions(options));
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -21,6 +21,7 @@ class NameTextField extends StatefulWidget {
|
||||
|
||||
class _NameTextFieldState extends State<NameTextField> {
|
||||
late FocusNode _focusNode;
|
||||
var isEdited = false;
|
||||
late TextEditingController _controller;
|
||||
|
||||
@override
|
||||
@ -35,31 +36,53 @@ class _NameTextFieldState extends State<NameTextField> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = context.watch<AppTheme>();
|
||||
|
||||
return RoundedInputField(
|
||||
controller: _controller,
|
||||
focusNode: _focusNode,
|
||||
height: 36,
|
||||
style: const TextStyle(fontSize: 13, fontWeight: FontWeight.w500),
|
||||
normalBorderColor: theme.shader4,
|
||||
errorBorderColor: theme.red,
|
||||
focusBorderColor: theme.main1,
|
||||
cursorColor: theme.main1,
|
||||
onChanged: (text) {
|
||||
print(text);
|
||||
});
|
||||
controller: _controller,
|
||||
focusNode: _focusNode,
|
||||
autoFocus: true,
|
||||
height: 36,
|
||||
style: const TextStyle(fontSize: 13, fontWeight: FontWeight.w500),
|
||||
normalBorderColor: theme.shader4,
|
||||
focusBorderColor: theme.main1,
|
||||
cursorColor: theme.main1,
|
||||
onEditingComplete: () {
|
||||
widget.onDone(_controller.text);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_focusNode.removeListener(notifyDidEndEditing);
|
||||
_focusNode.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void notifyDidEndEditing() {
|
||||
if (_controller.text.isEmpty) {
|
||||
// widget.onCanceled();
|
||||
if (isEdited) {
|
||||
widget.onCanceled();
|
||||
}
|
||||
isEdited = true;
|
||||
} else {
|
||||
widget.onDone(_controller.text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TypeOptionSeparator extends StatelessWidget {
|
||||
const TypeOptionSeparator({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = context.watch<AppTheme>();
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 6),
|
||||
child: Container(
|
||||
color: theme.shader4,
|
||||
height: 0.25,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ class FlowyButton extends StatelessWidget {
|
||||
Key? key,
|
||||
required this.text,
|
||||
this.onTap,
|
||||
this.padding = const EdgeInsets.symmetric(horizontal: 3, vertical: 2),
|
||||
this.padding = const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
|
||||
this.leftIcon,
|
||||
this.rightIcon,
|
||||
this.hoverColor = Colors.transparent,
|
||||
@ -44,12 +44,13 @@ class FlowyButton extends StatelessWidget {
|
||||
|
||||
if (rightIcon != null) {
|
||||
children.add(SizedBox.fromSize(size: const Size.square(16), child: rightIcon!));
|
||||
children.add(const HSpace(6));
|
||||
}
|
||||
|
||||
return Padding(
|
||||
padding: padding,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: children,
|
||||
),
|
||||
);
|
||||
|
@ -15,6 +15,7 @@ class RoundedInputField extends StatefulWidget {
|
||||
final String errorText;
|
||||
final TextStyle style;
|
||||
final ValueChanged<String>? onChanged;
|
||||
final VoidCallback? onEditingComplete;
|
||||
final String? initialValue;
|
||||
final EdgeInsets margin;
|
||||
final EdgeInsets padding;
|
||||
@ -22,6 +23,7 @@ class RoundedInputField extends StatefulWidget {
|
||||
final double height;
|
||||
final FocusNode? focusNode;
|
||||
final TextEditingController? controller;
|
||||
final bool autoFocus;
|
||||
|
||||
const RoundedInputField({
|
||||
Key? key,
|
||||
@ -32,6 +34,7 @@ class RoundedInputField extends StatefulWidget {
|
||||
this.obscureIcon,
|
||||
this.obscureHideIcon,
|
||||
this.onChanged,
|
||||
this.onEditingComplete,
|
||||
this.normalBorderColor = Colors.transparent,
|
||||
this.errorBorderColor = Colors.transparent,
|
||||
this.focusBorderColor,
|
||||
@ -43,6 +46,7 @@ class RoundedInputField extends StatefulWidget {
|
||||
this.height = 48,
|
||||
this.focusNode,
|
||||
this.controller,
|
||||
this.autoFocus = false,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
@ -78,6 +82,7 @@ class _RoundedInputFieldState extends State<RoundedInputField> {
|
||||
controller: widget.controller,
|
||||
initialValue: widget.initialValue,
|
||||
focusNode: widget.focusNode,
|
||||
autofocus: widget.autoFocus,
|
||||
onChanged: (value) {
|
||||
inputText = value;
|
||||
if (widget.onChanged != null) {
|
||||
@ -85,6 +90,7 @@ class _RoundedInputFieldState extends State<RoundedInputField> {
|
||||
}
|
||||
setState(() {});
|
||||
},
|
||||
onEditingComplete: widget.onEditingComplete,
|
||||
cursorColor: widget.cursorColor,
|
||||
obscureText: obscuteText,
|
||||
style: widget.style,
|
||||
|
@ -137,6 +137,23 @@ class GridEventCreateEditFieldContext {
|
||||
}
|
||||
}
|
||||
|
||||
class GridEventCreateSelectOption {
|
||||
CreateSelectOptionPayload request;
|
||||
GridEventCreateSelectOption(this.request);
|
||||
|
||||
Future<Either<SelectOption, FlowyError>> send() {
|
||||
final request = FFIRequest.create()
|
||||
..event = GridEvent.CreateSelectOption.toString()
|
||||
..payload = requestToBytes(this.request);
|
||||
|
||||
return Dispatch.asyncRequest(request)
|
||||
.then((bytesResult) => bytesResult.fold(
|
||||
(okBytes) => left(SelectOption.fromBuffer(okBytes)),
|
||||
(errBytes) => right(FlowyError.fromBuffer(errBytes)),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
class GridEventCreateRow {
|
||||
CreateRowPayload request;
|
||||
GridEventCreateRow(this.request);
|
||||
|
@ -4,6 +4,7 @@ import 'package:flowy_sdk/log.dart';
|
||||
// ignore: unnecessary_import
|
||||
import 'package:flowy_sdk/protobuf/dart-ffi/ffi_response.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-net/event.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-net/network_state.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/event_map.pb.dart';
|
||||
|
@ -47,6 +47,7 @@ class ErrorCode extends $pb.ProtobufEnum {
|
||||
static const ErrorCode RowIdIsEmpty = ErrorCode._(430, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'RowIdIsEmpty');
|
||||
static const ErrorCode FieldIdIsEmpty = ErrorCode._(440, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'FieldIdIsEmpty');
|
||||
static const ErrorCode FieldDoesNotExist = ErrorCode._(441, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'FieldDoesNotExist');
|
||||
static const ErrorCode SelectOptionNameIsEmpty = ErrorCode._(442, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'SelectOptionNameIsEmpty');
|
||||
static const ErrorCode TypeOptionDataIsEmpty = ErrorCode._(450, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'TypeOptionDataIsEmpty');
|
||||
static const ErrorCode InvalidData = ErrorCode._(500, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'InvalidData');
|
||||
|
||||
@ -88,6 +89,7 @@ class ErrorCode extends $pb.ProtobufEnum {
|
||||
RowIdIsEmpty,
|
||||
FieldIdIsEmpty,
|
||||
FieldDoesNotExist,
|
||||
SelectOptionNameIsEmpty,
|
||||
TypeOptionDataIsEmpty,
|
||||
InvalidData,
|
||||
];
|
||||
|
@ -49,10 +49,11 @@ const ErrorCode$json = const {
|
||||
const {'1': 'RowIdIsEmpty', '2': 430},
|
||||
const {'1': 'FieldIdIsEmpty', '2': 440},
|
||||
const {'1': 'FieldDoesNotExist', '2': 441},
|
||||
const {'1': 'SelectOptionNameIsEmpty', '2': 442},
|
||||
const {'1': 'TypeOptionDataIsEmpty', '2': 450},
|
||||
const {'1': 'InvalidData', '2': 500},
|
||||
],
|
||||
};
|
||||
|
||||
/// Descriptor for `ErrorCode`. Decode as a `google.protobuf.EnumDescriptorProto`.
|
||||
final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSDAoISW50ZXJuYWwQABIUChBVc2VyVW5hdXRob3JpemVkEAISEgoOUmVjb3JkTm90Rm91bmQQAxIRCg1Vc2VySWRJc0VtcHR5EAQSGAoUV29ya3NwYWNlTmFtZUludmFsaWQQZBIWChJXb3Jrc3BhY2VJZEludmFsaWQQZRIYChRBcHBDb2xvclN0eWxlSW52YWxpZBBmEhgKFFdvcmtzcGFjZURlc2NUb29Mb25nEGcSGAoUV29ya3NwYWNlTmFtZVRvb0xvbmcQaBIQCgxBcHBJZEludmFsaWQQbhISCg5BcHBOYW1lSW52YWxpZBBvEhMKD1ZpZXdOYW1lSW52YWxpZBB4EhgKFFZpZXdUaHVtYm5haWxJbnZhbGlkEHkSEQoNVmlld0lkSW52YWxpZBB6EhMKD1ZpZXdEZXNjVG9vTG9uZxB7EhMKD1ZpZXdEYXRhSW52YWxpZBB8EhMKD1ZpZXdOYW1lVG9vTG9uZxB9EhEKDENvbm5lY3RFcnJvchDIARIRCgxFbWFpbElzRW1wdHkQrAISFwoSRW1haWxGb3JtYXRJbnZhbGlkEK0CEhcKEkVtYWlsQWxyZWFkeUV4aXN0cxCuAhIUCg9QYXNzd29yZElzRW1wdHkQrwISFAoPUGFzc3dvcmRUb29Mb25nELACEiUKIFBhc3N3b3JkQ29udGFpbnNGb3JiaWRDaGFyYWN0ZXJzELECEhoKFVBhc3N3b3JkRm9ybWF0SW52YWxpZBCyAhIVChBQYXNzd29yZE5vdE1hdGNoELMCEhQKD1VzZXJOYW1lVG9vTG9uZxC0AhInCiJVc2VyTmFtZUNvbnRhaW5Gb3JiaWRkZW5DaGFyYWN0ZXJzELUCEhQKD1VzZXJOYW1lSXNFbXB0eRC2AhISCg1Vc2VySWRJbnZhbGlkELcCEhEKDFVzZXJOb3RFeGlzdBC4AhIQCgtUZXh0VG9vTG9uZxCQAxISCg1HcmlkSWRJc0VtcHR5EJoDEhMKDkJsb2NrSWRJc0VtcHR5EKQDEhEKDFJvd0lkSXNFbXB0eRCuAxITCg5GaWVsZElkSXNFbXB0eRC4AxIWChFGaWVsZERvZXNOb3RFeGlzdBC5AxIaChVUeXBlT3B0aW9uRGF0YUlzRW1wdHkQwgMSEAoLSW52YWxpZERhdGEQ9AM=');
|
||||
final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSDAoISW50ZXJuYWwQABIUChBVc2VyVW5hdXRob3JpemVkEAISEgoOUmVjb3JkTm90Rm91bmQQAxIRCg1Vc2VySWRJc0VtcHR5EAQSGAoUV29ya3NwYWNlTmFtZUludmFsaWQQZBIWChJXb3Jrc3BhY2VJZEludmFsaWQQZRIYChRBcHBDb2xvclN0eWxlSW52YWxpZBBmEhgKFFdvcmtzcGFjZURlc2NUb29Mb25nEGcSGAoUV29ya3NwYWNlTmFtZVRvb0xvbmcQaBIQCgxBcHBJZEludmFsaWQQbhISCg5BcHBOYW1lSW52YWxpZBBvEhMKD1ZpZXdOYW1lSW52YWxpZBB4EhgKFFZpZXdUaHVtYm5haWxJbnZhbGlkEHkSEQoNVmlld0lkSW52YWxpZBB6EhMKD1ZpZXdEZXNjVG9vTG9uZxB7EhMKD1ZpZXdEYXRhSW52YWxpZBB8EhMKD1ZpZXdOYW1lVG9vTG9uZxB9EhEKDENvbm5lY3RFcnJvchDIARIRCgxFbWFpbElzRW1wdHkQrAISFwoSRW1haWxGb3JtYXRJbnZhbGlkEK0CEhcKEkVtYWlsQWxyZWFkeUV4aXN0cxCuAhIUCg9QYXNzd29yZElzRW1wdHkQrwISFAoPUGFzc3dvcmRUb29Mb25nELACEiUKIFBhc3N3b3JkQ29udGFpbnNGb3JiaWRDaGFyYWN0ZXJzELECEhoKFVBhc3N3b3JkRm9ybWF0SW52YWxpZBCyAhIVChBQYXNzd29yZE5vdE1hdGNoELMCEhQKD1VzZXJOYW1lVG9vTG9uZxC0AhInCiJVc2VyTmFtZUNvbnRhaW5Gb3JiaWRkZW5DaGFyYWN0ZXJzELUCEhQKD1VzZXJOYW1lSXNFbXB0eRC2AhISCg1Vc2VySWRJbnZhbGlkELcCEhEKDFVzZXJOb3RFeGlzdBC4AhIQCgtUZXh0VG9vTG9uZxCQAxISCg1HcmlkSWRJc0VtcHR5EJoDEhMKDkJsb2NrSWRJc0VtcHR5EKQDEhEKDFJvd0lkSXNFbXB0eRCuAxITCg5GaWVsZElkSXNFbXB0eRC4AxIWChFGaWVsZERvZXNOb3RFeGlzdBC5AxIcChdTZWxlY3RPcHRpb25OYW1lSXNFbXB0eRC6AxIaChVUeXBlT3B0aW9uRGF0YUlzRW1wdHkQwgMSEAoLSW52YWxpZERhdGEQ9AM=');
|
||||
|
@ -1536,3 +1536,50 @@ class QueryRowPayload extends $pb.GeneratedMessage {
|
||||
void clearRowId() => clearField(3);
|
||||
}
|
||||
|
||||
class CreateSelectOptionPayload extends $pb.GeneratedMessage {
|
||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CreateSelectOptionPayload', createEmptyInstance: create)
|
||||
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'optionName')
|
||||
..hasRequiredFields = false
|
||||
;
|
||||
|
||||
CreateSelectOptionPayload._() : super();
|
||||
factory CreateSelectOptionPayload({
|
||||
$core.String? optionName,
|
||||
}) {
|
||||
final _result = create();
|
||||
if (optionName != null) {
|
||||
_result.optionName = optionName;
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
factory CreateSelectOptionPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
|
||||
factory CreateSelectOptionPayload.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
|
||||
@$core.Deprecated(
|
||||
'Using this can add significant overhead to your binary. '
|
||||
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
|
||||
'Will be removed in next major version')
|
||||
CreateSelectOptionPayload clone() => CreateSelectOptionPayload()..mergeFromMessage(this);
|
||||
@$core.Deprecated(
|
||||
'Using this can add significant overhead to your binary. '
|
||||
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
|
||||
'Will be removed in next major version')
|
||||
CreateSelectOptionPayload copyWith(void Function(CreateSelectOptionPayload) updates) => super.copyWith((message) => updates(message as CreateSelectOptionPayload)) as CreateSelectOptionPayload; // ignore: deprecated_member_use
|
||||
$pb.BuilderInfo get info_ => _i;
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static CreateSelectOptionPayload create() => CreateSelectOptionPayload._();
|
||||
CreateSelectOptionPayload createEmptyInstance() => create();
|
||||
static $pb.PbList<CreateSelectOptionPayload> createRepeated() => $pb.PbList<CreateSelectOptionPayload>();
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static CreateSelectOptionPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<CreateSelectOptionPayload>(create);
|
||||
static CreateSelectOptionPayload? _defaultInstance;
|
||||
|
||||
@$pb.TagNumber(1)
|
||||
$core.String get optionName => $_getSZ(0);
|
||||
@$pb.TagNumber(1)
|
||||
set optionName($core.String v) { $_setString(0, v); }
|
||||
@$pb.TagNumber(1)
|
||||
$core.bool hasOptionName() => $_has(0);
|
||||
@$pb.TagNumber(1)
|
||||
void clearOptionName() => clearField(1);
|
||||
}
|
||||
|
||||
|
@ -302,3 +302,13 @@ const QueryRowPayload$json = const {
|
||||
|
||||
/// Descriptor for `QueryRowPayload`. Decode as a `google.protobuf.DescriptorProto`.
|
||||
final $typed_data.Uint8List queryRowPayloadDescriptor = $convert.base64Decode('Cg9RdWVyeVJvd1BheWxvYWQSFwoHZ3JpZF9pZBgBIAEoCVIGZ3JpZElkEhkKCGJsb2NrX2lkGAIgASgJUgdibG9ja0lkEhUKBnJvd19pZBgDIAEoCVIFcm93SWQ=');
|
||||
@$core.Deprecated('Use createSelectOptionPayloadDescriptor instead')
|
||||
const CreateSelectOptionPayload$json = const {
|
||||
'1': 'CreateSelectOptionPayload',
|
||||
'2': const [
|
||||
const {'1': 'option_name', '3': 1, '4': 1, '5': 9, '10': 'optionName'},
|
||||
],
|
||||
};
|
||||
|
||||
/// Descriptor for `CreateSelectOptionPayload`. Decode as a `google.protobuf.DescriptorProto`.
|
||||
final $typed_data.Uint8List createSelectOptionPayloadDescriptor = $convert.base64Decode('ChlDcmVhdGVTZWxlY3RPcHRpb25QYXlsb2FkEh8KC29wdGlvbl9uYW1lGAEgASgJUgpvcHRpb25OYW1l');
|
||||
|
@ -18,9 +18,10 @@ class GridEvent extends $pb.ProtobufEnum {
|
||||
static const GridEvent DeleteField = GridEvent._(13, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DeleteField');
|
||||
static const GridEvent DuplicateField = GridEvent._(15, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DuplicateField');
|
||||
static const GridEvent CreateEditFieldContext = GridEvent._(16, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateEditFieldContext');
|
||||
static const GridEvent CreateRow = GridEvent._(21, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateRow');
|
||||
static const GridEvent GetRow = GridEvent._(22, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetRow');
|
||||
static const GridEvent UpdateCell = GridEvent._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateCell');
|
||||
static const GridEvent CreateSelectOption = GridEvent._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateSelectOption');
|
||||
static const GridEvent CreateRow = GridEvent._(50, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateRow');
|
||||
static const GridEvent GetRow = GridEvent._(51, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetRow');
|
||||
static const GridEvent UpdateCell = GridEvent._(70, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateCell');
|
||||
|
||||
static const $core.List<GridEvent> values = <GridEvent> [
|
||||
GetGridData,
|
||||
@ -31,6 +32,7 @@ class GridEvent extends $pb.ProtobufEnum {
|
||||
DeleteField,
|
||||
DuplicateField,
|
||||
CreateEditFieldContext,
|
||||
CreateSelectOption,
|
||||
CreateRow,
|
||||
GetRow,
|
||||
UpdateCell,
|
||||
|
@ -20,11 +20,12 @@ const GridEvent$json = const {
|
||||
const {'1': 'DeleteField', '2': 13},
|
||||
const {'1': 'DuplicateField', '2': 15},
|
||||
const {'1': 'CreateEditFieldContext', '2': 16},
|
||||
const {'1': 'CreateRow', '2': 21},
|
||||
const {'1': 'GetRow', '2': 22},
|
||||
const {'1': 'UpdateCell', '2': 30},
|
||||
const {'1': 'CreateSelectOption', '2': 30},
|
||||
const {'1': 'CreateRow', '2': 50},
|
||||
const {'1': 'GetRow', '2': 51},
|
||||
const {'1': 'UpdateCell', '2': 70},
|
||||
],
|
||||
};
|
||||
|
||||
/// Descriptor for `GridEvent`. Decode as a `google.protobuf.EnumDescriptorProto`.
|
||||
final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtDcmVhdGVGaWVsZBAMEg8KC0RlbGV0ZUZpZWxkEA0SEgoORHVwbGljYXRlRmllbGQQDxIaChZDcmVhdGVFZGl0RmllbGRDb250ZXh0EBASDQoJQ3JlYXRlUm93EBUSCgoGR2V0Um93EBYSDgoKVXBkYXRlQ2VsbBAe');
|
||||
final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtDcmVhdGVGaWVsZBAMEg8KC0RlbGV0ZUZpZWxkEA0SEgoORHVwbGljYXRlRmllbGQQDxIaChZDcmVhdGVFZGl0RmllbGRDb250ZXh0EBASFgoSQ3JlYXRlU2VsZWN0T3B0aW9uEB4SDQoJQ3JlYXRlUm93EDISCgoGR2V0Um93EDMSDgoKVXBkYXRlQ2VsbBBG');
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::manager::GridManager;
|
||||
use crate::services::field::type_option_data_from_str;
|
||||
use crate::services::field::{type_option_data_from_str, SelectOption};
|
||||
use flowy_error::FlowyError;
|
||||
use flowy_grid_data_model::entities::*;
|
||||
use lib_dispatch::prelude::{data_result, AppData, Data, DataResult};
|
||||
@ -88,6 +88,14 @@ pub(crate) async fn duplicate_field_handler(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(data), err)]
|
||||
pub(crate) async fn create_select_option_handler(
|
||||
data: Data<CreateSelectOptionPayload>,
|
||||
) -> DataResult<SelectOption, FlowyError> {
|
||||
let params: CreateSelectOptionParams = data.into_inner().try_into()?;
|
||||
data_result(SelectOption::new(¶ms.option_name))
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(data, manager), err)]
|
||||
pub(crate) async fn create_edit_field_context_handler(
|
||||
data: Data<CreateEditFieldContextParams>,
|
||||
|
@ -16,6 +16,7 @@ pub fn create(grid_manager: Arc<GridManager>) -> Module {
|
||||
.event(GridEvent::DeleteField, delete_field_handler)
|
||||
.event(GridEvent::DuplicateField, duplicate_field_handler)
|
||||
.event(GridEvent::CreateEditFieldContext, create_edit_field_context_handler)
|
||||
.event(GridEvent::CreateSelectOption, create_select_option_handler)
|
||||
.event(GridEvent::CreateRow, create_row_handler)
|
||||
.event(GridEvent::GetRow, get_row_handler)
|
||||
.event(GridEvent::UpdateCell, update_cell_handler);
|
||||
@ -50,12 +51,15 @@ pub enum GridEvent {
|
||||
#[event(input = "CreateEditFieldContextParams", output = "EditFieldContext")]
|
||||
CreateEditFieldContext = 16,
|
||||
|
||||
#[event(input = "CreateSelectOptionPayload", output = "SelectOption")]
|
||||
CreateSelectOption = 30,
|
||||
|
||||
#[event(input = "CreateRowPayload", output = "Row")]
|
||||
CreateRow = 21,
|
||||
CreateRow = 50,
|
||||
|
||||
#[event(input = "QueryRowPayload", output = "Row")]
|
||||
GetRow = 22,
|
||||
GetRow = 51,
|
||||
|
||||
#[event(input = "CellMetaChangeset")]
|
||||
UpdateCell = 30,
|
||||
UpdateCell = 70,
|
||||
}
|
||||
|
@ -33,9 +33,10 @@ pub enum GridEvent {
|
||||
DeleteField = 13,
|
||||
DuplicateField = 15,
|
||||
CreateEditFieldContext = 16,
|
||||
CreateRow = 21,
|
||||
GetRow = 22,
|
||||
UpdateCell = 30,
|
||||
CreateSelectOption = 30,
|
||||
CreateRow = 50,
|
||||
GetRow = 51,
|
||||
UpdateCell = 70,
|
||||
}
|
||||
|
||||
impl ::protobuf::ProtobufEnum for GridEvent {
|
||||
@ -53,9 +54,10 @@ impl ::protobuf::ProtobufEnum for GridEvent {
|
||||
13 => ::std::option::Option::Some(GridEvent::DeleteField),
|
||||
15 => ::std::option::Option::Some(GridEvent::DuplicateField),
|
||||
16 => ::std::option::Option::Some(GridEvent::CreateEditFieldContext),
|
||||
21 => ::std::option::Option::Some(GridEvent::CreateRow),
|
||||
22 => ::std::option::Option::Some(GridEvent::GetRow),
|
||||
30 => ::std::option::Option::Some(GridEvent::UpdateCell),
|
||||
30 => ::std::option::Option::Some(GridEvent::CreateSelectOption),
|
||||
50 => ::std::option::Option::Some(GridEvent::CreateRow),
|
||||
51 => ::std::option::Option::Some(GridEvent::GetRow),
|
||||
70 => ::std::option::Option::Some(GridEvent::UpdateCell),
|
||||
_ => ::std::option::Option::None
|
||||
}
|
||||
}
|
||||
@ -70,6 +72,7 @@ impl ::protobuf::ProtobufEnum for GridEvent {
|
||||
GridEvent::DeleteField,
|
||||
GridEvent::DuplicateField,
|
||||
GridEvent::CreateEditFieldContext,
|
||||
GridEvent::CreateSelectOption,
|
||||
GridEvent::CreateRow,
|
||||
GridEvent::GetRow,
|
||||
GridEvent::UpdateCell,
|
||||
@ -101,12 +104,13 @@ impl ::protobuf::reflect::ProtobufValue for GridEvent {
|
||||
}
|
||||
|
||||
static file_descriptor_proto_data: &'static [u8] = b"\
|
||||
\n\x0fevent_map.proto*\xcc\x01\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\
|
||||
\n\x0fevent_map.proto*\xe4\x01\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\
|
||||
\0\x12\x11\n\rGetGridBlocks\x10\x01\x12\r\n\tGetFields\x10\n\x12\x0f\n\
|
||||
\x0bUpdateField\x10\x0b\x12\x0f\n\x0bCreateField\x10\x0c\x12\x0f\n\x0bDe\
|
||||
leteField\x10\r\x12\x12\n\x0eDuplicateField\x10\x0f\x12\x1a\n\x16CreateE\
|
||||
ditFieldContext\x10\x10\x12\r\n\tCreateRow\x10\x15\x12\n\n\x06GetRow\x10\
|
||||
\x16\x12\x0e\n\nUpdateCell\x10\x1eb\x06proto3\
|
||||
ditFieldContext\x10\x10\x12\x16\n\x12CreateSelectOption\x10\x1e\x12\r\n\
|
||||
\tCreateRow\x102\x12\n\n\x06GetRow\x103\x12\x0e\n\nUpdateCell\x10Fb\x06p\
|
||||
roto3\
|
||||
";
|
||||
|
||||
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
|
||||
|
@ -9,7 +9,8 @@ enum GridEvent {
|
||||
DeleteField = 13;
|
||||
DuplicateField = 15;
|
||||
CreateEditFieldContext = 16;
|
||||
CreateRow = 21;
|
||||
GetRow = 22;
|
||||
UpdateCell = 30;
|
||||
CreateSelectOption = 30;
|
||||
CreateRow = 50;
|
||||
GetRow = 51;
|
||||
UpdateCell = 70;
|
||||
}
|
||||
|
@ -99,6 +99,8 @@ pub enum ErrorCode {
|
||||
FieldIdIsEmpty = 440,
|
||||
#[display(fmt = "Field doesn't exist")]
|
||||
FieldDoesNotExist = 441,
|
||||
#[display(fmt = "The name of the option should not be empty")]
|
||||
SelectOptionNameIsEmpty = 442,
|
||||
|
||||
#[display(fmt = "Field's type option data should not be empty")]
|
||||
TypeOptionDataIsEmpty = 450,
|
||||
|
@ -62,6 +62,7 @@ pub enum ErrorCode {
|
||||
RowIdIsEmpty = 430,
|
||||
FieldIdIsEmpty = 440,
|
||||
FieldDoesNotExist = 441,
|
||||
SelectOptionNameIsEmpty = 442,
|
||||
TypeOptionDataIsEmpty = 450,
|
||||
InvalidData = 500,
|
||||
}
|
||||
@ -110,6 +111,7 @@ impl ::protobuf::ProtobufEnum for ErrorCode {
|
||||
430 => ::std::option::Option::Some(ErrorCode::RowIdIsEmpty),
|
||||
440 => ::std::option::Option::Some(ErrorCode::FieldIdIsEmpty),
|
||||
441 => ::std::option::Option::Some(ErrorCode::FieldDoesNotExist),
|
||||
442 => ::std::option::Option::Some(ErrorCode::SelectOptionNameIsEmpty),
|
||||
450 => ::std::option::Option::Some(ErrorCode::TypeOptionDataIsEmpty),
|
||||
500 => ::std::option::Option::Some(ErrorCode::InvalidData),
|
||||
_ => ::std::option::Option::None
|
||||
@ -155,6 +157,7 @@ impl ::protobuf::ProtobufEnum for ErrorCode {
|
||||
ErrorCode::RowIdIsEmpty,
|
||||
ErrorCode::FieldIdIsEmpty,
|
||||
ErrorCode::FieldDoesNotExist,
|
||||
ErrorCode::SelectOptionNameIsEmpty,
|
||||
ErrorCode::TypeOptionDataIsEmpty,
|
||||
ErrorCode::InvalidData,
|
||||
];
|
||||
@ -185,7 +188,7 @@ impl ::protobuf::reflect::ProtobufValue for ErrorCode {
|
||||
}
|
||||
|
||||
static file_descriptor_proto_data: &'static [u8] = b"\
|
||||
\n\ncode.proto*\x80\x07\n\tErrorCode\x12\x0c\n\x08Internal\x10\0\x12\x14\
|
||||
\n\ncode.proto*\x9e\x07\n\tErrorCode\x12\x0c\n\x08Internal\x10\0\x12\x14\
|
||||
\n\x10UserUnauthorized\x10\x02\x12\x12\n\x0eRecordNotFound\x10\x03\x12\
|
||||
\x11\n\rUserIdIsEmpty\x10\x04\x12\x18\n\x14WorkspaceNameInvalid\x10d\x12\
|
||||
\x16\n\x12WorkspaceIdInvalid\x10e\x12\x18\n\x14AppColorStyleInvalid\x10f\
|
||||
@ -205,8 +208,9 @@ static file_descriptor_proto_data: &'static [u8] = b"\
|
||||
erNotExist\x10\xb8\x02\x12\x10\n\x0bTextTooLong\x10\x90\x03\x12\x12\n\rG\
|
||||
ridIdIsEmpty\x10\x9a\x03\x12\x13\n\x0eBlockIdIsEmpty\x10\xa4\x03\x12\x11\
|
||||
\n\x0cRowIdIsEmpty\x10\xae\x03\x12\x13\n\x0eFieldIdIsEmpty\x10\xb8\x03\
|
||||
\x12\x16\n\x11FieldDoesNotExist\x10\xb9\x03\x12\x1a\n\x15TypeOptionDataI\
|
||||
sEmpty\x10\xc2\x03\x12\x10\n\x0bInvalidData\x10\xf4\x03b\x06proto3\
|
||||
\x12\x16\n\x11FieldDoesNotExist\x10\xb9\x03\x12\x1c\n\x17SelectOptionNam\
|
||||
eIsEmpty\x10\xba\x03\x12\x1a\n\x15TypeOptionDataIsEmpty\x10\xc2\x03\x12\
|
||||
\x10\n\x0bInvalidData\x10\xf4\x03b\x06proto3\
|
||||
";
|
||||
|
||||
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
|
||||
|
@ -38,6 +38,7 @@ enum ErrorCode {
|
||||
RowIdIsEmpty = 430;
|
||||
FieldIdIsEmpty = 440;
|
||||
FieldDoesNotExist = 441;
|
||||
SelectOptionNameIsEmpty = 442;
|
||||
TypeOptionDataIsEmpty = 450;
|
||||
InvalidData = 500;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::entities::{FieldMeta, FieldType, RowMeta};
|
||||
use crate::parser::NotEmptyUuid;
|
||||
use crate::parser::{NotEmptyStr, NotEmptyUuid};
|
||||
use flowy_derive::ProtoBuf;
|
||||
use flowy_error_code::ErrorCode;
|
||||
use std::collections::HashMap;
|
||||
@ -494,3 +494,24 @@ impl TryInto<QueryRowParams> for QueryRowPayload {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf, Default)]
|
||||
pub struct CreateSelectOptionPayload {
|
||||
#[pb(index = 1)]
|
||||
pub option_name: String,
|
||||
}
|
||||
|
||||
pub struct CreateSelectOptionParams {
|
||||
pub option_name: String,
|
||||
}
|
||||
|
||||
impl TryInto<CreateSelectOptionParams> for CreateSelectOptionPayload {
|
||||
type Error = ErrorCode;
|
||||
|
||||
fn try_into(self) -> Result<CreateSelectOptionParams, Self::Error> {
|
||||
let option_name = NotEmptyStr::parse(self.option_name).map_err(|_| ErrorCode::SelectOptionNameIsEmpty)?;
|
||||
Ok(CreateSelectOptionParams {
|
||||
option_name: option_name.0,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
mod id_parser;
|
||||
mod str_parser;
|
||||
|
||||
pub use id_parser::*;
|
||||
pub use str_parser::*;
|
||||
|
@ -19,3 +19,21 @@ impl AsRef<str> for NotEmptyUuid {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct NotEmptyStr(pub String);
|
||||
|
||||
impl NotEmptyStr {
|
||||
pub fn parse(s: String) -> Result<Self, String> {
|
||||
if s.trim().is_empty() {
|
||||
return Err("Input string is empty".to_owned());
|
||||
}
|
||||
Ok(Self(s))
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<str> for NotEmptyStr {
|
||||
fn as_ref(&self) -> &str {
|
||||
&self.0
|
||||
}
|
||||
}
|
@ -5258,6 +5258,165 @@ impl ::protobuf::reflect::ProtobufValue for QueryRowPayload {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq,Clone,Default)]
|
||||
pub struct CreateSelectOptionPayload {
|
||||
// message fields
|
||||
pub option_name: ::std::string::String,
|
||||
// special fields
|
||||
pub unknown_fields: ::protobuf::UnknownFields,
|
||||
pub cached_size: ::protobuf::CachedSize,
|
||||
}
|
||||
|
||||
impl<'a> ::std::default::Default for &'a CreateSelectOptionPayload {
|
||||
fn default() -> &'a CreateSelectOptionPayload {
|
||||
<CreateSelectOptionPayload as ::protobuf::Message>::default_instance()
|
||||
}
|
||||
}
|
||||
|
||||
impl CreateSelectOptionPayload {
|
||||
pub fn new() -> CreateSelectOptionPayload {
|
||||
::std::default::Default::default()
|
||||
}
|
||||
|
||||
// string option_name = 1;
|
||||
|
||||
|
||||
pub fn get_option_name(&self) -> &str {
|
||||
&self.option_name
|
||||
}
|
||||
pub fn clear_option_name(&mut self) {
|
||||
self.option_name.clear();
|
||||
}
|
||||
|
||||
// Param is passed by value, moved
|
||||
pub fn set_option_name(&mut self, v: ::std::string::String) {
|
||||
self.option_name = v;
|
||||
}
|
||||
|
||||
// Mutable pointer to the field.
|
||||
// If field is not initialized, it is initialized with default value first.
|
||||
pub fn mut_option_name(&mut self) -> &mut ::std::string::String {
|
||||
&mut self.option_name
|
||||
}
|
||||
|
||||
// Take field
|
||||
pub fn take_option_name(&mut self) -> ::std::string::String {
|
||||
::std::mem::replace(&mut self.option_name, ::std::string::String::new())
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Message for CreateSelectOptionPayload {
|
||||
fn is_initialized(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
|
||||
while !is.eof()? {
|
||||
let (field_number, wire_type) = is.read_tag_unpack()?;
|
||||
match field_number {
|
||||
1 => {
|
||||
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.option_name)?;
|
||||
},
|
||||
_ => {
|
||||
::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
|
||||
},
|
||||
};
|
||||
}
|
||||
::std::result::Result::Ok(())
|
||||
}
|
||||
|
||||
// Compute sizes of nested messages
|
||||
#[allow(unused_variables)]
|
||||
fn compute_size(&self) -> u32 {
|
||||
let mut my_size = 0;
|
||||
if !self.option_name.is_empty() {
|
||||
my_size += ::protobuf::rt::string_size(1, &self.option_name);
|
||||
}
|
||||
my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
|
||||
self.cached_size.set(my_size);
|
||||
my_size
|
||||
}
|
||||
|
||||
fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
|
||||
if !self.option_name.is_empty() {
|
||||
os.write_string(1, &self.option_name)?;
|
||||
}
|
||||
os.write_unknown_fields(self.get_unknown_fields())?;
|
||||
::std::result::Result::Ok(())
|
||||
}
|
||||
|
||||
fn get_cached_size(&self) -> u32 {
|
||||
self.cached_size.get()
|
||||
}
|
||||
|
||||
fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
|
||||
&self.unknown_fields
|
||||
}
|
||||
|
||||
fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
|
||||
&mut self.unknown_fields
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn (::std::any::Any) {
|
||||
self as &dyn (::std::any::Any)
|
||||
}
|
||||
fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
|
||||
self as &mut dyn (::std::any::Any)
|
||||
}
|
||||
fn into_any(self: ::std::boxed::Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
|
||||
self
|
||||
}
|
||||
|
||||
fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
|
||||
Self::descriptor_static()
|
||||
}
|
||||
|
||||
fn new() -> CreateSelectOptionPayload {
|
||||
CreateSelectOptionPayload::new()
|
||||
}
|
||||
|
||||
fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
|
||||
static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT;
|
||||
descriptor.get(|| {
|
||||
let mut fields = ::std::vec::Vec::new();
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
|
||||
"option_name",
|
||||
|m: &CreateSelectOptionPayload| { &m.option_name },
|
||||
|m: &mut CreateSelectOptionPayload| { &mut m.option_name },
|
||||
));
|
||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<CreateSelectOptionPayload>(
|
||||
"CreateSelectOptionPayload",
|
||||
fields,
|
||||
file_descriptor_proto()
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn default_instance() -> &'static CreateSelectOptionPayload {
|
||||
static instance: ::protobuf::rt::LazyV2<CreateSelectOptionPayload> = ::protobuf::rt::LazyV2::INIT;
|
||||
instance.get(CreateSelectOptionPayload::new)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Clear for CreateSelectOptionPayload {
|
||||
fn clear(&mut self) {
|
||||
self.option_name.clear();
|
||||
self.unknown_fields.clear();
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::fmt::Debug for CreateSelectOptionPayload {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
|
||||
::protobuf::text_format::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::reflect::ProtobufValue for CreateSelectOptionPayload {
|
||||
fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
|
||||
::protobuf::reflect::ReflectValueRef::Message(self)
|
||||
}
|
||||
}
|
||||
|
||||
static file_descriptor_proto_data: &'static [u8] = b"\
|
||||
\n\ngrid.proto\x1a\nmeta.proto\"z\n\x04Grid\x12\x0e\n\x02id\x18\x01\x20\
|
||||
\x01(\tR\x02id\x12.\n\x0cfield_orders\x18\x02\x20\x03(\x0b2\x0b.FieldOrd\
|
||||
@ -5311,7 +5470,9 @@ static file_descriptor_proto_data: &'static [u8] = b"\
|
||||
ridId\x122\n\x0cblock_orders\x18\x02\x20\x03(\x0b2\x0f.GridBlockOrderR\
|
||||
\x0bblockOrders\"\\\n\x0fQueryRowPayload\x12\x17\n\x07grid_id\x18\x01\
|
||||
\x20\x01(\tR\x06gridId\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07bloc\
|
||||
kId\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowIdb\x06proto3\
|
||||
kId\x12\x15\n\x06row_id\x18\x03\x20\x01(\tR\x05rowId\"<\n\x19CreateSelec\
|
||||
tOptionPayload\x12\x1f\n\x0boption_name\x18\x01\x20\x01(\tR\noptionNameb\
|
||||
\x06proto3\
|
||||
";
|
||||
|
||||
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
|
||||
|
@ -103,3 +103,6 @@ message QueryRowPayload {
|
||||
string block_id = 2;
|
||||
string row_id = 3;
|
||||
}
|
||||
message CreateSelectOptionPayload {
|
||||
string option_name = 1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user