mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: integrate new field editor components (#4070)
* chore: use the fancy new create field UI * chore: adjust select option tag text weight * chore: use new field editor * chore: remove old field editor * chore: code cleanup
This commit is contained in:
parent
147080ad27
commit
ff3ff9f888
@ -1,203 +0,0 @@
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/mobile/presentation/widgets/flowy_paginated_bottom_sheet.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/field_controller.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/field_editor_bloc.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/type_option/type_option_context.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/setting/property_bloc.dart';
|
||||
import 'package:appflowy/plugins/database_view/widgets/setting/mobile_database_property_editor.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pb.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'bottom_sheet_action_widget.dart';
|
||||
import 'bottom_sheet_rename_widget.dart';
|
||||
|
||||
/// The mobile bottom bar field editor is a two-deep menu. The type option
|
||||
/// sub-menu may have its own sub-menus as well though.
|
||||
enum MobileDBBottomSheetViewMode {
|
||||
// operations shared between all fields
|
||||
general,
|
||||
// operations specific to the field type
|
||||
typeOption,
|
||||
}
|
||||
|
||||
class MobileDBBottomSheetFieldEditor extends StatefulWidget {
|
||||
final String viewId;
|
||||
final FieldController fieldController;
|
||||
final FieldPB field;
|
||||
final MobileDBBottomSheetViewMode initialPage;
|
||||
|
||||
const MobileDBBottomSheetFieldEditor({
|
||||
super.key,
|
||||
required this.viewId,
|
||||
required this.fieldController,
|
||||
required this.field,
|
||||
this.initialPage = MobileDBBottomSheetViewMode.general,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MobileDBBottomSheetFieldEditor> createState() =>
|
||||
_MobileDBBottomSheetFieldEditorState();
|
||||
}
|
||||
|
||||
class _MobileDBBottomSheetFieldEditorState
|
||||
extends State<MobileDBBottomSheetFieldEditor> {
|
||||
late MobileDBBottomSheetViewMode viewMode;
|
||||
late final FieldEditorBloc _fieldEditorBloc;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
viewMode = widget.initialPage;
|
||||
final loader = FieldTypeOptionLoader(
|
||||
viewId: widget.viewId,
|
||||
field: widget.field,
|
||||
);
|
||||
_fieldEditorBloc = FieldEditorBloc(
|
||||
viewId: widget.viewId,
|
||||
field: widget.field,
|
||||
loader: loader,
|
||||
fieldController: widget.fieldController,
|
||||
)..add(const FieldEditorEvent.initial());
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider<FieldEditorBloc>.value(
|
||||
value: _fieldEditorBloc,
|
||||
child: _buildBody(),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildBody() {
|
||||
return switch (viewMode) {
|
||||
MobileDBBottomSheetViewMode.general => MobileDBFieldBottomSheetBody(
|
||||
onAction: (action) {
|
||||
switch (action) {
|
||||
case MobileDBBottomSheetGeneralAction.typeOption:
|
||||
FlowyBottomSheetController.of(context)!.push(
|
||||
SheetPage(
|
||||
title: LocaleKeys.grid_field_editProperty.tr(),
|
||||
body: MobileDatabasePropertyEditor(
|
||||
padding: EdgeInsets.zero,
|
||||
viewId: widget.viewId,
|
||||
fieldInfo:
|
||||
widget.fieldController.getField(widget.field.id)!,
|
||||
fieldController: widget.fieldController,
|
||||
bloc: DatabasePropertyBloc(
|
||||
viewId: widget.viewId,
|
||||
fieldController: widget.fieldController,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
break;
|
||||
case MobileDBBottomSheetGeneralAction.toggleVisibility:
|
||||
_fieldEditorBloc
|
||||
.add(const FieldEditorEvent.toggleFieldVisibility());
|
||||
context.pop();
|
||||
break;
|
||||
case MobileDBBottomSheetGeneralAction.delete:
|
||||
_fieldEditorBloc.add(const FieldEditorEvent.deleteField());
|
||||
context.pop();
|
||||
break;
|
||||
case MobileDBBottomSheetGeneralAction.duplicate:
|
||||
_fieldEditorBloc.add(const FieldEditorEvent.duplicateField());
|
||||
context.pop();
|
||||
}
|
||||
},
|
||||
onRename: (name) {
|
||||
_fieldEditorBloc.add(FieldEditorEvent.renameField(name));
|
||||
},
|
||||
),
|
||||
MobileDBBottomSheetViewMode.typeOption => const SizedBox.shrink(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
enum MobileDBBottomSheetGeneralAction {
|
||||
toggleVisibility,
|
||||
duplicate,
|
||||
delete,
|
||||
typeOption,
|
||||
}
|
||||
|
||||
class MobileDBFieldBottomSheetBody extends StatelessWidget {
|
||||
const MobileDBFieldBottomSheetBody({
|
||||
super.key,
|
||||
required this.onAction,
|
||||
required this.onRename,
|
||||
});
|
||||
|
||||
final void Function(MobileDBBottomSheetGeneralAction action) onAction;
|
||||
final void Function(String name) onRename;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
// field name editor
|
||||
MobileBottomSheetRenameWidget(
|
||||
name: context.read<FieldEditorBloc>().state.field.name,
|
||||
onRename: (newName) => onRename(newName),
|
||||
padding: EdgeInsets.zero,
|
||||
),
|
||||
const VSpace(8),
|
||||
// type option button
|
||||
BottomSheetActionWidget(
|
||||
svg: FlowySvgs.date_s,
|
||||
text: LocaleKeys.grid_field_editProperty.tr(),
|
||||
onTap: () => onAction(MobileDBBottomSheetGeneralAction.typeOption),
|
||||
),
|
||||
const VSpace(8),
|
||||
Row(
|
||||
children: [
|
||||
// hide/show field
|
||||
Expanded(
|
||||
child: BottomSheetActionWidget(
|
||||
svg: FlowySvgs.hide_m,
|
||||
text: LocaleKeys.grid_field_hide.tr(),
|
||||
onTap: () =>
|
||||
onAction(MobileDBBottomSheetGeneralAction.toggleVisibility),
|
||||
),
|
||||
),
|
||||
const HSpace(8),
|
||||
// duplicate field
|
||||
Expanded(
|
||||
child: BottomSheetActionWidget(
|
||||
svg: FlowySvgs.copy_s,
|
||||
text: LocaleKeys.grid_field_duplicate.tr(),
|
||||
onTap: () {
|
||||
onAction(MobileDBBottomSheetGeneralAction.duplicate);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const VSpace(8),
|
||||
Row(
|
||||
children: [
|
||||
// delete field
|
||||
Expanded(
|
||||
child: BottomSheetActionWidget(
|
||||
svg: FlowySvgs.delete_s,
|
||||
text: LocaleKeys.grid_field_delete.tr(),
|
||||
onTap: () {
|
||||
onAction(MobileDBBottomSheetGeneralAction.delete);
|
||||
},
|
||||
),
|
||||
),
|
||||
const HSpace(8),
|
||||
const Expanded(child: SizedBox.shrink()),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
@ -23,7 +23,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'widgets/mobile_create_row_field_button.dart';
|
||||
import 'widgets/mobile_create_field_button.dart';
|
||||
import 'widgets/mobile_row_property_list.dart';
|
||||
|
||||
class MobileRowDetailPage extends StatefulWidget {
|
||||
@ -95,12 +95,9 @@ class _MobileRowDetailPageState extends State<MobileRowDetailPage> {
|
||||
if (state.rowInfos.isEmpty || state.currentRowId == null) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 18),
|
||||
child: MobileRowDetailPageContent(
|
||||
databaseController: widget.databaseController,
|
||||
rowMeta: state.rowInfos[index].rowMeta,
|
||||
),
|
||||
return MobileRowDetailPageContent(
|
||||
databaseController: widget.databaseController,
|
||||
rowMeta: state.rowInfos[index].rowMeta,
|
||||
);
|
||||
},
|
||||
);
|
||||
@ -371,9 +368,12 @@ class MobileRowDetailPageContentState
|
||||
fieldInfo: FieldInfo.initial(state.primaryField!),
|
||||
);
|
||||
|
||||
return cellBuilder.build(
|
||||
cellContext,
|
||||
style: cellStyle,
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 18),
|
||||
child: cellBuilder.build(
|
||||
cellContext,
|
||||
style: cellStyle,
|
||||
),
|
||||
);
|
||||
}
|
||||
return const SizedBox.shrink();
|
||||
@ -384,20 +384,23 @@ class MobileRowDetailPageContentState
|
||||
child: ListView(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
children: [
|
||||
MobileRowPropertyList(
|
||||
cellBuilder: cellBuilder,
|
||||
viewId: viewId,
|
||||
fieldController: fieldController,
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 18),
|
||||
child: MobileRowPropertyList(
|
||||
cellBuilder: cellBuilder,
|
||||
viewId: viewId,
|
||||
fieldController: fieldController,
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 12),
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (rowDetailState.numHiddenFields != 0)
|
||||
const ToggleHiddenFieldsVisibilityButton(),
|
||||
const VSpace(12),
|
||||
MobileCreateRowFieldButton(
|
||||
MobileRowDetailCreateFieldButton(
|
||||
viewId: viewId,
|
||||
fieldController: fieldController,
|
||||
),
|
||||
|
@ -0,0 +1,49 @@
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/field/bottom_sheet_create_field.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/field_controller.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class MobileRowDetailCreateFieldButton extends StatelessWidget {
|
||||
const MobileRowDetailCreateFieldButton({
|
||||
super.key,
|
||||
required this.viewId,
|
||||
required this.fieldController,
|
||||
});
|
||||
|
||||
final String viewId;
|
||||
final FieldController fieldController;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ConstrainedBox(
|
||||
constraints: const BoxConstraints(minWidth: double.infinity),
|
||||
child: TextButton.icon(
|
||||
style: Theme.of(context).textButtonTheme.style?.copyWith(
|
||||
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
|
||||
RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12.0),
|
||||
side: BorderSide.none,
|
||||
),
|
||||
),
|
||||
overlayColor: MaterialStateProperty.all<Color>(
|
||||
Theme.of(context).hoverColor,
|
||||
),
|
||||
alignment: AlignmentDirectional.centerStart,
|
||||
splashFactory: NoSplash.splashFactory,
|
||||
padding: const MaterialStatePropertyAll(
|
||||
EdgeInsets.symmetric(vertical: 14, horizontal: 6),
|
||||
),
|
||||
),
|
||||
label: FlowyText.medium(
|
||||
LocaleKeys.grid_field_newProperty.tr(),
|
||||
fontSize: 15,
|
||||
),
|
||||
onPressed: () => showCreateFieldBottomSheet(context, viewId),
|
||||
icon: const FlowySvg(FlowySvgs.add_m),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/card/card_detail/mobile_create_row_field_screen.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/field_controller.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/type_option/type_option_service.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
class MobileCreateRowFieldButton extends StatelessWidget {
|
||||
const MobileCreateRowFieldButton({
|
||||
super.key,
|
||||
required this.viewId,
|
||||
required this.fieldController,
|
||||
});
|
||||
|
||||
final String viewId;
|
||||
final FieldController fieldController;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ConstrainedBox(
|
||||
constraints:
|
||||
const BoxConstraints(maxHeight: 44, minWidth: double.infinity),
|
||||
child: TextButton.icon(
|
||||
style: Theme.of(context).textButtonTheme.style?.copyWith(
|
||||
alignment: AlignmentDirectional.centerStart,
|
||||
splashFactory: NoSplash.splashFactory,
|
||||
padding: const MaterialStatePropertyAll(EdgeInsets.zero),
|
||||
),
|
||||
label: Text(
|
||||
LocaleKeys.grid_field_newProperty.tr(),
|
||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(fontSize: 15),
|
||||
),
|
||||
onPressed: () async {
|
||||
final result = await TypeOptionBackendService.createFieldTypeOption(
|
||||
viewId: viewId,
|
||||
);
|
||||
result.fold(
|
||||
(typeOption) {
|
||||
context.push(
|
||||
MobileCreateRowFieldScreen.routeName,
|
||||
extra: {
|
||||
MobileCreateRowFieldScreen.argViewId: viewId,
|
||||
MobileCreateRowFieldScreen.argTypeOption: typeOption,
|
||||
MobileCreateRowFieldScreen.argFieldController:
|
||||
fieldController,
|
||||
},
|
||||
);
|
||||
},
|
||||
(r) => Log.error("Failed to create field type option: $r"),
|
||||
);
|
||||
},
|
||||
icon: const FlowySvg(FlowySvgs.add_m),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
export 'mobile_field_name_text_field.dart';
|
||||
export 'mobile_create_row_field_button.dart';
|
||||
export 'mobile_create_field_button.dart';
|
||||
export 'mobile_row_property_list.dart';
|
||||
|
@ -0,0 +1,82 @@
|
||||
import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/card/card_detail/mobile_create_field_screen.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/card/card_detail/mobile_edit_field_screen.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/card/card_detail/widgets/_field_options.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/card/card_detail/widgets/_field_options_eidtor.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/field_info.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/field_service.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
void showCreateFieldBottomSheet(BuildContext context, String viewId) {
|
||||
showMobileBottomSheet(
|
||||
context,
|
||||
padding: EdgeInsets.zero,
|
||||
builder: (context) {
|
||||
return DraggableScrollableSheet(
|
||||
expand: false,
|
||||
snap: true,
|
||||
initialChildSize: 0.7,
|
||||
minChildSize: 0.7,
|
||||
builder: (context, controller) => FieldOptions(
|
||||
scrollController: controller,
|
||||
onAddField: (type) async {
|
||||
final optionValues = await context.push<FieldOptionValues>(
|
||||
Uri(
|
||||
path: MobileNewPropertyScreen.routeName,
|
||||
queryParameters: {
|
||||
MobileNewPropertyScreen.argViewId: viewId,
|
||||
MobileNewPropertyScreen.argFieldTypeId: type.value.toString(),
|
||||
},
|
||||
).toString(),
|
||||
);
|
||||
if (optionValues != null) {
|
||||
await optionValues.create(viewId: viewId);
|
||||
if (context.mounted) {
|
||||
context.pop();
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void showEditFieldScreen(
|
||||
BuildContext context,
|
||||
String viewId,
|
||||
FieldInfo field,
|
||||
) async {
|
||||
final optionValues = await context.push<FieldOptionValues>(
|
||||
MobileEditPropertyScreen.routeName,
|
||||
extra: {
|
||||
MobileEditPropertyScreen.argViewId: viewId,
|
||||
MobileEditPropertyScreen.argField: field.field,
|
||||
MobileEditPropertyScreen.argIsPrimary: field.isPrimary,
|
||||
},
|
||||
);
|
||||
if (optionValues != null) {
|
||||
final service = FieldBackendService(
|
||||
viewId: viewId,
|
||||
fieldId: field.id,
|
||||
);
|
||||
|
||||
if (optionValues.name != field.name) {
|
||||
await service.updateField(name: optionValues.name);
|
||||
}
|
||||
|
||||
if (optionValues.type != field.fieldType) {
|
||||
await service.updateFieldType(fieldType: optionValues.type);
|
||||
}
|
||||
|
||||
final data = optionValues.toTypeOptionBuffer();
|
||||
if (data != null) {
|
||||
await FieldBackendService.updateFieldTypeOption(
|
||||
viewId: viewId,
|
||||
fieldId: field.id,
|
||||
typeOptionData: data,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +1,6 @@
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/card/card_detail/mobile_create_field_screen.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/card/card_detail/widgets/_field_options.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/card/card_detail/widgets/_field_options_eidtor.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/field/bottom_sheet_create_field.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/field_controller.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/application/grid_bloc.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/application/grid_header_bloc.dart';
|
||||
@ -15,7 +12,6 @@ import 'package:flowy_infra/theme_extension.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:reorderables/reorderables.dart';
|
||||
|
||||
import '../../../../application/field/type_option/type_option_service.dart';
|
||||
@ -236,7 +232,7 @@ class _CreateFieldButtonState extends State<CreateFieldButton> {
|
||||
hoverColor: AFThemeExtension.of(context).greyHover,
|
||||
onTap: () async {
|
||||
if (PlatformExtension.isMobile) {
|
||||
_showCreateFieldBottomSheet(context);
|
||||
showCreateFieldBottomSheet(context, widget.viewId);
|
||||
} else {
|
||||
final result = await TypeOptionBackendService.createFieldTypeOption(
|
||||
viewId: widget.viewId,
|
||||
@ -253,40 +249,4 @@ class _CreateFieldButtonState extends State<CreateFieldButton> {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _showCreateFieldBottomSheet(BuildContext context) {
|
||||
showMobileBottomSheet(
|
||||
context,
|
||||
padding: EdgeInsets.zero,
|
||||
builder: (context) {
|
||||
return DraggableScrollableSheet(
|
||||
expand: false,
|
||||
snap: true,
|
||||
initialChildSize: 0.7,
|
||||
minChildSize: 0.7,
|
||||
builder: (context, controller) => FieldOptions(
|
||||
scrollController: controller,
|
||||
onAddField: (type) async {
|
||||
final optionValues = await context.push<FieldOptionValues>(
|
||||
Uri(
|
||||
path: MobileNewPropertyScreen.routeName,
|
||||
queryParameters: {
|
||||
MobileNewPropertyScreen.argViewId: widget.viewId,
|
||||
MobileNewPropertyScreen.argFieldTypeId:
|
||||
type.value.toString(),
|
||||
},
|
||||
).toString(),
|
||||
);
|
||||
if (optionValues != null) {
|
||||
await optionValues.create(viewId: widget.viewId);
|
||||
if (context.mounted) {
|
||||
context.pop();
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,9 @@
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/card/card_detail/mobile_edit_field_screen.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/card/card_detail/widgets/_field_options_eidtor.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/field/bottom_sheet_create_field.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/field_controller.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/field_info.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/field_service.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'field_type_extension.dart';
|
||||
|
||||
@ -41,39 +38,8 @@ class MobileFieldButton extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
child: FlowyButton(
|
||||
onTap: () async {
|
||||
final optionValues = await context.push<FieldOptionValues>(
|
||||
MobileEditPropertyScreen.routeName,
|
||||
extra: {
|
||||
MobileEditPropertyScreen.argViewId: viewId,
|
||||
MobileEditPropertyScreen.argField: fieldInfo.field,
|
||||
MobileEditPropertyScreen.argIsPrimary: fieldInfo.isPrimary,
|
||||
},
|
||||
);
|
||||
if (optionValues != null) {
|
||||
final fieldId = fieldInfo.field.id;
|
||||
final service = FieldBackendService(
|
||||
viewId: viewId,
|
||||
fieldId: fieldId,
|
||||
);
|
||||
|
||||
if (optionValues.name != fieldInfo.name) {
|
||||
await service.updateField(name: optionValues.name);
|
||||
}
|
||||
|
||||
if (optionValues.type != fieldInfo.fieldType) {
|
||||
await service.updateFieldType(fieldType: optionValues.type);
|
||||
}
|
||||
|
||||
final data = optionValues.toTypeOptionBuffer();
|
||||
if (data != null) {
|
||||
await FieldBackendService.updateFieldTypeOption(
|
||||
viewId: viewId,
|
||||
fieldId: fieldId,
|
||||
typeOptionData: data,
|
||||
);
|
||||
}
|
||||
}
|
||||
onTap: () {
|
||||
showEditFieldScreen(context, viewId, fieldInfo);
|
||||
},
|
||||
radius: BorderRadius.zero,
|
||||
margin: const EdgeInsets.symmetric(vertical: 12, horizontal: 8),
|
||||
|
@ -95,7 +95,7 @@ class SelectOptionTag extends StatelessWidget {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Flexible(
|
||||
child: FlowyText.regular(
|
||||
child: FlowyText.medium(
|
||||
optionName,
|
||||
fontSize: fontSize,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
|
@ -1,124 +0,0 @@
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/card/card_detail/widgets/mobile_field_name_text_field.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/card/card_property_edit/mobile_field_type_option_editor.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/card/card_property_edit/widgets/property_title.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/field_controller.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/field_editor_bloc.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/field_info.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/type_option/type_option_context.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/setting/property_bloc.dart';
|
||||
import 'package:appflowy/plugins/database_view/widgets/setting/field_visibility_extension.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/toggle/toggle.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/toggle/toggle_style.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/field_settings_entities.pbenum.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class MobileDatabasePropertyEditor extends StatefulWidget {
|
||||
const MobileDatabasePropertyEditor({
|
||||
super.key,
|
||||
required this.viewId,
|
||||
required this.fieldInfo,
|
||||
required this.fieldController,
|
||||
required this.bloc,
|
||||
this.padding = const EdgeInsets.all(16),
|
||||
});
|
||||
|
||||
final String viewId;
|
||||
final FieldInfo fieldInfo;
|
||||
final FieldController fieldController;
|
||||
final DatabasePropertyBloc bloc;
|
||||
final EdgeInsets padding;
|
||||
|
||||
@override
|
||||
State<MobileDatabasePropertyEditor> createState() =>
|
||||
_MobileDatabasePropertyEditorState();
|
||||
}
|
||||
|
||||
class _MobileDatabasePropertyEditorState
|
||||
extends State<MobileDatabasePropertyEditor> {
|
||||
late FieldVisibility _visibility =
|
||||
widget.fieldInfo.visibility ?? FieldVisibility.AlwaysShown;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final typeOptionLoader = FieldTypeOptionLoader(
|
||||
viewId: widget.viewId,
|
||||
field: widget.fieldInfo.field,
|
||||
);
|
||||
|
||||
return MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider<DatabasePropertyBloc>.value(value: widget.bloc),
|
||||
BlocProvider<FieldEditorBloc>(
|
||||
create: (context) => FieldEditorBloc(
|
||||
viewId: widget.viewId,
|
||||
loader: typeOptionLoader,
|
||||
field: widget.fieldInfo.field,
|
||||
fieldController: widget.fieldController,
|
||||
)..add(const FieldEditorEvent.initial()),
|
||||
),
|
||||
],
|
||||
child: BlocBuilder<DatabasePropertyBloc, DatabasePropertyState>(
|
||||
builder: (context, _) {
|
||||
return BlocBuilder<FieldEditorBloc, FieldEditorState>(
|
||||
builder: (context, state) {
|
||||
final dataController =
|
||||
context.read<FieldEditorBloc>().typeOptionController;
|
||||
|
||||
return Padding(
|
||||
padding: widget.padding,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// TODO(yijing): improve hint text
|
||||
PropertyTitle(LocaleKeys.settings_user_name.tr()),
|
||||
BlocSelector<FieldEditorBloc, FieldEditorState, String>(
|
||||
selector: (state) => state.field.name,
|
||||
builder: (context, fieldName) => MobileFieldNameTextField(
|
||||
text: fieldName,
|
||||
),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: PropertyTitle(
|
||||
LocaleKeys.grid_field_visibility.tr(),
|
||||
),
|
||||
),
|
||||
Toggle(
|
||||
padding: EdgeInsets.zero,
|
||||
value: _visibility.isVisibleState(),
|
||||
style: ToggleStyle.mobile,
|
||||
onChanged: (newValue) {
|
||||
final newVisibility = _visibility.toggle();
|
||||
|
||||
context.read<DatabasePropertyBloc>().add(
|
||||
DatabasePropertyEvent.setFieldVisibility(
|
||||
widget.fieldInfo.id,
|
||||
newVisibility,
|
||||
),
|
||||
);
|
||||
|
||||
setState(() => _visibility = newVisibility);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
const VSpace(8),
|
||||
if (!typeOptionLoader.field.isPrimary)
|
||||
MobileFieldTypeOptionEditor(
|
||||
dataController: dataController,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,8 +1,7 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/mobile/presentation/widgets/flowy_paginated_bottom_sheet.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/field/bottom_sheet_create_field.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/field_controller.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/field/field_info.dart';
|
||||
import 'package:appflowy/plugins/database_view/application/setting/property_bloc.dart';
|
||||
@ -10,14 +9,12 @@ import 'package:appflowy/plugins/database_view/grid/presentation/layout/sizes.da
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/header/field_editor.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/header/field_type_extension.dart';
|
||||
import 'package:appflowy/plugins/database_view/widgets/setting/field_visibility_extension.dart';
|
||||
import 'package:appflowy/plugins/database_view/widgets/setting/mobile_database_property_editor.dart';
|
||||
import 'package:appflowy/util/platform_extension.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/toggle/toggle.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/toggle/toggle_style.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
|
||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra/theme_extension.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@ -137,22 +134,20 @@ class DatabasePropertyCell extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (PlatformExtension.isMobile) {
|
||||
return MobileDatabasePropertyCell(
|
||||
fieldInfo: fieldInfo,
|
||||
viewId: viewId,
|
||||
fieldController: fieldController,
|
||||
bloc: bloc,
|
||||
);
|
||||
}
|
||||
|
||||
return DesktopDatabasePropertyCell(
|
||||
fieldInfo: fieldInfo,
|
||||
viewId: viewId,
|
||||
popoverMutex: popoverMutex,
|
||||
index: index,
|
||||
fieldController: fieldController,
|
||||
);
|
||||
return PlatformExtension.isMobile
|
||||
? MobileDatabasePropertyCell(
|
||||
fieldInfo: fieldInfo,
|
||||
viewId: viewId,
|
||||
fieldController: fieldController,
|
||||
bloc: bloc,
|
||||
)
|
||||
: DesktopDatabasePropertyCell(
|
||||
fieldInfo: fieldInfo,
|
||||
viewId: viewId,
|
||||
popoverMutex: popoverMutex,
|
||||
index: index,
|
||||
fieldController: fieldController,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -188,18 +183,8 @@ class _MobileDatabasePropertyCellState
|
||||
),
|
||||
child: InkWell(
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
onTap: () => FlowyBottomSheetController.of(context)!.push(
|
||||
SheetPage(
|
||||
title: LocaleKeys.grid_field_editProperty.tr(),
|
||||
body: MobileDatabasePropertyEditor(
|
||||
viewId: widget.viewId,
|
||||
fieldInfo: widget.fieldInfo,
|
||||
fieldController: widget.fieldController,
|
||||
bloc: widget.bloc,
|
||||
padding: EdgeInsets.zero,
|
||||
),
|
||||
),
|
||||
),
|
||||
onTap: () =>
|
||||
showEditFieldScreen(context, widget.viewId, widget.fieldInfo),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(10),
|
||||
child: Row(
|
||||
|
Loading…
Reference in New Issue
Block a user