Sfoglia il codice sorgente

chore: show edit field

appflowy 3 anni fa
parent
commit
c3c75dde9f

+ 17 - 5
frontend/app_flowy/lib/workspace/application/grid/field/type_option/date_bloc.dart

@@ -2,7 +2,7 @@ import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
 import 'dart:async';
-
+import 'package:protobuf/protobuf.dart';
 part 'date_bloc.freezed.dart';
 
 class DateTypeOptionBloc extends Bloc<DateTypeOptionEvent, DateTypeOptionState> {
@@ -11,18 +11,30 @@ class DateTypeOptionBloc extends Bloc<DateTypeOptionEvent, DateTypeOptionState>
       (event, emit) async {
         event.map(
           didSelectDateFormat: (_DidSelectDateFormat value) {
-            state.typeOption.dateFormat = value.format;
-            emit(state);
+            emit(state.copyWith(typeOption: _updateDateFormat(value.format)));
           },
           didSelectTimeFormat: (_DidSelectTimeFormat value) {
-            state.typeOption.timeFormat = value.format;
-            emit(state);
+            emit(state.copyWith(typeOption: _updateTimeFormat(value.format)));
           },
         );
       },
     );
   }
 
+  DateTypeOption _updateTimeFormat(TimeFormat format) {
+    state.typeOption.freeze();
+    return state.typeOption.rebuild((typeOption) {
+      typeOption.timeFormat = format;
+    });
+  }
+
+  DateTypeOption _updateDateFormat(DateFormat format) {
+    state.typeOption.freeze();
+    return state.typeOption.rebuild((typeOption) {
+      typeOption.dateFormat = format;
+    });
+  }
+
   @override
   Future<void> close() async {
     return super.close();

+ 9 - 2
frontend/app_flowy/lib/workspace/application/grid/field/type_option/number_bloc.dart

@@ -2,6 +2,7 @@ import 'package:flowy_sdk/protobuf/flowy-grid/number_type_option.pb.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
 import 'dart:async';
+import 'package:protobuf/protobuf.dart';
 
 part 'number_bloc.freezed.dart';
 
@@ -11,14 +12,20 @@ class NumberTypeOptionBloc extends Bloc<NumberTypeOptionEvent, NumberTypeOptionS
       (event, emit) async {
         event.map(
           didSelectFormat: (_DidSelectFormat value) {
-            state.typeOption.format = value.format;
-            emit(state);
+            emit(state.copyWith(typeOption: _updateNumberFormat(value.format)));
           },
         );
       },
     );
   }
 
