Browse Source

chore: config checkbox ui

appflowy 2 years ago
parent
commit
5b92805e93

+ 62 - 27
frontend/app_flowy/lib/plugins/board/application/board_bloc.dart

@@ -1,4 +1,6 @@
 import 'dart:async';
+import 'dart:collection';
+
 import 'package:app_flowy/plugins/grid/application/block/block_cache.dart';
 import 'package:app_flowy/plugins/grid/application/field/field_controller.dart';
 import 'package:app_flowy/plugins/grid/application/row/row_cache.dart';
@@ -12,7 +14,6 @@ import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/protobuf.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
-import 'dart:collection';
 
 import 'board_data_controller.dart';
 import 'group_controller.dart';
@@ -164,12 +165,17 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
     boardController.clear();
 
     //
-    List<AFBoardColumnData> columns = groups.map((group) {
+    List<AFBoardColumnData> columns = groups
+        .where((group) => fieldController.getField(group.fieldId) != null)
+        .map((group) {
       return AFBoardColumnData(
         id: group.groupId,
         name: group.desc,
         items: _buildRows(group),
-        customData: group,
+        customData: BoardCustomData(
+          group: group,
+          fieldContext: fieldController.getField(group.fieldId)!,
+        ),
       );
     }).toList();
     boardController.addColumns(columns);
@@ -177,6 +183,7 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
     for (final group in groups) {
       final delegate = GroupControllerDelegateImpl(
         controller: boardController,
+        fieldController: fieldController,
         onNewColumnItem: (groupId, row, index) {
           add(BoardEvent.didCreateRow(groupId, row, index));
         },
@@ -238,10 +245,8 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
 
   List<AFColumnItem> _buildRows(GroupPB group) {
     final items = group.rows.map((row) {
-      return BoardColumnItem(
-        row: row,
-        fieldId: group.fieldId,
-      );
+      final fieldContext = fieldController.getField(group.fieldId);
+      return BoardColumnItem(row: row, fieldContext: fieldContext!);
     }).toList();
 
     return <AFColumnItem>[...items];
@@ -332,15 +337,11 @@ class GridFieldEquatable extends Equatable {
 
 class BoardColumnItem extends AFColumnItem {
   final RowPB row;
-
-  final String fieldId;
-
-  final bool requestFocus;
+  final GridFieldContext fieldContext;
 
   BoardColumnItem({
     required this.row,
-    required this.fieldId,
-    this.requestFocus = false,
+    required this.fieldContext,
   });
 
   @override
@@ -348,24 +349,29 @@ class BoardColumnItem extends AFColumnItem {
 }
 
 class GroupControllerDelegateImpl extends GroupControllerDelegate {
+  final GridFieldController fieldController;
   final AFBoardDataController controller;
   final void Function(String, RowPB, int?) onNewColumnItem;
 
   GroupControllerDelegateImpl({
     required this.controller,
+    required this.fieldController,
     required this.onNewColumnItem,
   });
 
   @override
   void insertRow(GroupPB group, RowPB row, int? index) {
+    final fieldContext = fieldController.getField(group.fieldId);
+    if (fieldContext == null) {
+      Log.warn("FieldContext should not be null");
+      return;
+    }
+
     if (index != null) {
-      final item = BoardColumnItem(row: row, fieldId: group.fieldId);
+      final item = BoardColumnItem(row: row, fieldContext: fieldContext);
       controller.insertColumnItem(group.groupId, index, item);
     } else {
-      final item = BoardColumnItem(
-        row: row,
-        fieldId: group.fieldId,
-      );
+      final item = BoardColumnItem(row: row, fieldContext: fieldContext);
       controller.addColumnItem(group.groupId, item);
     }
   }
@@ -377,22 +383,25 @@ class GroupControllerDelegateImpl extends GroupControllerDelegate {
 
   @override
   void updateRow(GroupPB group, RowPB row) {
+    final fieldContext = fieldController.getField(group.fieldId);
+    if (fieldContext == null) {
+      Log.warn("FieldContext should not be null");
+      return;
+    }
     controller.updateColumnItem(
       group.groupId,
-      BoardColumnItem(
-        row: row,
-        fieldId: group.fieldId,
-      ),
+      BoardColumnItem(row: row, fieldContext: fieldContext),
     );
   }
 
   @override
   void addNewRow(GroupPB group, RowPB row, int? index) {
-    final item = BoardColumnItem(
-      row: row,
-      fieldId: group.fieldId,
-      requestFocus: true,
-    );
+    final fieldContext = fieldController.getField(group.fieldId);
+    if (fieldContext == null) {
+      Log.warn("FieldContext should not be null");
+      return;
+    }
+    final item = BoardColumnItem(row: row, fieldContext: fieldContext);
 
     if (index != null) {
       controller.insertColumnItem(group.groupId, index, item);
@@ -414,3 +423,29 @@ class BoardEditingRow {
     required this.index,
   });
 }
+
+class BoardCustomData {
+  final GroupPB group;
+  final GridFieldContext fieldContext;
+  BoardCustomData({
+    required this.group,
+    required this.fieldContext,
+  });
+
+  CheckboxGroup? asCheckboxGroup() {
+    if (fieldType != FieldType.Checkbox) return null;
+    return CheckboxGroup(group);
+  }
+
+  FieldType get fieldType => fieldContext.fieldType;
+}
+
+class CheckboxGroup {
+  final GroupPB group;
+
+  CheckboxGroup(this.group);
+
+// Hardcode value: "Yes" that equal to the value defined in Rust
+// pub const CHECK: &str = "Yes";
+  bool get isCheck => group.groupId == "Yes";
+}

+ 70 - 32
frontend/app_flowy/lib/plugins/board/presentation/board_page.dart

@@ -17,7 +17,7 @@ import 'package:flowy_infra_ui/style_widget/text.dart';
 import 'package:flowy_infra_ui/widget/error_page.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/block_entities.pb.dart';
-import 'package:flowy_sdk/protobuf/flowy-grid/group.pbserver.dart';
+import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import '../../grid/application/row/row_cache.dart';
@@ -36,8 +36,7 @@ class BoardPage extends StatelessWidget {
       create: (context) =>
           BoardBloc(view: view)..add(const BoardEvent.initial()),
       child: BlocBuilder<BoardBloc, BoardState>(
-        buildWhen: (previous, current) =>
-            previous.loadingState != current.loadingState,
+        buildWhen: (p, c) => p.loadingState != c.loadingState,
         builder: (context, state) {
           return state.loadingState.map(
             loading: (_) =>
@@ -84,36 +83,15 @@ class _BoardContentState extends State<BoardContent> {
       child: BlocBuilder<BoardBloc, BoardState>(
         buildWhen: (previous, current) => previous.groupIds != current.groupIds,
         builder: (context, state) {
-          final theme = context.read<AppTheme>();
+          final column = Column(
+            children: [const _ToolbarBlocAdaptor(), _buildBoard(context)],
+          );
+
           return Container(
-            color: theme.surface,
+            color: context.read<AppTheme>().surface,
             child: Padding(
               padding: const EdgeInsets.symmetric(horizontal: 20),
-              child: Column(
-                children: [
-                  const _ToolbarBlocAdaptor(),
-                  Expanded(
-                    child: AFBoard(
-                      key: UniqueKey(),
-                      scrollManager: scrollManager,
-                      scrollController: scrollController,
-                      dataController: context.read<BoardBloc>().boardController,
-                      headerBuilder: _buildHeader,
-                      footBuilder: _buildFooter,
-                      cardBuilder: (_, column, columnItem) => _buildCard(
-                        context,
-                        column,
-                        columnItem,
-                      ),
-                      columnConstraints:
-                          const BoxConstraints.tightFor(width: 300),
-                      config: AFBoardConfig(
-                        columnBackgroundColor: HexColor.fromHex('#F7F8FC'),
-                      ),
-                    ),
-                  ),
-                ],
-              ),
+              child: column,
             ),
           );
         },
@@ -121,6 +99,27 @@ class _BoardContentState extends State<BoardContent> {
     );
   }
 
+  Expanded _buildBoard(BuildContext context) {
+    return Expanded(
+      child: AFBoard(
+        scrollManager: scrollManager,
+        scrollController: scrollController,
+        dataController: context.read<BoardBloc>().boardController,
+        headerBuilder: _buildHeader,
+        footBuilder: _buildFooter,
+        cardBuilder: (_, column, columnItem) => _buildCard(
+          context,
+          column,
+          columnItem,
+        ),
+        columnConstraints: const BoxConstraints.tightFor(width: 300),
+        config: AFBoardConfig(
+          columnBackgroundColor: HexColor.fromHex('#F7F8FC'),
+        ),
+      ),
+    );
+  }
+
   void _handleEditState(BoardState state, BuildContext context) {
     state.editingRow.fold(
       () => null,
@@ -152,6 +151,7 @@ class _BoardContentState extends State<BoardContent> {
     BuildContext context,
     AFBoardColumnData columnData,
   ) {
+    final boardCustomData = columnData.customData as BoardCustomData;
     return AppFlowyColumnHeader(
       title: Flexible(
         fit: FlexFit.tight,
@@ -162,6 +162,7 @@ class _BoardContentState extends State<BoardContent> {
           color: context.read<AppTheme>().textColor,
         ),
       ),
+      icon: _buildHeaderIcon(boardCustomData),
       addIcon: SizedBox(
         height: 20,
         width: 20,
@@ -181,7 +182,9 @@ class _BoardContentState extends State<BoardContent> {
   }
 
   Widget _buildFooter(BuildContext context, AFBoardColumnData columnData) {
-    final group = columnData.customData as GroupPB;
+    final boardCustomData = columnData.customData as BoardCustomData;
+    final group = boardCustomData.group;
+
     if (group.isDefault) {
       return const SizedBox();
     } else {
@@ -246,7 +249,7 @@ class _BoardContentState extends State<BoardContent> {
       child: BoardCard(
         gridId: gridId,
         groupId: column.id,
-        fieldId: boardColumnItem.fieldId,
+        fieldId: boardColumnItem.fieldContext.id,
         isEditing: isEditing,
         cellBuilder: cellBuilder,
         dataController: cardController,
@@ -319,3 +322,38 @@ extension HexColor on Color {
     return Color(int.parse(buffer.toString(), radix: 16));
   }
 }
+
+Widget? _buildHeaderIcon(BoardCustomData customData) {
+  Widget? widget;
+  switch (customData.fieldType) {
+    case FieldType.Checkbox:
+      final group = customData.asCheckboxGroup()!;
+      if (group.isCheck) {
+        widget = svgWidget('editor/editor_check');
+      } else {
+        widget = svgWidget('editor/editor_uncheck');
+      }
+      break;
+    case FieldType.DateTime:
+      break;
+    case FieldType.MultiSelect:
+      break;
+    case FieldType.Number:
+      break;
+    case FieldType.RichText:
+      break;
+    case FieldType.SingleSelect:
+      break;
+    case FieldType.URL:
+      break;
+  }
+
+  if (widget != null) {
+    widget = SizedBox(
+      width: 20,
+      height: 20,
+      child: widget,
+    );
+  }
+  return widget;
+}

+ 22 - 9
frontend/app_flowy/lib/plugins/grid/application/field/field_controller.dart

@@ -7,6 +7,7 @@ import 'package:dartz/dartz.dart';
 import 'package:flowy_sdk/log.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-grid/group.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/setting_entities.pb.dart';
 import 'package:flutter/foundation.dart';
 import '../row/row_cache.dart';
@@ -35,12 +36,12 @@ class GridFieldController {
   final SettingListener _settingListener;
   final Map<OnReceiveFields, VoidCallback> _fieldCallbackMap = {};
   final Map<OnChangeset, OnChangeset> _changesetCallbackMap = {};
-
-  _GridFieldNotifier? _fieldNotifier = _GridFieldNotifier();
-  List<String> _groupFieldIds = [];
   final GridFFIService _gridFFIService;
   final SettingFFIService _settingFFIService;
 
+  _GridFieldNotifier? _fieldNotifier = _GridFieldNotifier();
+  final Map<String, GridGroupConfigurationPB> _configurationByFieldId = {};
+
   List<GridFieldContext> get fieldContexts =>
       [..._fieldNotifier?.fieldContexts ?? []];
 
@@ -67,31 +68,43 @@ class GridFieldController {
     //Listen on setting changes
     _settingListener.start(onSettingUpdated: (result) {
       result.fold(
-        (setting) => _updateFieldsWhenSettingChanged(setting),
+        (setting) => _updateGroupConfiguration(setting),
         (r) => Log.error(r),
       );
     });
 
     _settingFFIService.getSetting().then((result) {
       result.fold(
-        (setting) => _updateFieldsWhenSettingChanged(setting),
+        (setting) => _updateGroupConfiguration(setting),
         (err) => Log.error(err),
       );
     });
   }
 
-  void _updateFieldsWhenSettingChanged(GridSettingPB setting) {
-    _groupFieldIds = setting.groupConfigurations.items
-        .map((item) => item.groupFieldId)
+  GridFieldContext? getField(String fieldId) {
+    final fields = _fieldNotifier?.fieldContexts
+        .where(
+          (element) => element.id == fieldId,
+        )
         .toList();
+    if (fields?.isEmpty ?? true) {
+      return null;
+    }
+    return fields!.first;
+  }
 
+  void _updateGroupConfiguration(GridSettingPB setting) {
+    _configurationByFieldId.clear();
+    for (final configuration in setting.groupConfigurations.items) {
+      _configurationByFieldId[configuration.fieldId] = configuration;
+    }
     _updateFieldContexts();
   }
 
   void _updateFieldContexts() {
     if (_fieldNotifier != null) {
       for (var field in _fieldNotifier!.fieldContexts) {
-        if (_groupFieldIds.contains(field.id)) {
+        if (_configurationByFieldId[field.id] != null) {
           field._isGroupField = true;
         } else {
           field._isGroupField = false;

+ 1 - 1
frontend/app_flowy/packages/appflowy_board/lib/src/widgets/board_column/board_column.dart

@@ -31,7 +31,7 @@ typedef AFBoardColumnCardBuilder = Widget Function(
 
 typedef AFBoardColumnHeaderBuilder = Widget? Function(
   BuildContext context,
-  AFBoardColumnData headerData,
+  AFBoardColumnData columnData,
 );
 
 typedef AFBoardColumnFooterBuilder = Widget Function(

+ 2 - 2
frontend/rust-lib/flowy-grid/src/entities/group_entities/group.rs

@@ -44,14 +44,14 @@ pub struct GridGroupConfigurationPB {
     pub id: String,
 
     #[pb(index = 2)]
-    pub group_field_id: String,
+    pub field_id: String,
 }
 
 impl std::convert::From<&GroupConfigurationRevision> for GridGroupConfigurationPB {
     fn from(rev: &GroupConfigurationRevision) -> Self {
         GridGroupConfigurationPB {
             id: rev.id.clone(),
-            group_field_id: rev.field_id.clone(),
+            field_id: rev.field_id.clone(),
         }
     }
 }