diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/row_detail.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/row_detail.dart index a68ac63984..6ee22cce98 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/row_detail.dart +++ b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/row_detail.dart @@ -2,6 +2,7 @@ import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_servic import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart'; import 'package:app_flowy/plugins/grid/application/row/row_data_controller.dart'; import 'package:app_flowy/plugins/grid/application/row/row_detail_bloc.dart'; +import 'package:app_flowy/workspace/presentation/widgets/dialogs.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; @@ -112,67 +113,61 @@ class _PropertyList extends StatelessWidget { builder: (context, state) { return Column( children: [ - Expanded( - child: ScrollbarListStack( - axis: Axis.vertical, - controller: _scrollController, - barSize: GridSize.scrollBarSize, - autoHideScrollbar: false, - child: ListView.separated( - controller: _scrollController, - itemCount: state.gridCells.length, - itemBuilder: (BuildContext context, int index) { - return _RowDetailCell( - cellId: state.gridCells[index], - cellBuilder: cellBuilder, - ); - }, - separatorBuilder: (BuildContext context, int index) { - return const VSpace(2); - }, - ), - ), - ), + Expanded(child: _wrapScrollbar(buildList(state))), const VSpace(10), _CreateFieldButton( viewId: viewId, - onClosed: () { - WidgetsBinding.instance.addPostFrameCallback((_) { - _scrollController.animateTo( - _scrollController.position.maxScrollExtent, - duration: const Duration(milliseconds: 250), - curve: Curves.ease, - ); - }); - }, - onOpened: (controller) { - return FieldEditor( - gridId: viewId, - typeOptionLoader: NewFieldTypeOptionLoader(gridId: viewId), - onDeleted: (fieldId) { - controller.close(); - context - .read() - .add(RowDetailEvent.deleteField(fieldId)); - }, - ); - }, + onClosed: _handleDidCreateField, ), ], ); }, ); } + + Widget buildList(RowDetailState state) { + return ListView.separated( + controller: _scrollController, + itemCount: state.gridCells.length, + itemBuilder: (BuildContext context, int index) { + return _RowDetailCell( + cellId: state.gridCells[index], + cellBuilder: cellBuilder, + ); + }, + separatorBuilder: (BuildContext context, int index) { + return const VSpace(2); + }, + ); + } + + Widget _wrapScrollbar(Widget child) { + return ScrollbarListStack( + axis: Axis.vertical, + controller: _scrollController, + barSize: GridSize.scrollBarSize, + autoHideScrollbar: false, + child: child, + ); + } + + void _handleDidCreateField() { + WidgetsBinding.instance.addPostFrameCallback((_) { + _scrollController.animateTo( + _scrollController.position.maxScrollExtent, + duration: const Duration(milliseconds: 250), + curve: Curves.ease, + ); + }); + } } class _CreateFieldButton extends StatefulWidget { final String viewId; - final Widget Function(PopoverController) onOpened; final VoidCallback onClosed; const _CreateFieldButton({ required this.viewId, - required this.onOpened, required this.onClosed, Key? key, }) : super(key: key); @@ -213,8 +208,24 @@ class _CreateFieldButtonState extends State<_CreateFieldButton> { leftIcon: svgWidget("home/add"), ), ), - popupBuilder: (BuildContext context) => - widget.onOpened(popoverController), + popupBuilder: (BuildContext popOverContext) { + return FieldEditor( + gridId: widget.viewId, + typeOptionLoader: NewFieldTypeOptionLoader(gridId: widget.viewId), + onDeleted: (fieldId) { + popoverController.close(); + + NavigatorAlertDialog( + title: LocaleKeys.grid_field_deleteFieldPromptMessage.tr(), + confirm: () { + context + .read() + .add(RowDetailEvent.deleteField(fieldId)); + }, + ).show(context); + }, + ); + }, ); } @@ -260,41 +271,24 @@ class _RowDetailCellState extends State<_RowDetailCell> { ), ); - return ConstrainedBox( - constraints: const BoxConstraints(minHeight: 40), - child: IntrinsicHeight( + return IntrinsicHeight( + child: ConstrainedBox( + constraints: const BoxConstraints(minHeight: 40), child: Row( crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisAlignment: MainAxisAlignment.center, children: [ - SizedBox( - width: 150, - child: Popover( - controller: popover, - offset: const Offset(20, 0), - popupBuilder: (popoverContext) { - return OverlayContainer( - constraints: BoxConstraints.loose(const Size(240, 600)), - child: FieldEditor( - gridId: widget.cellId.gridId, - fieldName: widget.cellId.fieldContext.field.name, - isGroupField: widget.cellId.fieldContext.isGroupField, - typeOptionLoader: FieldTypeOptionLoader( - gridId: widget.cellId.gridId, - field: widget.cellId.fieldContext.field, - ), - onDeleted: (fieldId) { - popover.close(); - context - .read() - .add(RowDetailEvent.deleteField(fieldId)); - }, - ), - ); - }, + AppFlowyPopover( + controller: popover, + constraints: BoxConstraints.loose(const Size(240, 600)), + popupBuilder: (popoverContext) => buildFieldEditor(), + child: SizedBox( + width: 150, child: FieldCellButton( field: widget.cellId.fieldContext.field, - onTap: () => popover.show(), + onTap: () { + popover.show(); + }, ), ), ), @@ -305,6 +299,30 @@ class _RowDetailCellState extends State<_RowDetailCell> { ), ); } + + Widget buildFieldEditor() { + return FieldEditor( + gridId: widget.cellId.gridId, + fieldName: widget.cellId.fieldContext.field.name, + isGroupField: widget.cellId.fieldContext.isGroupField, + typeOptionLoader: FieldTypeOptionLoader( + gridId: widget.cellId.gridId, + field: widget.cellId.fieldContext.field, + ), + onDeleted: (fieldId) { + popover.close(); + + NavigatorAlertDialog( + title: LocaleKeys.grid_field_deleteFieldPromptMessage.tr(), + confirm: () { + context + .read() + .add(RowDetailEvent.deleteField(fieldId)); + }, + ).show(context); + }, + ); + } } GridCellStyle? _customCellStyle(AppTheme theme, FieldType fieldType) { diff --git a/frontend/app_flowy/lib/workspace/presentation/widgets/dialogs.dart b/frontend/app_flowy/lib/workspace/presentation/widgets/dialogs.dart index 296f64d86d..006194fe97 100644 --- a/frontend/app_flowy/lib/workspace/presentation/widgets/dialogs.dart +++ b/frontend/app_flowy/lib/workspace/presentation/widgets/dialogs.dart @@ -86,42 +86,6 @@ class _CreateTextFieldDialog extends State { } } -class PopoverAlertView extends StatelessWidget { - final String title; - final void Function()? cancel; - final void Function()? confirm; - - const PopoverAlertView({ - required this.title, - this.confirm, - this.cancel, - Key? key, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - final theme = context.watch(); - return StyledDialog( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ...[ - FlowyText.medium(title, color: theme.shader4), - ], - if (confirm != null) ...[ - const VSpace(20), - OkCancelButton( - onOkPressed: confirm, - onCancelPressed: cancel, - ) - ] - ], - ), - ); - } -} - class NavigatorAlertDialog extends StatefulWidget { final String title; final void Function()? cancel;