Selaa lähdekoodia

chore: support group by checkbox field

appflowy 2 vuotta sitten
vanhempi
commit
6384edf0e6

+ 0 - 1
frontend/rust-lib/flowy-grid/src/services/cell/cell_operation.rs

@@ -182,7 +182,6 @@ pub fn delete_select_option_cell(option_id: String, field_rev: &FieldRevision) -
     CellRevision::new(data)
 }
 
-/// If the cell data is not String type, it should impl this trait.
 /// Deserialize the String into cell specific data type.  
 pub trait FromCellString {
     fn from_cell_str(s: &str) -> FlowyResult<Self>

+ 5 - 2
frontend/rust-lib/flowy-grid/src/services/group/action.rs

@@ -1,13 +1,16 @@
 use crate::entities::GroupChangesetPB;
 
 use crate::services::group::controller::MoveGroupRowContext;
-use flowy_grid_data_model::revision::RowRevision;
+use flowy_grid_data_model::revision::{CellRevision, RowRevision};
 
 pub trait GroupAction: Send + Sync {
     type CellDataType;
+    fn default_cell_rev(&self) -> Option<CellRevision> {
+        None
+    }
+
     fn can_group(&self, content: &str, cell_data: &Self::CellDataType) -> bool;
     fn add_row_if_match(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType) -> Vec<GroupChangesetPB>;
     fn remove_row_if_match(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType) -> Vec<GroupChangesetPB>;
-
     fn move_row(&mut self, cell_data: &Self::CellDataType, context: MoveGroupRowContext) -> Vec<GroupChangesetPB>;
 }

+ 7 - 3
frontend/rust-lib/flowy-grid/src/services/group/controller.rs

@@ -7,7 +7,6 @@ use flowy_error::FlowyResult;
 use flowy_grid_data_model::revision::{
     FieldRevision, GroupConfigurationContentSerde, GroupRevision, RowChangeset, RowRevision, TypeOptionDataDeserializer,
 };
-
 use std::marker::PhantomData;
 use std::sync::Arc;
 
@@ -193,9 +192,14 @@ where
     #[tracing::instrument(level = "trace", skip_all, fields(row_count=%row_revs.len(), group_result))]
     fn fill_groups(&mut self, row_revs: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<()> {
         for row_rev in row_revs {
-            if let Some(cell_rev) = row_rev.cells.get(&self.field_id) {
+            let cell_rev = match row_rev.cells.get(&self.field_id) {
+                None => self.default_cell_rev(),
+                Some(cell_rev) => Some(cell_rev.clone()),
+            };
+
+            if let Some(cell_rev) = cell_rev {
                 let mut grouped_rows: Vec<GroupedRow> = vec![];
-                let cell_bytes = decode_any_cell_data(cell_rev.data.clone(), field_rev);
+                let cell_bytes = decode_any_cell_data(cell_rev.data, field_rev);
                 let cell_data = cell_bytes.parser::<P>()?;
                 for group in self.group_ctx.concrete_groups() {
                     if self.can_group(&group.filter_content, &cell_data) {

+ 73 - 21
frontend/rust-lib/flowy-grid/src/services/group/controller_impls/checkbox_controller.rs

@@ -1,4 +1,4 @@
-use crate::entities::GroupChangesetPB;
+use crate::entities::{GroupChangesetPB, InsertedRowPB, RowPB};
 use crate::services::field::{CheckboxCellData, CheckboxCellDataParser, CheckboxTypeOptionPB, CHECK, UNCHECK};
 use crate::services::group::action::GroupAction;
 use crate::services::group::configuration::GroupContext;
@@ -6,8 +6,11 @@ use crate::services::group::controller::{
     GenericGroupController, GroupController, GroupGenerator, MoveGroupRowContext,
 };
 
-use crate::services::group::GeneratedGroup;
-use flowy_grid_data_model::revision::{CheckboxGroupConfigurationRevision, FieldRevision, GroupRevision, RowRevision};
+use crate::services::cell::insert_checkbox_cell;
+use crate::services::group::{move_group_row, GeneratedGroup};
+use flowy_grid_data_model::revision::{
+    CellRevision, CheckboxGroupConfigurationRevision, FieldRevision, GroupRevision, RowRevision,
+};
 
 pub type CheckboxGroupController = GenericGroupController<
     CheckboxGroupConfigurationRevision,
@@ -20,30 +23,79 @@ pub type CheckboxGroupContext = GroupContext<CheckboxGroupConfigurationRevision>
 
 impl GroupAction for CheckboxGroupController {
     type CellDataType = CheckboxCellData;
-    fn can_group(&self, _content: &str, _cell_data: &Self::CellDataType) -> bool {
-        false
+    fn default_cell_rev(&self) -> Option<CellRevision> {
+        Some(CellRevision::new(UNCHECK.to_string()))
     }
 
-    fn add_row_if_match(&mut self, _row_rev: &RowRevision, _cell_data: &Self::CellDataType) -> Vec<GroupChangesetPB> {
-        todo!()
+    fn can_group(&self, content: &str, cell_data: &Self::CellDataType) -> bool {
+        return if cell_data.is_check() {
+            content == CHECK
+        } else {
+            content == UNCHECK
+        };
     }
 
-    fn remove_row_if_match(
-        &mut self,
-        _row_rev: &RowRevision,
-        _cell_data: &Self::CellDataType,
-    ) -> Vec<GroupChangesetPB> {
-        todo!()
+    fn add_row_if_match(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType) -> Vec<GroupChangesetPB> {
+        let mut changesets = vec![];
+        self.group_ctx.iter_mut_groups(|group| {
+            let mut changeset = GroupChangesetPB::new(group.id.clone());
+            let is_contained = group.contains_row(&row_rev.id);
+            if group.id == CHECK && cell_data.is_check() {
+                if !is_contained {
+                    let row_pb = RowPB::from(row_rev);
+                    changeset.inserted_rows.push(InsertedRowPB::new(row_pb.clone()));
+                    group.add_row(row_pb);
+                }
+            } else {
+                if is_contained {
+                    changeset.deleted_rows.push(row_rev.id.clone());
+                    group.remove_row(&row_rev.id);
+                }
+            }
+            if !changeset.is_empty() {
+                changesets.push(changeset);
+            }
+        });
+        changesets
+    }
+
+    fn remove_row_if_match(&mut self, row_rev: &RowRevision, _cell_data: &Self::CellDataType) -> Vec<GroupChangesetPB> {
+        let mut changesets = vec![];
+        self.group_ctx.iter_mut_groups(|group| {
+            let mut changeset = GroupChangesetPB::new(group.id.clone());
+            if group.contains_row(&row_rev.id) {
+                changeset.deleted_rows.push(row_rev.id.clone());
+                group.remove_row(&row_rev.id);
+            }
+
+            if !changeset.is_empty() {
+                changesets.push(changeset);
+            }
+        });
+        changesets
     }
 
-    fn move_row(&mut self, _cell_data: &Self::CellDataType, _context: MoveGroupRowContext) -> Vec<GroupChangesetPB> {
-        todo!()
+    fn move_row(&mut self, _cell_data: &Self::CellDataType, mut context: MoveGroupRowContext) -> Vec<GroupChangesetPB> {
+        let mut group_changeset = vec![];
+        self.group_ctx.iter_mut_groups(|group| {
+            if let Some(changeset) = move_group_row(group, &mut context) {
+                group_changeset.push(changeset);
+            }
+        });
+        group_changeset
     }
 }
 
 impl GroupController for CheckboxGroupController {
-    fn will_create_row(&mut self, _row_rev: &mut RowRevision, _field_rev: &FieldRevision, _group_id: &str) {
-        todo!()
+    fn will_create_row(&mut self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str) {
+        match self.group_ctx.get_group(group_id) {
+            None => tracing::warn!("Can not find the group: {}", group_id),
+            Some((_, group)) => {
+                let is_check = group.id == CHECK;
+                let cell_rev = insert_checkbox_cell(is_check, field_rev);
+                row_rev.cells.insert(field_rev.id.clone(), cell_rev);
+            }
+        }
     }
 }
 
@@ -58,13 +110,13 @@ impl GroupGenerator for CheckboxGroupGenerator {
         _type_option: &Option<Self::TypeOptionType>,
     ) -> Vec<GeneratedGroup> {
         let check_group = GeneratedGroup {
-            group_rev: GroupRevision::new("true".to_string(), CHECK.to_string()),
-            filter_content: "".to_string(),
+            group_rev: GroupRevision::new(CHECK.to_string(), "".to_string()),
+            filter_content: CHECK.to_string(),
         };
 
         let uncheck_group = GeneratedGroup {
-            group_rev: GroupRevision::new("false".to_string(), UNCHECK.to_string()),
-            filter_content: "".to_string(),
+            group_rev: GroupRevision::new(UNCHECK.to_string(), "".to_string()),
+            filter_content: UNCHECK.to_string(),
         };
         vec![check_group, uncheck_group]
     }

+ 2 - 2
frontend/rust-lib/flowy-grid/src/services/group/controller_impls/select_option_controller/multi_select_controller.rs

@@ -46,10 +46,10 @@ impl GroupAction for MultiSelectGroupController {
         changesets
     }
 
-    fn move_row(&mut self, cell_data: &Self::CellDataType, mut context: MoveGroupRowContext) -> Vec<GroupChangesetPB> {
+    fn move_row(&mut self, _cell_data: &Self::CellDataType, mut context: MoveGroupRowContext) -> Vec<GroupChangesetPB> {
         let mut group_changeset = vec![];
         self.group_ctx.iter_mut_groups(|group| {
-            if let Some(changeset) = move_select_option_row(group, cell_data, &mut context) {
+            if let Some(changeset) = move_group_row(group, &mut context) {
                 group_changeset.push(changeset);
             }
         });

+ 2 - 2
frontend/rust-lib/flowy-grid/src/services/group/controller_impls/select_option_controller/single_select_controller.rs

@@ -46,10 +46,10 @@ impl GroupAction for SingleSelectGroupController {
         changesets
     }
 
-    fn move_row(&mut self, cell_data: &Self::CellDataType, mut context: MoveGroupRowContext) -> Vec<GroupChangesetPB> {
+    fn move_row(&mut self, _cell_data: &Self::CellDataType, mut context: MoveGroupRowContext) -> Vec<GroupChangesetPB> {
         let mut group_changeset = vec![];
         self.group_ctx.iter_mut_groups(|group| {
-            if let Some(changeset) = move_select_option_row(group, cell_data, &mut context) {
+            if let Some(changeset) = move_group_row(group, &mut context) {
                 group_changeset.push(changeset);
             }
         });

+ 1 - 5
frontend/rust-lib/flowy-grid/src/services/group/controller_impls/select_option_controller/util.rs

@@ -62,11 +62,7 @@ pub fn remove_select_option_row(
     }
 }
 
-pub fn move_select_option_row(
-    group: &mut Group,
-    _cell_data: &SelectOptionCellDataPB,
-    context: &mut MoveGroupRowContext,
-) -> Option<GroupChangesetPB> {
+pub fn move_group_row(group: &mut Group, context: &mut MoveGroupRowContext) -> Option<GroupChangesetPB> {
     let mut changeset = GroupChangesetPB::new(group.id.clone());
     let MoveGroupRowContext {
         row_rev,