Przeglądaj źródła

chore: support create new field when editing the row

appflowy 2 lat temu
rodzic
commit
a9f5f8d508

+ 2 - 1
frontend/app_flowy/assets/translations/en.json

@@ -189,7 +189,8 @@
       "addSelectOption": "Add an option",
       "optionTitle": "Options",
       "addOption": "Add option",
-      "editProperty": "Edit property"
+      "editProperty": "Edit property",
+      "newColumn": "New column"
     },
     "row": {
       "duplicate": "Duplicate",

+ 4 - 1
frontend/app_flowy/lib/plugins/board/presentation/card/board_select_option_cell.dart

@@ -65,7 +65,10 @@ class _BoardSelectOptionCellState extends State<BoardSelectOptionCell> {
                 alignment: AlignmentDirectional.center,
                 fit: StackFit.expand,
                 children: [
-                  Wrap(spacing: 4, runSpacing: 2, children: children),
+                  Padding(
+                    padding: const EdgeInsets.symmetric(vertical: 6),
+                    child: Wrap(spacing: 4, runSpacing: 2, children: children),
+                  ),
                   _SelectOptionDialog(
                     controller: widget.cellControllerBuilder.build(),
                   ),

+ 29 - 27
frontend/app_flowy/lib/plugins/board/presentation/card/board_text_cell.dart

@@ -78,36 +78,38 @@ class _BoardTextCellState extends State<BoardTextCell> {
         child: BlocBuilder<BoardTextCellBloc, BoardTextCellState>(
           builder: (context, state) {
             Widget child;
-            if (state.enableEdit) {
-              child = TextField(
-                controller: _controller,
-                focusNode: focusNode,
-                onChanged: (value) => focusChanged(),
-                onEditingComplete: () => focusNode.unfocus(),
-                maxLines: 1,
-                style: const TextStyle(
-                  fontSize: 14,
-                  fontWeight: FontWeight.w500,
-                  fontFamily: 'Mulish',
-                ),
-                decoration: const InputDecoration(
-                  // Magic number 4 makes the textField take up the same space as FlowyText
-                  contentPadding: EdgeInsets.symmetric(vertical: 4),
-                  border: InputBorder.none,
-                  isDense: true,
-                ),
-              );
+            if (state.content.isEmpty) {
+              child = const SizedBox();
             } else {
-              child = FlowyText.medium(state.content, fontSize: 14);
+              if (state.enableEdit) {
+                child = TextField(
+                  controller: _controller,
+                  focusNode: focusNode,
+                  onChanged: (value) => focusChanged(),
+                  onEditingComplete: () => focusNode.unfocus(),
+                  maxLines: 1,
+                  style: const TextStyle(
+                    fontSize: 14,
+                    fontWeight: FontWeight.w500,
+                    fontFamily: 'Mulish',
+                  ),
+                  decoration: const InputDecoration(
+                    // Magic number 4 makes the textField take up the same space as FlowyText
+                    contentPadding: EdgeInsets.symmetric(vertical: 4),
+                    border: InputBorder.none,
+                    isDense: true,
+                  ),
+                );
+              } else {
+                child = FlowyText.medium(state.content, fontSize: 14);
+                child = Padding(
+                  padding: const EdgeInsets.symmetric(vertical: 6),
+                  child: child,
+                );
+              }
             }
 
-            return Align(
-              alignment: Alignment.centerLeft,
-              child: Padding(
-                padding: const EdgeInsets.symmetric(vertical: 6),
-                child: child,
-              ),
-            );
+            return Align(alignment: Alignment.centerLeft, child: child);
           },
         ),
       ),

+ 5 - 14
frontend/app_flowy/lib/plugins/board/presentation/card/card.dart

@@ -100,20 +100,11 @@ class _BoardCardState extends State<BoardCard> {
         );
         rowNotifier.insertCell(cellId, cellNotifier);
 
-        if (index != 0) {
-          child = Padding(
-            key: cellId.key(),
-            padding: const EdgeInsets.only(left: 4, right: 4, top: 8),
-            child: child,
-          );
-        } else {
-          child = Padding(
-            key: UniqueKey(),
-            padding: const EdgeInsets.only(left: 4, right: 4),
-            child: child,
-          );
-        }
-
+        child = Padding(
+          key: cellId.key(),
+          padding: const EdgeInsets.only(left: 4, right: 4),
+          child: child,
+        );
         children.add(child);
       },
     );

+ 6 - 1
frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/grid_header.dart

@@ -1,7 +1,9 @@
+import 'package:app_flowy/generated/locale_keys.g.dart';
 import 'package:app_flowy/plugins/grid/application/field/field_cache.dart';
 import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart';
 import 'package:app_flowy/startup/startup.dart';
 import 'package:app_flowy/plugins/grid/application/prelude.dart';
+import 'package:easy_localization/easy_localization.dart';
 import 'package:flowy_infra/image.dart';
 import 'package:flowy_infra/theme.dart';
 import 'package:flowy_infra_ui/style_widget/button.dart';
@@ -155,7 +157,10 @@ class CreateFieldButton extends StatelessWidget {
     final theme = context.watch<AppTheme>();
 
     return FlowyButton(
-      text: const FlowyText.medium('New column', fontSize: 12),
+      text: FlowyText.medium(
+        LocaleKeys.grid_field_newColumn.tr(),
+        fontSize: 12,
+      ),
       hoverColor: theme.shader6,
       onTap: () => FieldEditor(
         gridId: gridId,

+ 66 - 21
frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/row_detail.dart

@@ -5,8 +5,10 @@ import 'package:app_flowy/plugins/grid/application/row/row_detail_bloc.dart';
 import 'package:flowy_infra/image.dart';
 import 'package:flowy_infra/theme.dart';
 import 'package:flowy_infra_ui/flowy_infra_ui.dart';
+import 'package:flowy_infra_ui/style_widget/button.dart';
 import 'package:flowy_infra_ui/style_widget/icon_button.dart';
 import 'package:flowy_infra_ui/style_widget/scrolling/styled_scroll_bar.dart';
+import 'package:flowy_infra_ui/style_widget/text.dart';
 import 'package:flowy_infra_ui/widget/spacing.dart';
 import 'package:easy_localization/easy_localization.dart';
 import 'package:app_flowy/generated/locale_keys.g.dart';
@@ -67,16 +69,21 @@ class _RowDetailPageState extends State<RowDetailPage> {
         return bloc;
       },
       child: Padding(
-        padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 20),
+        padding: const EdgeInsets.symmetric(horizontal: 30, vertical: 20),
         child: Column(
           children: [
             SizedBox(
-              height: 40,
+              height: 30,
               child: Row(
                 children: const [Spacer(), _CloseButton()],
               ),
             ),
-            Expanded(child: _PropertyList(cellBuilder: widget.cellBuilder)),
+            Expanded(
+              child: _PropertyList(
+                cellBuilder: widget.cellBuilder,
+                viewId: widget.dataController.rowInfo.gridId,
+              ),
+            ),
           ],
         ),
       ),
@@ -101,9 +108,11 @@ class _CloseButton extends StatelessWidget {
 }
 
 class _PropertyList extends StatelessWidget {
+  final String viewId;
   final GridCellBuilder cellBuilder;
   final ScrollController _scrollController;
   _PropertyList({
+    required this.viewId,
     required this.cellBuilder,
     Key? key,
   })  : _scrollController = ScrollController(),
@@ -114,29 +123,63 @@ class _PropertyList extends StatelessWidget {
     return BlocBuilder<RowDetailBloc, RowDetailState>(
       buildWhen: (previous, current) => previous.gridCells != current.gridCells,
       builder: (context, state) {
-        return ScrollbarListStack(
-          axis: Axis.vertical,
-          controller: _scrollController,
-          barSize: GridSize.scrollBarSize,
-          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);
-            },
-          ),
+        return Column(
+          children: [
+            Expanded(
+              child: ScrollbarListStack(
+                axis: Axis.vertical,
+                controller: _scrollController,
+                barSize: GridSize.scrollBarSize,
+                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);
+                  },
+                ),
+              ),
+            ),
+            _CreateFieldButton(viewId: viewId),
+          ],
         );
       },
     );
   }
 }
 
+class _CreateFieldButton extends StatelessWidget {
+  final String viewId;
+  const _CreateFieldButton({required this.viewId, Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    final theme = context.read<AppTheme>();
+
+    return SizedBox(
+      height: 40,
+      child: FlowyButton(
+        text: FlowyText.medium(
+          LocaleKeys.grid_field_newColumn.tr(),
+          fontSize: 12,
+        ),
+        hoverColor: theme.shader6,
+        onTap: () => FieldEditor(
+          gridId: viewId,
+          fieldName: "",
+          typeOptionLoader: NewFieldTypeOptionLoader(gridId: viewId),
+        ).show(context),
+        leftIcon: svgWidget("home/add"),
+      ),
+    );
+  }
+}
+
 class _RowDetailCell extends StatelessWidget {
   final GridCellIdentifier cellId;
   final GridCellBuilder cellBuilder;
@@ -172,7 +215,9 @@ class _RowDetailCell extends StatelessWidget {
             SizedBox(
               width: 150,
               child: FieldCellButton(
-                  field: cellId.field, onTap: () => _showFieldEditor(context)),
+                field: cellId.field,
+                onTap: () => _showFieldEditor(context),
+              ),
             ),
             const HSpace(10),
             Expanded(child: gesture),