diff --git a/frontend/app_flowy/lib/plugins/board/application/board_bloc.dart b/frontend/app_flowy/lib/plugins/board/application/board_bloc.dart index 422f1dff2b..7c04dec814 100644 --- a/frontend/app_flowy/lib/plugins/board/application/board_bloc.dart +++ b/frontend/app_flowy/lib/plugins/board/application/board_bloc.dart @@ -317,9 +317,6 @@ class GroupControllerDelegateImpl extends GroupControllerDelegate { @override void updateRow(String groupId, RowPB row) { - // workaround: fix the board card reload timing issue. - Future.delayed(const Duration(milliseconds: 300), () { - controller.updateColumnItem(groupId, BoardColumnItem(row: row)); - }); + controller.updateColumnItem(groupId, BoardColumnItem(row: row)); } } diff --git a/frontend/app_flowy/lib/plugins/board/application/card/board_select_option_cell_bloc.dart b/frontend/app_flowy/lib/plugins/board/application/card/board_select_option_cell_bloc.dart index df36033cfa..1b70710a35 100644 --- a/frontend/app_flowy/lib/plugins/board/application/card/board_select_option_cell_bloc.dart +++ b/frontend/app_flowy/lib/plugins/board/application/card/board_select_option_cell_bloc.dart @@ -68,7 +68,6 @@ class BoardSelectOptionCellState with _$BoardSelectOptionCellState { factory BoardSelectOptionCellState.initial( GridSelectOptionCellController context) { final data = context.getCellData(); - return BoardSelectOptionCellState( selectedOptions: data?.selectOptions ?? [], ); diff --git a/frontend/app_flowy/lib/plugins/board/presentation/board_page.dart b/frontend/app_flowy/lib/plugins/board/presentation/board_page.dart index 26c44e52bf..3d109309d7 100644 --- a/frontend/app_flowy/lib/plugins/board/presentation/board_page.dart +++ b/frontend/app_flowy/lib/plugins/board/presentation/board_page.dart @@ -84,7 +84,6 @@ class BoardContent extends StatelessWidget { Widget _buildHeader( BuildContext context, AFBoardColumnHeaderData headerData) { return AppFlowyColumnHeader( - // icon: const Icon(Icons.lightbulb_circle), title: Flexible( fit: FlexFit.tight, child: FlowyText.medium( @@ -95,14 +94,14 @@ class BoardContent extends StatelessWidget { ), ), // addIcon: const Icon(Icons.add, size: 20), - moreIcon: SizedBox( - width: 20, - height: 20, - child: svgWidget( - 'grid/details', - color: context.read().iconColor, - ), - ), + // moreIcon: SizedBox( + // width: 20, + // height: 20, + // child: svgWidget( + // 'grid/details', + // color: context.read().iconColor, + // ), + // ), height: 50, margin: config.headerPadding, ); diff --git a/frontend/app_flowy/lib/plugins/board/presentation/card/board_checkbox_cell.dart b/frontend/app_flowy/lib/plugins/board/presentation/card/board_checkbox_cell.dart index 25aacb5678..522a23fe78 100644 --- a/frontend/app_flowy/lib/plugins/board/presentation/card/board_checkbox_cell.dart +++ b/frontend/app_flowy/lib/plugins/board/presentation/card/board_checkbox_cell.dart @@ -5,8 +5,6 @@ import 'package:flowy_infra_ui/style_widget/icon_button.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'define.dart'; - class BoardCheckboxCell extends StatefulWidget { final GridCellControllerBuilder cellControllerBuilder; @@ -41,9 +39,7 @@ class _BoardCheckboxCellState extends State { ? svgWidget('editor/editor_check') : svgWidget('editor/editor_uncheck'); return Padding( - padding: EdgeInsets.symmetric( - vertical: BoardSizes.cardCellVPading, - ), + padding: EdgeInsets.zero, child: Align( alignment: Alignment.centerLeft, child: FlowyIconButton( diff --git a/frontend/app_flowy/lib/plugins/board/presentation/card/board_date_cell.dart b/frontend/app_flowy/lib/plugins/board/presentation/card/board_date_cell.dart index 7c7386696d..8896a32732 100644 --- a/frontend/app_flowy/lib/plugins/board/presentation/card/board_date_cell.dart +++ b/frontend/app_flowy/lib/plugins/board/presentation/card/board_date_cell.dart @@ -45,7 +45,7 @@ class _BoardDateCellState extends State { alignment: Alignment.centerLeft, child: Padding( padding: EdgeInsets.symmetric( - vertical: BoardSizes.cardCellVPading, + vertical: BoardSizes.cardCellVPadding, ), child: FlowyText.regular( state.dateStr, diff --git a/frontend/app_flowy/lib/plugins/board/presentation/card/board_number_cell.dart b/frontend/app_flowy/lib/plugins/board/presentation/card/board_number_cell.dart index 965c06e643..33fb4a9b4b 100644 --- a/frontend/app_flowy/lib/plugins/board/presentation/card/board_number_cell.dart +++ b/frontend/app_flowy/lib/plugins/board/presentation/card/board_number_cell.dart @@ -42,7 +42,7 @@ class _BoardNumberCellState extends State { } else { return Padding( padding: - EdgeInsets.symmetric(vertical: BoardSizes.cardCellVPading), + EdgeInsets.symmetric(vertical: BoardSizes.cardCellVPadding), child: Align( alignment: Alignment.centerLeft, child: FlowyText.medium( diff --git a/frontend/app_flowy/lib/plugins/board/presentation/card/board_select_option_cell.dart b/frontend/app_flowy/lib/plugins/board/presentation/card/board_select_option_cell.dart index 9865875e44..6cba08c636 100644 --- a/frontend/app_flowy/lib/plugins/board/presentation/card/board_select_option_cell.dart +++ b/frontend/app_flowy/lib/plugins/board/presentation/card/board_select_option_cell.dart @@ -45,7 +45,8 @@ class _BoardSelectOptionCellState extends State { ) .toList(); return Padding( - padding: EdgeInsets.symmetric(vertical: BoardSizes.cardCellVPading), + padding: + EdgeInsets.symmetric(vertical: BoardSizes.cardCellVPadding), child: Align( alignment: Alignment.centerLeft, child: AbsorbPointer( diff --git a/frontend/app_flowy/lib/plugins/board/presentation/card/board_text_cell.dart b/frontend/app_flowy/lib/plugins/board/presentation/card/board_text_cell.dart index 89b193edc5..6f6e35429a 100644 --- a/frontend/app_flowy/lib/plugins/board/presentation/card/board_text_cell.dart +++ b/frontend/app_flowy/lib/plugins/board/presentation/card/board_text_cell.dart @@ -41,7 +41,7 @@ class _BoardTextCellState extends State { alignment: Alignment.centerLeft, child: Padding( padding: - EdgeInsets.symmetric(vertical: BoardSizes.cardCellVPading), + EdgeInsets.symmetric(vertical: BoardSizes.cardCellVPadding), child: FlowyText.medium( state.content, fontSize: 14, diff --git a/frontend/app_flowy/lib/plugins/board/presentation/card/board_url_cell.dart b/frontend/app_flowy/lib/plugins/board/presentation/card/board_url_cell.dart index 5940e71788..f687e7efeb 100644 --- a/frontend/app_flowy/lib/plugins/board/presentation/card/board_url_cell.dart +++ b/frontend/app_flowy/lib/plugins/board/presentation/card/board_url_cell.dart @@ -42,7 +42,7 @@ class _BoardUrlCellState extends State { } else { return Padding( padding: - EdgeInsets.symmetric(vertical: BoardSizes.cardCellVPading), + EdgeInsets.symmetric(vertical: BoardSizes.cardCellVPadding), child: Align( alignment: Alignment.centerLeft, child: RichText( diff --git a/frontend/app_flowy/lib/plugins/board/presentation/card/card_container.dart b/frontend/app_flowy/lib/plugins/board/presentation/card/card_container.dart index 4b8c0548d5..0e0a7287ae 100644 --- a/frontend/app_flowy/lib/plugins/board/presentation/card/card_container.dart +++ b/frontend/app_flowy/lib/plugins/board/presentation/card/card_container.dart @@ -74,6 +74,7 @@ class CardAccessoryContainer extends StatelessWidget { width: 26, height: 26, padding: const EdgeInsets.all(3), + decoration: _makeBoxDecoration(context), child: accessory, ), ); @@ -88,6 +89,23 @@ class CardAccessoryContainer extends StatelessWidget { } } +BoxDecoration _makeBoxDecoration(BuildContext context) { + final theme = context.read(); + final borderSide = BorderSide(color: theme.shader6, width: 1.0); + return BoxDecoration( + color: theme.surface, + border: Border.fromBorderSide(borderSide), + boxShadow: [ + BoxShadow( + color: theme.shader6, + spreadRadius: 0, + blurRadius: 2, + offset: Offset.zero) + ], + borderRadius: const BorderRadius.all(Radius.circular(6)), + ); +} + class _CardEnterRegion extends StatelessWidget { final Widget child; final List accessories; diff --git a/frontend/app_flowy/lib/plugins/board/presentation/card/define.dart b/frontend/app_flowy/lib/plugins/board/presentation/card/define.dart index ced0fefb83..c2cff2ee0f 100644 --- a/frontend/app_flowy/lib/plugins/board/presentation/card/define.dart +++ b/frontend/app_flowy/lib/plugins/board/presentation/card/define.dart @@ -1,3 +1,3 @@ class BoardSizes { - static double get cardCellVPading => 4; + static double get cardCellVPadding => 4; } diff --git a/frontend/app_flowy/lib/plugins/grid/application/cell/cell_service/context_builder.dart b/frontend/app_flowy/lib/plugins/grid/application/cell/cell_service/context_builder.dart index 95c708e0e2..8ab486a48c 100644 --- a/frontend/app_flowy/lib/plugins/grid/application/cell/cell_service/context_builder.dart +++ b/frontend/app_flowy/lib/plugins/grid/application/cell/cell_service/context_builder.dart @@ -190,7 +190,10 @@ class IGridCellController extends Equatable { /// cell display: $12 _cellListener?.start(onCellChanged: (result) { result.fold( - (_) => _loadData(), + (_) { + _cellsCache.remove(fieldId); + _loadData(); + }, (err) => Log.error(err), ); }); diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/extension.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/extension.dart index 6b937a3c9b..f045984e66 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/extension.dart +++ b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/extension.dart @@ -91,12 +91,10 @@ class SelectOptionTag extends StatelessWidget { Widget build(BuildContext context) { return ChoiceChip( pressElevation: 1, - label: Flexible( - child: FlowyText.medium( - name, - fontSize: 12, - overflow: TextOverflow.clip, - ), + label: FlowyText.medium( + name, + fontSize: 12, + overflow: TextOverflow.clip, ), selectedColor: color, backgroundColor: color, diff --git a/frontend/rust-lib/flowy-grid/src/entities/group_entities/configuration.rs b/frontend/rust-lib/flowy-grid/src/entities/group_entities/configuration.rs index cb5503727b..19f5b27a9b 100644 --- a/frontend/rust-lib/flowy-grid/src/entities/group_entities/configuration.rs +++ b/frontend/rust-lib/flowy-grid/src/entities/group_entities/configuration.rs @@ -1,5 +1,5 @@ use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; -use flowy_grid_data_model::revision::{GroupRecordRevision, SelectOptionGroupConfigurationRevision}; +use flowy_grid_data_model::revision::{GroupRevision, SelectOptionGroupConfigurationRevision}; #[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] pub struct UrlGroupConfigurationPB { @@ -36,10 +36,10 @@ pub struct GroupRecordPB { visible: bool, } -impl std::convert::From for GroupRecordPB { - fn from(rev: GroupRecordRevision) -> Self { +impl std::convert::From for GroupRecordPB { + fn from(rev: GroupRevision) -> Self { Self { - group_id: rev.group_id, + group_id: rev.id, visible: rev.visible, } } diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index a9060aa87e..4b525c233f 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -269,7 +269,7 @@ pub(crate) async fn create_table_row_handler( data_result(row) } -// #[tracing::instrument(level = "debug", skip_all, err)] +#[tracing::instrument(level = "trace", skip_all, err)] pub(crate) async fn get_cell_handler( data: Data, manager: AppData>, diff --git a/frontend/rust-lib/flowy-grid/src/services/group/configuration.rs b/frontend/rust-lib/flowy-grid/src/services/group/configuration.rs index 5126c9b2fc..546afb8a32 100644 --- a/frontend/rust-lib/flowy-grid/src/services/group/configuration.rs +++ b/frontend/rust-lib/flowy-grid/src/services/group/configuration.rs @@ -2,10 +2,11 @@ use crate::entities::{GroupPB, GroupViewChangesetPB, InsertedGroupPB}; use crate::services::group::{default_group_configuration, Group}; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::revision::{ - FieldRevision, FieldTypeRevision, GroupConfigurationContentSerde, GroupConfigurationRevision, GroupRecordRevision, + FieldRevision, FieldTypeRevision, GroupConfigurationContentSerde, GroupConfigurationRevision, GroupRevision, }; use indexmap::IndexMap; use lib_infra::future::AFFuture; +use std::fmt::Formatter; use std::marker::PhantomData; use std::sync::Arc; @@ -25,6 +26,15 @@ pub trait GroupConfigurationWriter: Send + Sync + 'static { ) -> AFFuture>; } +impl std::fmt::Display for GenericGroupConfiguration { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + self.groups_map.iter().for_each(|(_, group)| { + let _ = f.write_fmt(format_args!("Group:{} has {} rows \n", group.id, group.rows.len())); + }); + Ok(()) + } +} + pub struct GenericGroupConfiguration { view_id: String, pub configuration: Arc, @@ -84,12 +94,31 @@ where let group_revs = groups .iter() - .map(|group| GroupRecordRevision::new(group.id.clone(), group.name.clone())) - .collect(); + .map(|group| GroupRevision::new(group.id.clone(), group.name.clone())) + .collect::>(); self.mut_configuration(move |configuration| { - configuration.groups = group_revs; - true + let mut is_changed = false; + for new_group_rev in group_revs { + match configuration + .groups + .iter() + .position(|group_rev| group_rev.id == new_group_rev.id) + { + None => { + configuration.groups.push(new_group_rev); + is_changed = true; + } + Some(pos) => { + let removed_group = configuration.groups.remove(pos); + if removed_group != new_group_rev { + is_changed = true; + } + configuration.groups.insert(pos, new_group_rev); + } + } + } + is_changed })?; groups.into_iter().for_each(|group| { @@ -139,8 +168,8 @@ where self.groups_map.swap_indices(from_index, to_index); self.mut_configuration(|configuration| { - let from_index = configuration.groups.iter().position(|group| group.group_id == from_id); - let to_index = configuration.groups.iter().position(|group| group.group_id == to_id); + let from_index = configuration.groups.iter().position(|group| group.id == from_id); + let to_index = configuration.groups.iter().position(|group| group.id == to_id); if let (Some(from), Some(to)) = (from_index, to_index) { configuration.groups.swap(from, to); } @@ -183,10 +212,10 @@ where fn mut_configuration_group( &mut self, group_id: &str, - mut_groups_fn: impl Fn(&mut GroupRecordRevision), + mut_groups_fn: impl Fn(&mut GroupRevision), ) -> FlowyResult<()> { self.mut_configuration(|configuration| { - match configuration.groups.iter_mut().find(|group| group.group_id == group_id) { + match configuration.groups.iter_mut().find(|group| group.id == group_id) { None => false, Some(group_rev) => { mut_groups_fn(group_rev); @@ -209,7 +238,7 @@ where } } -fn merge_groups(old_groups: &[GroupRecordRevision], groups: Vec) -> MergeGroupResult { +fn merge_groups(old_groups: &[GroupRevision], groups: Vec) -> MergeGroupResult { let mut merge_result = MergeGroupResult::new(); if old_groups.is_empty() { merge_result.groups = groups; @@ -224,7 +253,7 @@ fn merge_groups(old_groups: &[GroupRecordRevision], groups: Vec) -> Merge // The group is ordered in old groups. Add them before adding the new groups for group_rev in old_groups { - if let Some(group) = group_map.remove(&group_rev.group_id) { + if let Some(group) = group_map.remove(&group_rev.id) { if group.name == group_rev.name { merge_result.add_group(group); } else { diff --git a/frontend/rust-lib/flowy-grid/src/services/group/controller.rs b/frontend/rust-lib/flowy-grid/src/services/group/controller.rs index 1dae47c0db..fac034f6f5 100644 --- a/frontend/rust-lib/flowy-grid/src/services/group/controller.rs +++ b/frontend/rust-lib/flowy-grid/src/services/group/controller.rs @@ -124,7 +124,11 @@ where } fn groups(&self) -> Vec { - self.configuration.clone_groups() + let mut groups = self.configuration.clone_groups(); + if self.default_group.is_empty() == false { + groups.insert(0, self.default_group.clone()); + } + groups } fn get_group(&self, group_id: &str) -> Option<(usize, Group)> { @@ -132,25 +136,28 @@ where Some((group.0, group.1.clone())) } + #[tracing::instrument(level = "trace", skip_all, fields(row_count=%row_revs.len(), group_result))] fn fill_groups(&mut self, row_revs: &[Arc], field_rev: &FieldRevision) -> FlowyResult> { + // let mut ungrouped_rows = vec![]; for row_rev in row_revs { if let Some(cell_rev) = row_rev.cells.get(&self.field_id) { - let mut group_rows: Vec = vec![]; + let mut grouped_rows: Vec = vec![]; let cell_bytes = decode_any_cell_data(cell_rev.data.clone(), field_rev); let cell_data = cell_bytes.parser::

()?; for group in self.configuration.groups() { if self.can_group(&group.content, &cell_data) { - group_rows.push(GroupRow { + grouped_rows.push(GroupedRow { row: row_rev.into(), group_id: group.id.clone(), }); } } - if group_rows.is_empty() { + if grouped_rows.is_empty() { + // ungrouped_rows.push(RowPB::from(row_rev)); self.default_group.add_row(row_rev.into()); } else { - for group_row in group_rows { + for group_row in grouped_rows { if let Some(group) = self.configuration.get_mut_group(&group_row.group_id) { group.add_row(group_row.row); } @@ -161,13 +168,27 @@ where } } - let default_group = self.default_group.clone(); - let mut groups: Vec = self.configuration.clone_groups(); - if !default_group.number_of_row() == 0 { - groups.push(default_group); - } + // if !ungrouped_rows.is_empty() { + // let default_group_rev = GroupRevision::default_group(gen_grid_group_id(), format!("No {}", field_rev.name)); + // let default_group = Group::new( + // default_group_rev.id.clone(), + // field_rev.id.clone(), + // default_group_rev.name.clone(), + // "".to_owned(), + // ); + // } - Ok(groups) + tracing::Span::current().record( + "group_result", + &format!( + "{}, default_group has {} rows", + self.configuration, + self.default_group.rows.len() + ) + .as_str(), + ); + + Ok(self.groups()) } fn move_group(&mut self, from_group_id: &str, to_group_id: &str) -> FlowyResult<()> { @@ -222,7 +243,7 @@ where } } -struct GroupRow { +struct GroupedRow { row: RowPB, group_id: String, } diff --git a/frontend/rust-lib/flowy-grid/src/services/group/entities.rs b/frontend/rust-lib/flowy-grid/src/services/group/entities.rs index d8c4169eaf..f4d0ee1652 100644 --- a/frontend/rust-lib/flowy-grid/src/services/group/entities.rs +++ b/frontend/rust-lib/flowy-grid/src/services/group/entities.rs @@ -59,4 +59,8 @@ impl Group { pub fn number_of_row(&self) -> usize { self.rows.len() } + + pub fn is_empty(&self) -> bool { + self.rows.is_empty() + } } diff --git a/shared-lib/flowy-grid-data-model/src/revision/group_rev.rs b/shared-lib/flowy-grid-data-model/src/revision/group_rev.rs index ce378c0ffb..04b571fd76 100644 --- a/shared-lib/flowy-grid-data-model/src/revision/group_rev.rs +++ b/shared-lib/flowy-grid-data-model/src/revision/group_rev.rs @@ -14,7 +14,7 @@ pub struct GroupConfigurationRevision { pub id: String, pub field_id: String, pub field_type_rev: FieldTypeRevision, - pub groups: Vec, + pub groups: Vec, pub content: String, } @@ -106,24 +106,38 @@ impl GroupConfigurationContentSerde for SelectOptionGroupConfigurationRevision { } } -#[derive(Clone, Debug, Default, Serialize, Deserialize)] -pub struct GroupRecordRevision { - pub group_id: String, +#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq)] +pub struct GroupRevision { + pub id: String, #[serde(default)] pub name: String, - #[serde(default = "DEFAULT_GROUP_RECORD_VISIBILITY")] + #[serde(skip, default = "IS_DEFAULT_GROUP")] + pub is_default: bool, + + #[serde(default = "GROUP_REV_VISIBILITY")] pub visible: bool, } -const DEFAULT_GROUP_RECORD_VISIBILITY: fn() -> bool = || true; +const GROUP_REV_VISIBILITY: fn() -> bool = || true; +const IS_DEFAULT_GROUP: fn() -> bool = || false; -impl GroupRecordRevision { - pub fn new(group_id: String, group_name: String) -> Self { +impl GroupRevision { + pub fn new(id: String, group_name: String) -> Self { Self { - group_id, + id, name: group_name, + is_default: false, + visible: true, + } + } + + pub fn default_group(id: String, group_name: String) -> Self { + Self { + id, + name: group_name, + is_default: true, visible: true, } }