Kaynağa Gözat

fix: show delete field dialog

appflowy 2 yıl önce
ebeveyn
işleme
1f2b30abfb

+ 93 - 75
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<RowDetailBloc>()
-                        .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<RowDetailBloc>()
+                    .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<RowDetailBloc>()
-                            .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<RowDetailBloc>()
+                .add(RowDetailEvent.deleteField(fieldId));
+          },
+        ).show(context);
+      },
+    );
+  }
 }
 
 GridCellStyle? _customCellStyle(AppTheme theme, FieldType fieldType) {

+ 0 - 36
frontend/app_flowy/lib/workspace/presentation/widgets/dialogs.dart

@@ -86,42 +86,6 @@ class _CreateTextFieldDialog extends State<NavigatorTextFieldDialog> {
   }
 }
 
-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<AppTheme>();
-    return StyledDialog(
-      child: Column(
-        crossAxisAlignment: CrossAxisAlignment.start,
-        mainAxisAlignment: MainAxisAlignment.center,
-        children: <Widget>[
-          ...[
-            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;