diff --git a/frontend/rust-lib/flowy-grid/src/entities/filter_entities/util.rs b/frontend/rust-lib/flowy-grid/src/entities/filter_entities/util.rs index 32ac38f986..4a67d7ff52 100644 --- a/frontend/rust-lib/flowy-grid/src/entities/filter_entities/util.rs +++ b/frontend/rust-lib/flowy-grid/src/entities/filter_entities/util.rs @@ -22,16 +22,16 @@ pub struct RepeatedGridFilter { pub items: Vec, } -impl std::convert::From<&Arc> for GridFilter { - fn from(rev: &Arc) -> Self { +impl std::convert::From<&GridFilterRevision> for GridFilter { + fn from(rev: &GridFilterRevision) -> Self { Self { id: rev.id.clone() } } } -impl std::convert::From<&Vec>> for RepeatedGridFilter { - fn from(revs: &Vec>) -> Self { +impl std::convert::From>> for RepeatedGridFilter { + fn from(revs: Vec>) -> Self { RepeatedGridFilter { - items: revs.iter().map(|rev| rev.into()).collect(), + items: revs.into_iter().map(|rev| rev.as_ref().into()).collect(), } } } diff --git a/frontend/rust-lib/flowy-grid/src/entities/group_entities.rs b/frontend/rust-lib/flowy-grid/src/entities/group_entities.rs index dc090e6ea1..53d20bbc57 100644 --- a/frontend/rust-lib/flowy-grid/src/entities/group_entities.rs +++ b/frontend/rust-lib/flowy-grid/src/entities/group_entities.rs @@ -4,6 +4,7 @@ use flowy_grid_data_model::parser::NotEmptyStr; use flowy_grid_data_model::revision::GridGroupRevision; use flowy_sync::entities::grid::CreateGridGroupParams; use std::convert::TryInto; +use std::sync::Arc; #[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] pub struct GridGroup { @@ -39,10 +40,10 @@ impl std::convert::From> for RepeatedGridGroup { } } -impl std::convert::From<&Vec> for RepeatedGridGroup { - fn from(revs: &Vec) -> Self { +impl std::convert::From>> for RepeatedGridGroup { + fn from(revs: Vec>) -> Self { RepeatedGridGroup { - items: revs.iter().map(|rev| rev.into()).collect(), + items: revs.iter().map(|rev| rev.as_ref().into()).collect(), } } } diff --git a/frontend/rust-lib/flowy-grid/src/entities/setting_entities.rs b/frontend/rust-lib/flowy-grid/src/entities/setting_entities.rs index ce2d623b0c..4440b88bb7 100644 --- a/frontend/rust-lib/flowy-grid/src/entities/setting_entities.rs +++ b/frontend/rust-lib/flowy-grid/src/entities/setting_entities.rs @@ -1,57 +1,53 @@ use crate::entities::{ - CreateGridFilterPayload, CreateGridGroupPayload, CreateGridSortPayload, DeleteFilterPayload, RepeatedGridFilter, - RepeatedGridGroup, RepeatedGridSort, + CreateGridFilterPayload, CreateGridGroupPayload, CreateGridSortPayload, DeleteFilterPayload, GridFilter, GridGroup, + GridSort, RepeatedGridFilter, RepeatedGridGroup, RepeatedGridSort, }; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::ErrorCode; use flowy_grid_data_model::parser::NotEmptyStr; -use flowy_grid_data_model::revision::GridLayoutRevision; +use flowy_grid_data_model::revision::{GridLayoutRevision, GridSettingRevision}; use flowy_sync::entities::grid::GridSettingChangesetParams; use std::collections::HashMap; use std::convert::TryInto; +use strum::IntoEnumIterator; +use strum_macros::EnumIter; #[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] pub struct GridSetting { #[pb(index = 1)] - pub filters_by_layout_ty: HashMap, + pub layouts: Vec, #[pb(index = 2)] - pub groups_by_layout_ty: HashMap, + pub current_layout_type: GridLayoutType, #[pb(index = 3)] - pub sorts_by_layout_ty: HashMap, + pub filters_by_field_id: HashMap, + + #[pb(index = 4)] + pub groups_by_field_id: HashMap, + + #[pb(index = 5)] + pub sorts_by_field_id: HashMap, } -// -// impl std::convert::From<&GridSettingRevision> for GridSetting { -// fn from(rev: &GridSettingRevision) -> Self { -// let filters_by_layout_ty: HashMap = rev -// .filters -// .iter() -// .map(|(layout_rev, filter_revs)| (layout_rev.to_string(), filter_revs.into())) -// .collect(); -// -// let groups_by_layout_ty: HashMap = rev -// .groups -// .iter() -// .map(|(layout_rev, group_revs)| (layout_rev.to_string(), group_revs.into())) -// .collect(); -// -// let sorts_by_layout_ty: HashMap = rev -// .sorts -// .iter() -// .map(|(layout_rev, sort_revs)| (layout_rev.to_string(), sort_revs.into())) -// .collect(); -// -// GridSetting { -// filters_by_layout_ty, -// groups_by_layout_ty, -// sorts_by_layout_ty, -// } -// } -// } -// -#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum)] +#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] +pub struct GridLayout { + #[pb(index = 1)] + ty: GridLayoutType, +} + +impl GridLayout { + pub fn all() -> Vec { + let mut layouts = vec![]; + for layout_ty in GridLayoutType::iter() { + layouts.push(GridLayout { ty: layout_ty }) + } + + layouts + } +} + +#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum, EnumIter)] #[repr(u8)] pub enum GridLayoutType { Table = 0, diff --git a/frontend/rust-lib/flowy-grid/src/entities/sort_entities.rs b/frontend/rust-lib/flowy-grid/src/entities/sort_entities.rs index 1f03808fa8..3a560460fe 100644 --- a/frontend/rust-lib/flowy-grid/src/entities/sort_entities.rs +++ b/frontend/rust-lib/flowy-grid/src/entities/sort_entities.rs @@ -4,6 +4,7 @@ use flowy_grid_data_model::parser::NotEmptyStr; use flowy_grid_data_model::revision::GridSortRevision; use flowy_sync::entities::grid::CreateGridSortParams; use std::convert::TryInto; +use std::sync::Arc; #[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] pub struct GridSort { @@ -30,10 +31,10 @@ pub struct RepeatedGridSort { pub items: Vec, } -impl std::convert::From<&Vec> for RepeatedGridSort { - fn from(revs: &Vec) -> Self { +impl std::convert::From>> for RepeatedGridSort { + fn from(revs: Vec>) -> Self { RepeatedGridSort { - items: revs.iter().map(|rev| rev.into()).collect(), + items: revs.into_iter().map(|rev| rev.as_ref().into()).collect(), } } } diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index 152c9a8d2a..1d63b6dd69 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -11,6 +11,7 @@ use crate::services::row::{ make_grid_blocks, make_row_from_row_rev, make_row_rev_from_context, make_rows_from_row_revs, CreateRowRevisionBuilder, CreateRowRevisionPayload, GridBlockSnapshot, }; +use crate::services::setting::make_grid_setting; use bytes::Bytes; use flowy_error::{ErrorCode, FlowyError, FlowyResult}; use flowy_grid_data_model::revision::*; @@ -453,17 +454,21 @@ impl GridRevisionEditor { } pub async fn get_grid_setting(&self) -> FlowyResult { - // let read_guard = self.grid_pad.read().await; - // let grid_setting_rev = read_guard.get_grid_setting_rev(); - // Ok(grid_setting_rev.into()) - todo!() + let read_guard = self.grid_pad.read().await; + let grid_setting_rev = read_guard.get_grid_setting_rev(); + let field_revs = read_guard.get_field_revs(None)?; + let grid_setting = make_grid_setting(grid_setting_rev, &field_revs); + Ok(grid_setting) } pub async fn get_grid_filter(&self, layout_type: &GridLayoutType) -> FlowyResult> { let read_guard = self.grid_pad.read().await; let layout_rev = layout_type.clone().into(); match read_guard.get_filters(Some(&layout_rev), None) { - Some(filter_revs) => Ok(filter_revs.iter().map(GridFilter::from).collect::>()), + Some(filter_revs) => Ok(filter_revs + .iter() + .map(|filter_rev| filter_rev.as_ref().into()) + .collect::>()), None => Ok(vec![]), } } diff --git a/frontend/rust-lib/flowy-grid/src/services/setting/setting_builder.rs b/frontend/rust-lib/flowy-grid/src/services/setting/setting_builder.rs index 866b0a51e6..744d319976 100644 --- a/frontend/rust-lib/flowy-grid/src/services/setting/setting_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/setting/setting_builder.rs @@ -1,5 +1,10 @@ -use crate::entities::GridLayoutType; +use crate::entities::{ + GridLayout, GridLayoutType, GridSetting, RepeatedGridFilter, RepeatedGridGroup, RepeatedGridSort, +}; +use flowy_grid_data_model::revision::{FieldRevision, GridSettingRevision}; use flowy_sync::entities::grid::{CreateGridFilterParams, DeleteFilterParams, GridSettingChangesetParams}; +use std::collections::HashMap; +use std::sync::Arc; pub struct GridSettingChangesetBuilder { params: GridSettingChangesetParams, @@ -34,3 +39,48 @@ impl GridSettingChangesetBuilder { self.params } } + +pub fn make_grid_setting(grid_setting_rev: &GridSettingRevision, field_revs: &[Arc]) -> GridSetting { + let current_layout_type: GridLayoutType = grid_setting_rev.layout.clone().into(); + let filters_by_field_id = grid_setting_rev + .get_all_filter(&field_revs) + .and_then(|filters_by_field_id| { + Some( + filters_by_field_id + .into_iter() + .map(|(k, v)| (k, v.into())) + .collect::>(), + ) + }) + .unwrap_or(HashMap::default()); + let groups_by_field_id = grid_setting_rev + .get_all_group() + .and_then(|groups_by_field_id| { + Some( + groups_by_field_id + .into_iter() + .map(|(k, v)| (k, v.into())) + .collect::>(), + ) + }) + .unwrap_or(HashMap::default()); + let sorts_by_field_id = grid_setting_rev + .get_all_sort() + .and_then(|sorts_by_field_id| { + Some( + sorts_by_field_id + .into_iter() + .map(|(k, v)| (k, v.into())) + .collect::>(), + ) + }) + .unwrap_or(HashMap::default()); + + GridSetting { + layouts: GridLayout::all(), + current_layout_type, + filters_by_field_id, + groups_by_field_id, + sorts_by_field_id, + } +} diff --git a/shared-lib/flowy-grid-data-model/src/revision/grid_setting_rev.rs b/shared-lib/flowy-grid-data-model/src/revision/grid_setting_rev.rs index 7bd18024ca..5cd6fc287e 100644 --- a/shared-lib/flowy-grid-data-model/src/revision/grid_setting_rev.rs +++ b/shared-lib/flowy-grid-data-model/src/revision/grid_setting_rev.rs @@ -1,8 +1,9 @@ -use crate::revision::FieldTypeRevision; +use crate::revision::{FieldRevision, FieldTypeRevision}; use indexmap::IndexMap; use nanoid::nanoid; use serde::{Deserialize, Serialize}; use serde_repr::*; +use std::collections::HashMap; use std::sync::Arc; pub fn gen_grid_filter_id() -> String { @@ -17,20 +18,33 @@ pub fn gen_grid_sort_id() -> String { nanoid!(6) } +/// Each layout contains multiple key/value. +/// Key: field_id +/// Value: this value also contains key/value. +/// Key: FieldType, +/// Value: the corresponding filter. +/// +/// This overall struct is described below: +/// GridSettingRevision +/// layout: +/// field_id: +/// FieldType: GridFilterRevision +/// FieldType: GridFilterRevision +/// field_id: +/// FieldType: GridFilterRevision +/// FieldType: GridFilterRevision +/// layout: +/// field_id: +/// FieldType: GridFilterRevision +/// FieldType: GridFilterRevision +/// +/// Group and sorts will be the same structure as filters. #[derive(Debug, Clone, Serialize, Deserialize, Default, Eq, PartialEq)] pub struct GridSettingRevision { pub layout: GridLayoutRevision, - // layout: - // field_id: - // FieldType: GridFilterRevision - // FieldType: GridFilterRevision - // layout: - // field_id: - // FieldType: GridFilterRevision - // field_id: - // FieldType: GridFilterRevision + #[serde(with = "indexmap::serde_seq")] - pub filters: IndexMap>, + filters: IndexMap>, #[serde(skip, with = "indexmap::serde_seq")] pub groups: IndexMap>, @@ -39,7 +53,43 @@ pub struct GridSettingRevision { pub sorts: IndexMap>, } +pub type FiltersByFieldId = HashMap>>; +pub type GroupsByFieldId = HashMap>>; +pub type SortsByFieldId = HashMap>>; impl GridSettingRevision { + pub fn get_all_group(&self) -> Option { + None + } + + pub fn get_all_sort(&self) -> Option { + None + } + + /// Return the Filters of the current layout + pub fn get_all_filter(&self, field_revs: &[Arc]) -> Option { + let layout = &self.layout; + // Acquire the read lock of the filters. + let filter_rev_map_by_field_id = self.filters.get(layout)?; + // Get the filters according to the FieldType, so we need iterate the field_revs. + let filters_by_field_id = field_revs + .iter() + .flat_map(|field_rev| { + let field_type = &field_rev.field_type_rev; + let field_id = &field_rev.id; + + let filter_rev_map: &GridFilterRevisionMap = filter_rev_map_by_field_id.get(field_id)?; + let filters: Vec> = filter_rev_map.get(field_type)?.clone(); + Some((field_rev.id.clone(), filters)) + }) + .collect::(); + Some(filters_by_field_id) + } + + fn get_filter_rev_map(&self, layout: &GridLayoutRevision, field_id: &str) -> Option<&GridFilterRevisionMap> { + let filter_rev_map_by_field_id = self.filters.get(layout)?; + filter_rev_map_by_field_id.get(field_id) + } + pub fn get_mut_filters( &mut self, layout: &GridLayoutRevision,