+  NumberTypeOption _updateNumberFormat(NumberFormat format) {
+    state.typeOption.freeze();
+    return state.typeOption.rebuild((typeOption) {
+      typeOption.format = format;
+    });
+  }
+
   @override
   Future<void> close() async {
     return super.close();

+ 0 - 110
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/edit_field_pannel.dart

@@ -1,110 +0,0 @@
-import 'package:app_flowy/startup/startup.dart';
-import 'package:app_flowy/workspace/application/grid/prelude.dart';
-import 'package:flowy_infra_ui/flowy_infra_ui.dart';
-import 'package:flowy_infra_ui/widget/spacing.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-
-import 'field_name_input.dart';
-import 'field_operation_list.dart';
-import 'field_tyep_switcher.dart';
-
-class EditFieldPannel extends StatelessWidget {
-  final GridFieldData fieldData;
-  const EditFieldPannel({required this.fieldData, Key? key}) : super(key: key);
-
-  static void show(BuildContext context, GridFieldData fieldData) {
-    final editor = EditFieldPannel(fieldData: fieldData);
-    FlowyOverlay.of(context).insertWithAnchor(
-      widget: OverlayContainer(
-        child: editor,
-        constraints: BoxConstraints.loose(const Size(300, 200)),
-      ),
-      identifier: editor.identifier(),
-      anchorContext: context,
-      anchorDirection: AnchorDirection.bottomWithLeftAligned,
-    );
-  }
-
-  @override
-  Widget build(BuildContext context) {
-    return BlocProvider(
-      create: (context) => getIt<EditFieldBloc>(param1: fieldData)..add(const EditFieldEvent.initial()),
-      child: SingleChildScrollView(
-        child: Column(
-          children: [
-            const _FieldNameTextField(),
-            const VSpace(6),
-            const _FieldTypeSwitcher(),
-            const VSpace(6),
-            _FieldOperationList(fieldData, () => FlowyOverlay.of(context).remove(identifier())),
-          ],
-        ),
-      ),
-    );
-  }
-
-  String identifier() {
-    return toString();
-  }
-}
-
-class _FieldOperationList extends StatelessWidget {
-  final GridFieldData fieldData;
-  final VoidCallback onDismissed;
-  const _FieldOperationList(this.fieldData, this.onDismissed, {Key? key}) : super(key: key);
-
-  @override
-  Widget build(BuildContext context) {
-    final actions = FieldAction.values
-        .map(
-          (action) => FieldActionItem(
-            fieldId: fieldData.field.id,
-            action: action,
-            onTap: onDismissed,
-          ),
-        )
-        .toList();
-
-    return FieldOperationList(actions: actions);
-  }
-}
-
-class _FieldTypeSwitcher extends StatelessWidget {
-  const _FieldTypeSwitcher({Key? key}) : super(key: key);
-
-  @override
-  Widget build(BuildContext context) {
-    return BlocBuilder<EditFieldBloc, EditFieldState>(
-      builder: (context, state) {
-        final editContext = context.read<EditFieldBloc>().state.editContext;
-        final switchContext = SwitchFieldContext(
-          editContext.gridId,
-          editContext.gridField,
-          editContext.typeOptionData,
-        );
-        return FieldTypeSwitcher(switchContext: switchContext, onSelected: (field, typeOptionData) {});
-      },
-    );
-  }
-}
-
-class _FieldNameTextField extends StatelessWidget {
-  const _FieldNameTextField({Key? key}) : super(key: key);
-
-  @override
-  Widget build(BuildContext context) {
-    return BlocBuilder<EditFieldBloc, EditFieldState>(
-      buildWhen: ((previous, current) => previous.fieldName == current.fieldName),
-      builder: (context, state) {
-        return FieldNameTextField(
-          name: state.fieldName,
-          errorText: state.errorText,
-          onNameChanged: (newName) {
-            context.read<EditFieldBloc>().add(EditFieldEvent.updateFieldName(newName));
-          },
-        );
-      },
-    );
-  }
-}

+ 2 - 2
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/grid_header_cell.dart

@@ -7,7 +7,7 @@ import 'package:flowy_infra_ui/style_widget/text.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 
-import 'edit_field_pannel.dart';
+import 'field_detail_pannel.dart';
 
 class GridHeaderCell extends StatelessWidget {
   final GridFieldData fieldData;
@@ -18,7 +18,7 @@ class GridHeaderCell extends StatelessWidget {
     final theme = context.watch<AppTheme>();
     final button = FlowyButton(
       hoverColor: theme.hover,
-      onTap: () => EditFieldPannel.show(context, fieldData),
+      onTap: () => FieldDetailPannel.show(context, fieldData),
       rightIcon: svg("editor/details", color: theme.iconColor),
       text: Padding(padding: GridSize.cellContentInsets, child: FlowyText.medium(fieldData.field.name, fontSize: 12)),
     );

+ 52 - 15
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart

@@ -50,15 +50,15 @@ class DateTypeOptionWidget extends TypeOptionWidget {
         listener: (context, state) => dataDelegate.didUpdateTypeOptionData(state.typeOption.writeToBuffer()),
         builder: (context, state) {
           return Column(children: [
-            _dateFormatButton(context),
-            _timeFormatButton(context),
+            _dateFormatButton(context, state.typeOption.dateFormat),
+            _timeFormatButton(context, state.typeOption.timeFormat),
           ]);
         },
       ),
     );
   }
 
-  Widget _dateFormatButton(BuildContext context) {
+  Widget _dateFormatButton(BuildContext context, DateFormat dataFormat) {
     final theme = context.watch<AppTheme>();
     return SizedBox(
       height: GridSize.typeOptionItemHeight,
@@ -67,9 +67,12 @@ class DateTypeOptionWidget extends TypeOptionWidget {
         padding: GridSize.typeOptionContentInsets,
         hoverColor: theme.hover,
         onTap: () {
-          final list = DateFormatList(onSelected: (format) {
-            context.read<DateTypeOptionBloc>().add(DateTypeOptionEvent.didSelectDateFormat(format));
-          });
+          final list = DateFormatList(
+            selectedFormat: dataFormat,
+            onSelected: (format) {
+              context.read<DateTypeOptionBloc>().add(DateTypeOptionEvent.didSelectDateFormat(format));
+            },
+          );
           overlayDelegate.showOverlay(context, list);
         },
         rightIcon: svg("grid/more", color: theme.iconColor),
@@ -77,7 +80,7 @@ class DateTypeOptionWidget extends TypeOptionWidget {
     );
   }
 
-  Widget _timeFormatButton(BuildContext context) {
+  Widget _timeFormatButton(BuildContext context, TimeFormat timeFormat) {
     final theme = context.watch<AppTheme>();
     return SizedBox(
       height: GridSize.typeOptionItemHeight,
@@ -86,9 +89,11 @@ class DateTypeOptionWidget extends TypeOptionWidget {
         padding: GridSize.typeOptionContentInsets,
         hoverColor: theme.hover,
         onTap: () {
-          final list = TimeFormatList(onSelected: (format) {
-            context.read<DateTypeOptionBloc>().add(DateTypeOptionEvent.didSelectTimeFormat(format));
-          });
+          final list = TimeFormatList(
+              selectedFormat: timeFormat,
+              onSelected: (format) {
+                context.read<DateTypeOptionBloc>().add(DateTypeOptionEvent.didSelectTimeFormat(format));
+              });
           overlayDelegate.showOverlay(context, list);
         },
         rightIcon: svg("grid/more", color: theme.iconColor),
@@ -98,8 +103,9 @@ class DateTypeOptionWidget extends TypeOptionWidget {
 }
 
 class DateFormatList extends StatelessWidget {
+  final DateFormat selectedFormat;
   final Function(DateFormat format) onSelected;
-  const DateFormatList({required this.onSelected, Key? key}) : super(key: key);
+  const DateFormatList({required this.selectedFormat, required this.onSelected, Key? key}) : super(key: key);
 
   @override
   Widget build(BuildContext context) {
@@ -109,7 +115,8 @@ class DateFormatList extends StatelessWidget {
           onSelected: (format) {
             onSelected(format);
             FlowyOverlay.of(context).remove(identifier());
-          });
+          },
+          isSelected: selectedFormat == format);
     }).toList();
 
     return SizedBox(
@@ -134,18 +141,30 @@ class DateFormatList extends StatelessWidget {
 }
 
 class DateFormatItem extends StatelessWidget {
+  final bool isSelected;
   final DateFormat dateFormat;
   final Function(DateFormat format) onSelected;
-  const DateFormatItem({required this.dateFormat, required this.onSelected, Key? key}) : super(key: key);
+  const DateFormatItem({
+    required this.dateFormat,
+    required this.onSelected,
+    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/checkmark");
+    }
+
     return SizedBox(
       height: GridSize.typeOptionItemHeight,
       child: FlowyButton(
         text: FlowyText.medium(dateFormat.title(), fontSize: 12),
         hoverColor: theme.hover,
+        rightIcon: checkmark,
         onTap: () => onSelected(dateFormat),
       ),
     );
@@ -170,13 +189,19 @@ extension DateFormatExtension on DateFormat {
 }
 
 class TimeFormatList extends StatelessWidget {
+  final TimeFormat selectedFormat;
   final Function(TimeFormat format) onSelected;
-  const TimeFormatList({required this.onSelected, Key? key}) : super(key: key);
+  const TimeFormatList({
+    required this.selectedFormat,
+    required this.onSelected,
+    Key? key,
+  }) : super(key: key);
 
   @override
   Widget build(BuildContext context) {
     final formatItems = TimeFormat.values.map((format) {
       return TimeFormatItem(
+          isSelected: format == selectedFormat,
           timeFormat: format,
           onSelected: (format) {
             onSelected(format);
@@ -207,17 +232,29 @@ class TimeFormatList extends StatelessWidget {
 
 class TimeFormatItem extends StatelessWidget {
   final TimeFormat timeFormat;
+  final bool isSelected;
   final Function(TimeFormat format) onSelected;
-  const TimeFormatItem({required this.timeFormat, required this.onSelected, Key? key}) : super(key: key);
+  const TimeFormatItem({
+    required this.timeFormat,
+    required this.onSelected,
+    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/checkmark");
+    }
+
     return SizedBox(
       height: GridSize.typeOptionItemHeight,
       child: FlowyButton(
         text: FlowyText.medium(timeFormat.title(), fontSize: 12),
         hoverColor: theme.hover,
+        rightIcon: checkmark,
         onTap: () => onSelected(timeFormat),
       ),
     );