Browse Source

chore: create the default group for the rows that are not belong to any groups

appflowy 2 năm trước cách đây
mục cha
commit
dc53cb00dd

+ 11 - 1
frontend/app_flowy/lib/plugins/board/application/board_bloc.dart

@@ -55,10 +55,19 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
           createRow: () async {
             final result = await _dataController.createRow();
             result.fold(
-              (rowPB) => null,
+              (rowPB) {
+                emit(state.copyWith(editingRow: some(rowPB)));
+              },
               (err) => Log.error(err),
             );
           },
+          endEditRow: (rowId) {
+            assert(state.editingRow.isSome());
+            state.editingRow.fold(() => null, (row) {
+              assert(row.id == rowId);
+              emit(state.copyWith(editingRow: none()));
+            });
+          },
           didReceiveGridUpdate: (GridPB grid) {
             emit(state.copyWith(grid: Some(grid)));
           },
@@ -145,6 +154,7 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
 class BoardEvent with _$BoardEvent {
   const factory BoardEvent.initial() = InitialGrid;
   const factory BoardEvent.createRow() = _CreateRow;
+  const factory BoardEvent.endEditRow(String rowId) = _EndEditRow;
   const factory BoardEvent.didReceiveGroups(List<GroupPB> groups) =
       _DidReceiveGroup;
   const factory BoardEvent.didReceiveRows(List<RowInfo> rowInfos) =

+ 3 - 1
frontend/app_flowy/lib/plugins/board/application/board_data_controller.dart

@@ -123,7 +123,9 @@ class BoardDataController {
         fieldCache: fieldCache,
       );
 
-      // cache.addListener(onRowsChanged: (rows, reason) {})
+      cache.addListener(onRowsChanged: (reason) {
+        _onRowsChanged?.call(rowInfos, reason);
+      });
       _blocks[block.id] = cache;
     }
 

+ 17 - 7
frontend/app_flowy/lib/plugins/board/presentation/board_page.dart

