appflowy пре 3 година
родитељ
комит
bf93376cf3

+ 1 - 1
frontend/app_flowy/lib/workspace/application/grid/cell/select_option_service.dart

@@ -94,7 +94,7 @@ class SelectOptionService {
     return GridEventUpdateCellSelectOption(payload).send();
   }
 
-  Future<Either<void, FlowyError>> remove({
+  Future<Either<void, FlowyError>> unSelect({
     required String gridId,
     required String fieldId,
     required String rowId,

+ 18 - 8
frontend/app_flowy/lib/workspace/application/grid/cell/selection_editor_bloc.dart

@@ -51,7 +51,7 @@ class SelectOptionEditorBloc extends Bloc<SelectOptionEditorEvent, SelectOptionE
             _updateOption(value.option);
           },
           selectOption: (_SelectOption value) {
-            _makeOptionAsSelected(value.optionId);
+            _onSelectOption(value.optionId);
           },
         );
       },
@@ -98,13 +98,23 @@ class SelectOptionEditorBloc extends Bloc<SelectOptionEditorEvent, SelectOptionE
     result.fold((l) => null, (err) => Log.error(err));
   }
 
-  void _makeOptionAsSelected(String optionId) {
-    _selectOptionService.select(
-      gridId: state.gridId,
-      fieldId: state.field.id,
-      rowId: state.rowId,
-      optionId: optionId,
-    );
+  void _onSelectOption(String optionId) {
+    final hasSelected = state.selectedOptions.firstWhereOrNull((option) => option.id == optionId);
+    if (hasSelected != null) {
+      _selectOptionService.unSelect(
+        gridId: state.gridId,
+        fieldId: state.field.id,
+        rowId: state.rowId,
+        optionId: optionId,
+      );
+    } else {
+      _selectOptionService.select(
+        gridId: state.gridId,
+        fieldId: state.field.id,
+        rowId: state.rowId,
+        optionId: optionId,
+      );
+    }
   }
 
   void _loadOptions() async {

+ 3 - 3
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart

@@ -16,13 +16,13 @@ GridCellWidget buildGridCell(GridCell cellData, {GridCellStyle? style}) {
     case FieldType.DateTime:
       return DateCell(cellData: cellData, key: key);
     case FieldType.MultiSelect:
-      return MultiSelectCell(cellData: cellData, key: key);
+      return MultiSelectCell(cellData: cellData, style: style, key: key);
     case FieldType.Number:
       return NumberCell(cellData: cellData, key: key);
     case FieldType.RichText:
-      return GridTextCell(cellData: cellData, key: key, style: style);
+      return GridTextCell(cellData: cellData, style: style, key: key);
     case FieldType.SingleSelect:
-      return SingleSelectCell(cellData: cellData, key: key);
+      return SingleSelectCell(cellData: cellData, style: style, key: key);
     default:
       throw UnimplementedError;
   }

+ 42 - 4
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/selection_cell/selection_cell.dart

@@ -1,19 +1,37 @@
 import 'package:app_flowy/startup/startup.dart';
 import 'package:app_flowy/workspace/application/grid/prelude.dart';
 import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart';
+import 'package:flowy_infra/theme.dart';
+import 'package:flowy_infra_ui/style_widget/text.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 
 import 'extension.dart';
 import 'selection_editor.dart';
 
+class SelectOptionCellStyle extends GridCellStyle {
+  String placeholder;
+
+  SelectOptionCellStyle({
+    required this.placeholder,
+  });
+}
+
 class SingleSelectCell extends GridCellWidget {
   final GridCell cellData;
+  late final SelectOptionCellStyle? cellStyle;
 
   SingleSelectCell({
     required this.cellData,
+    GridCellStyle? style,
     Key? key,
-  }) : super(key: key);
+  }) : super(key: key) {
+    if (style != null) {
+      cellStyle = (style as SelectOptionCellStyle);
+    } else {
+      cellStyle = null;
+    }
+  }
 
   @override
   State<SingleSelectCell> createState() => _SingleSelectCellState();
@@ -30,11 +48,18 @@ class _SingleSelectCellState extends State<SingleSelectCell> {
 
   @override
   Widget build(BuildContext context) {
+    final theme = context.watch<AppTheme>();
+
     return BlocProvider.value(
       value: _cellBloc,
       child: BlocBuilder<SelectionCellBloc, SelectionCellState>(
         builder: (context, state) {
-          final children = state.selectedOptions.map((option) => SelectOptionTag(option: option)).toList();
+          List<Widget> children = [];
+          children.addAll(state.selectedOptions.map((option) => SelectOptionTag(option: option)).toList());
+
+          if (children.isEmpty && widget.cellStyle != null) {
+            children.add(FlowyText.medium(widget.cellStyle!.placeholder, fontSize: 14, color: theme.shader3));
+          }
           return SizedBox.expand(
             child: InkWell(
               onTap: () {
@@ -65,11 +90,19 @@ class _SingleSelectCellState extends State<SingleSelectCell> {
 //----------------------------------------------------------------
 class MultiSelectCell extends GridCellWidget {
   final GridCell cellData;
+  late final SelectOptionCellStyle? cellStyle;
 
   MultiSelectCell({
     required this.cellData,
+    GridCellStyle? style,
     Key? key,
-  }) : super(key: key);
+  }) : super(key: key) {
+    if (style != null) {
+      cellStyle = (style as SelectOptionCellStyle);
+    } else {
+      cellStyle = null;
+    }
+  }
 
   @override
   State<MultiSelectCell> createState() => _MultiSelectCellState();
@@ -90,7 +123,12 @@ class _MultiSelectCellState extends State<MultiSelectCell> {
       value: _cellBloc,
       child: BlocBuilder<SelectionCellBloc, SelectionCellState>(
         builder: (context, state) {
-          final children = state.selectedOptions.map((option) => SelectOptionTag(option: option)).toList();
+          List<Widget> children = state.selectedOptions.map((option) => SelectOptionTag(option: option)).toList();
+
+          if (children.isEmpty && widget.cellStyle != null) {
+            children.add(FlowyText.medium(widget.cellStyle!.placeholder, fontSize: 14));
+          }
+
           return SizedBox.expand(
             child: InkWell(
               onTap: () {

+ 28 - 14
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/row_detail.dart

@@ -1,12 +1,14 @@
 import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
 import 'package:app_flowy/workspace/application/grid/row/row_detail_bloc.dart';
 import 'package:app_flowy/workspace/application/grid/row/row_service.dart';
+import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart';
 import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/cell/prelude.dart';
 import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_cell.dart';
 import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/header/field_editor.dart';
 import 'package:flowy_infra/theme.dart';
 import 'package:flowy_infra_ui/flowy_infra_ui.dart';
 import 'package:flowy_infra_ui/style_widget/hover.dart';
+import 'package:flowy_infra_ui/style_widget/scrolling/styled_scroll_bar.dart';
 import 'package:flowy_infra_ui/widget/spacing.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show FieldType;
 import 'package:easy_localization/easy_localization.dart';
@@ -59,8 +61,8 @@ class _RowDetailPageState extends State<RowDetailPage> {
         bloc.add(const RowDetailEvent.initial());
         return bloc;
       },
-      child: const Padding(
-        padding: EdgeInsets.symmetric(horizontal: 80, vertical: 40),
+      child: Padding(
+        padding: const EdgeInsets.symmetric(horizontal: 80, vertical: 40),
         child: _PropertyList(),
       ),
     );
@@ -68,23 +70,31 @@ class _RowDetailPageState extends State<RowDetailPage> {
 }
 
 class _PropertyList extends StatelessWidget {
-  const _PropertyList({
+  final ScrollController _scrollController;
+  _PropertyList({
     Key? key,
-  }) : super(key: key);
+  })  : _scrollController = ScrollController(),
+        super(key: key);
 
   @override
   Widget build(BuildContext context) {
     return BlocBuilder<RowDetailBloc, RowDetailState>(
       buildWhen: (previous, current) => previous.cellDatas != current.cellDatas,
       builder: (context, state) {
-        return ListView.separated(
-          itemCount: state.cellDatas.length,
-          itemBuilder: (BuildContext context, int index) {
-            return _RowDetailCell(cellData: state.cellDatas[index]);
-          },
-          separatorBuilder: (BuildContext context, int index) {
-            return const VSpace(2);
-          },
+        return ScrollbarListStack(
+          axis: Axis.vertical,
+          controller: _scrollController,
+          barSize: GridSize.scrollBarSize,
+          child: ListView.separated(
+            controller: _scrollController,
+            itemCount: state.cellDatas.length,
+            itemBuilder: (BuildContext context, int index) {
+              return _RowDetailCell(cellData: state.cellDatas[index]);
+            },
+            separatorBuilder: (BuildContext context, int index) {
+              return const VSpace(2);
+            },
+          ),
         );
       },
     );
@@ -142,7 +152,9 @@ GridCellStyle? _buildCellStyle(AppTheme theme, FieldType fieldType) {
     case FieldType.DateTime:
       return null;
     case FieldType.MultiSelect:
-      return null;
+      return SelectOptionCellStyle(
+        placeholder: LocaleKeys.grid_row_textPlaceholder.tr(),
+      );
     case FieldType.Number:
       return null;
     case FieldType.RichText:
@@ -150,7 +162,9 @@ GridCellStyle? _buildCellStyle(AppTheme theme, FieldType fieldType) {
         placeholder: LocaleKeys.grid_row_textPlaceholder.tr(),
       );
     case FieldType.SingleSelect:
-      return null;
+      return SelectOptionCellStyle(
+        placeholder: LocaleKeys.grid_row_textPlaceholder.tr(),
+      );
     default:
       return null;
   }

+ 1 - 1
frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/text.dart

@@ -46,7 +46,7 @@ class FlowyText extends StatelessWidget {
         style: TextStyle(
           color: color ?? theme.textColor,
           fontWeight: fontWeight,
-          fontSize: fontSize + 2,
+          fontSize: fontSize,
           fontFamily: 'Mulish',
         ));
   }