@@ -53,7 +53,7 @@ class BoardContent extends StatelessWidget {
           child: Padding(
             padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 20),
             child: AFBoard(
-              key: UniqueKey(),
+              // key: UniqueKey(),
               scrollController: ScrollController(),
               dataController: context.read<BoardBloc>().boardDataController,
               headerBuilder: _buildHeader,
@@ -83,11 +83,13 @@ class BoardContent extends StatelessWidget {
 
   Widget _buildFooter(BuildContext context, AFBoardColumnData columnData) {
     return AppFlowyColumnFooter(
-      icon: const Icon(Icons.add, size: 20),
-      title: const Text('New'),
-      height: 50,
-      margin: config.columnItemPadding,
-    );
+        icon: const Icon(Icons.add, size: 20),
+        title: const Text('New'),
+        height: 50,
+        margin: config.columnItemPadding,
+        onAddButtonClick: () {
+          context.read<BoardBloc>().add(const BoardEvent.createRow());
+        });
   }
 
   Widget _buildCard(BuildContext context, AFColumnItem item) {
@@ -106,13 +108,21 @@ class BoardContent extends StatelessWidget {
     );
 
     final cellBuilder = BoardCellBuilder(cardController);
+    final isEditing = context.read<BoardBloc>().state.editingRow.fold(
+          () => false,
+          (editingRow) => editingRow.id == rowPB.id,
+        );
 
     return AppFlowyColumnItemCard(
       key: ObjectKey(item),
       child: BoardCard(
+        gridId: gridId,
+        isEditing: isEditing,
         cellBuilder: cellBuilder,
         dataController: cardController,
-        gridId: gridId,
+        onEditEditing: (rowId) {
+          context.read<BoardBloc>().add(BoardEvent.endEditRow(rowId));
+        },
       ),
     );
   }

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

@@ -9,15 +9,21 @@ import 'package:flutter_bloc/flutter_bloc.dart';
 import 'card_cell_builder.dart';
 import 'card_container.dart';
 
+typedef OnEndEditing = void Function(String rowId);
+
 class BoardCard extends StatefulWidget {
   final String gridId;
+  final bool isEditing;
   final CardDataController dataController;
   final BoardCellBuilder cellBuilder;
+  final OnEndEditing onEditEditing;
 
   const BoardCard({
     required this.gridId,
+    required this.isEditing,
     required this.dataController,
     required this.cellBuilder,
+    required this.onEditEditing,
     Key? key,
   }) : super(key: key);
 
@@ -60,7 +66,6 @@ class _BoardCardState extends State<BoardCard> {
     return cellMap.values.map(
       (cellId) {
         final child = widget.cellBuilder.buildCell(cellId);
-
         return Padding(
           padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
           child: child,

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

@@ -29,9 +29,13 @@ class BoardCardContainer extends StatelessWidget {
               );
             }
           }
+
           return Padding(
             padding: const EdgeInsets.all(8),
-            child: container,
+            child: ConstrainedBox(
+              constraints: const BoxConstraints(minHeight: 30),
+              child: container,
+            ),
           );
         },
       ),

+ 3 - 3
frontend/rust-lib/flowy-grid/src/event_handler.rs

@@ -266,11 +266,11 @@ pub(crate) async fn duplicate_row_handler(
 pub(crate) async fn create_row_handler(
     data: Data<CreateRowPayloadPB>,
     manager: AppData<Arc<GridManager>>,
-) -> Result<(), FlowyError> {
+) -> DataResult<RowPB, FlowyError> {
     let params: CreateRowParams = data.into_inner().try_into()?;
     let editor = manager.get_grid_editor(params.grid_id.as_ref())?;
-    let _ = editor.create_row(params.start_row_id).await?;
-    Ok(())
+    let row = editor.create_row(params.start_row_id).await?;
+    data_result(row)
 }
 
 // #[tracing::instrument(level = "debug", skip_all, err)]

+ 28 - 5
frontend/rust-lib/flowy-grid/src/services/group/group_generator/generator.rs

@@ -34,9 +34,12 @@ pub trait GroupGenerator {
     ) -> Vec<Group>;
 }
 
+const DEFAULT_GROUP_ID: &str = "default_group";
+
 pub struct GroupController<C, T, G, CP> {
     pub field_rev: Arc<FieldRevision>,
     pub groups: IndexMap<String, Group>,
+    pub default_group: Group,
     pub type_option: Option<T>,
     pub configuration: Option<C>,
     group_action_phantom: PhantomData<G>,
@@ -78,9 +81,18 @@ where
         let field_type_rev = field_rev.field_type_rev;
         let type_option = field_rev.get_type_option_entry::<T>(field_type_rev);
         let groups = G::gen_groups(&configuration, &type_option, cell_content_provider);
+
+        let default_group = Group {
+            id: DEFAULT_GROUP_ID.to_owned(),
+            desc: format!("No {}", field_rev.name),
+            rows: vec![],
+            content: "".to_string(),
+        };
+
         Ok(Self {
             field_rev,
             groups: groups.into_iter().map(|group| (group.id.clone(), group)).collect(),
+            default_group,
             type_option,
             configuration,
             group_action_phantom: PhantomData,
@@ -89,7 +101,12 @@ where
     }
 
     pub fn take_groups(self) -> Vec<Group> {
-        self.groups.into_values().collect()
+        let default_group = self.default_group;
+        let mut groups: Vec<Group> = self.groups.into_values().collect();
+        if !default_group.rows.is_empty() {
+            groups.push(default_group);
+        }
+        groups
     }
 }
 
@@ -102,6 +119,7 @@ where
         if self.configuration.is_none() {
             return Ok(());
         }
+        tracing::debug!("group {} rows", rows.len());
 
         for row in rows {
             if let Some(cell_rev) = row.cells.get(&self.field_rev.id) {
@@ -115,15 +133,20 @@ where
                             row: row.into(),
                             group_id: group.id.clone(),
                         });
-                        break;
                     }
                 }
 
-                for record in records {
-                    if let Some(group) = self.groups.get_mut(&record.group_id) {
-                        group.rows.push(record.row);
+                if records.is_empty() {
+                    self.default_group.rows.push(row.into());
+                } else {
+                    for record in records {
+                        if let Some(group) = self.groups.get_mut(&record.group_id) {
+                            group.rows.push(record.row);
+                        }
                     }
                 }
+            } else {
+                self.default_group.rows.push(row.into());
             }
         }