mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: enable group condition (#5248)
* feat: enable group condition * style: added i18n for date field group conditions * fix: flutter analyze * fix: test use i18n * fix: more localization --------- Co-authored-by: Mathias Mogensen <42929161+Xazin@users.noreply.github.com> Co-authored-by: Mathias Mogensen <mathias@appflowy.io>
This commit is contained in:
committed by
GitHub
parent
f1a4deb459
commit
4f4be7eac7
@ -1,5 +1,10 @@
|
||||
use crate::services::group::Group;
|
||||
use crate::{
|
||||
entities::FieldType,
|
||||
services::group::{DateCondition, DateGroupConfiguration, Group},
|
||||
};
|
||||
use bytes::Bytes;
|
||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||
use flowy_error::FlowyResult;
|
||||
|
||||
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
|
||||
pub struct URLGroupConfigurationPB {
|
||||
@ -46,16 +51,33 @@ pub struct NumberGroupConfigurationPB {
|
||||
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
|
||||
pub struct DateGroupConfigurationPB {
|
||||
#[pb(index = 1)]
|
||||
pub condition: DateCondition,
|
||||
pub condition: DateConditionPB,
|
||||
|
||||
#[pb(index = 2)]
|
||||
hide_empty: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum)]
|
||||
impl From<DateGroupConfigurationPB> for DateGroupConfiguration {
|
||||
fn from(data: DateGroupConfigurationPB) -> Self {
|
||||
Self {
|
||||
condition: data.condition.into(),
|
||||
hide_empty: data.hide_empty,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<DateGroupConfiguration> for DateGroupConfigurationPB {
|
||||
fn from(data: DateGroupConfiguration) -> Self {
|
||||
Self {
|
||||
condition: data.condition.into(),
|
||||
hide_empty: data.hide_empty,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum, Default)]
|
||||
#[repr(u8)]
|
||||
#[derive(Default)]
|
||||
pub enum DateCondition {
|
||||
pub enum DateConditionPB {
|
||||
#[default]
|
||||
Relative = 0,
|
||||
Day = 1,
|
||||
@ -64,8 +86,56 @@ pub enum DateCondition {
|
||||
Year = 4,
|
||||
}
|
||||
|
||||
impl From<DateConditionPB> for DateCondition {
|
||||
fn from(data: DateConditionPB) -> Self {
|
||||
match data {
|
||||
DateConditionPB::Relative => DateCondition::Relative,
|
||||
DateConditionPB::Day => DateCondition::Day,
|
||||
DateConditionPB::Week => DateCondition::Week,
|
||||
DateConditionPB::Month => DateCondition::Month,
|
||||
DateConditionPB::Year => DateCondition::Year,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<DateCondition> for DateConditionPB {
|
||||
fn from(data: DateCondition) -> Self {
|
||||
match data {
|
||||
DateCondition::Relative => DateConditionPB::Relative,
|
||||
DateCondition::Day => DateConditionPB::Day,
|
||||
DateCondition::Week => DateConditionPB::Week,
|
||||
DateCondition::Month => DateConditionPB::Month,
|
||||
DateCondition::Year => DateConditionPB::Year,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
|
||||
pub struct CheckboxGroupConfigurationPB {
|
||||
#[pb(index = 1)]
|
||||
pub(crate) hide_empty: bool,
|
||||
}
|
||||
|
||||
pub fn group_config_pb_to_json_str<T: Into<Bytes>>(
|
||||
bytes: T,
|
||||
field_type: &FieldType,
|
||||
) -> FlowyResult<String> {
|
||||
let bytes = bytes.into();
|
||||
match field_type {
|
||||
FieldType::DateTime => DateGroupConfigurationPB::try_from(bytes)
|
||||
.map(|pb| DateGroupConfiguration::from(pb).to_json())?,
|
||||
_ => Ok("".to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn group_config_json_to_pb(setting_content: String, field_type: &FieldType) -> Bytes {
|
||||
match field_type {
|
||||
FieldType::DateTime => {
|
||||
let date_group_config = DateGroupConfiguration::from_json(setting_content.as_ref()).unwrap();
|
||||
DateGroupConfigurationPB::from(date_group_config)
|
||||
.try_into()
|
||||
.unwrap()
|
||||
},
|
||||
_ => Bytes::new(),
|
||||
}
|
||||
}
|
||||
|
@ -5,9 +5,11 @@ use flowy_error::ErrorCode;
|
||||
use validator::Validate;
|
||||
|
||||
use crate::entities::parser::NotEmptyStr;
|
||||
use crate::entities::RowMetaPB;
|
||||
use crate::entities::{FieldType, RowMetaPB};
|
||||
use crate::services::group::{GroupChangeset, GroupData, GroupSetting};
|
||||
|
||||
use super::group_config_json_to_pb;
|
||||
|
||||
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
|
||||
pub struct GroupSettingPB {
|
||||
#[pb(index = 1)]
|
||||
@ -15,13 +17,18 @@ pub struct GroupSettingPB {
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub field_id: String,
|
||||
|
||||
#[pb(index = 3)]
|
||||
pub content: Vec<u8>,
|
||||
}
|
||||
|
||||
impl std::convert::From<&GroupSetting> for GroupSettingPB {
|
||||
fn from(rev: &GroupSetting) -> Self {
|
||||
let field_type = FieldType::from(rev.field_type);
|
||||
GroupSettingPB {
|
||||
id: rev.id.clone(),
|
||||
field_id: rev.field_id.clone(),
|
||||
content: group_config_json_to_pb(rev.content.clone(), &field_type).to_vec(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -105,6 +112,9 @@ pub struct GroupByFieldPayloadPB {
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub view_id: String,
|
||||
|
||||
#[pb(index = 3)]
|
||||
pub setting_content: Vec<u8>,
|
||||
}
|
||||
|
||||
impl TryInto<GroupByFieldParams> for GroupByFieldPayloadPB {
|
||||
@ -118,13 +128,18 @@ impl TryInto<GroupByFieldParams> for GroupByFieldPayloadPB {
|
||||
.map_err(|_| ErrorCode::ViewIdIsInvalid)?
|
||||
.0;
|
||||
|
||||
Ok(GroupByFieldParams { field_id, view_id })
|
||||
Ok(GroupByFieldParams {
|
||||
field_id,
|
||||
view_id,
|
||||
setting_content: self.setting_content,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct GroupByFieldParams {
|
||||
pub field_id: String,
|
||||
pub view_id: String,
|
||||
pub setting_content: Vec<u8>,
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone, Validate)]
|
||||
|
@ -656,7 +656,7 @@ pub(crate) async fn set_group_by_field_handler(
|
||||
let params: GroupByFieldParams = data.into_inner().try_into()?;
|
||||
let database_editor = manager.get_database_with_view_id(¶ms.view_id).await?;
|
||||
database_editor
|
||||
.set_group_by_field(¶ms.view_id, ¶ms.field_id)
|
||||
.set_group_by_field(¶ms.view_id, ¶ms.field_id, params.setting_content)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -136,20 +136,37 @@ impl DatabaseEditor {
|
||||
self.database.lock().fields.get_field(field_id)
|
||||
}
|
||||
|
||||
pub async fn set_group_by_field(&self, view_id: &str, field_id: &str) -> FlowyResult<()> {
|
||||
pub async fn set_group_by_field(
|
||||
&self,
|
||||
view_id: &str,
|
||||
field_id: &str,
|
||||
data: Vec<u8>,
|
||||
) -> FlowyResult<()> {
|
||||
let old_group_settings: Vec<GroupSetting>;
|
||||
let mut setting_content = "".to_string();
|
||||
{
|
||||
let database = self.database.lock();
|
||||
let field = database.fields.get_field(field_id);
|
||||
old_group_settings = database.get_all_group_setting(view_id);
|
||||
if let Some(field) = field {
|
||||
let group_setting = default_group_setting(&field);
|
||||
let field_type = FieldType::from(field.field_type);
|
||||
setting_content = group_config_pb_to_json_str(data, &field_type)?;
|
||||
let mut group_setting = default_group_setting(&field);
|
||||
group_setting.content = setting_content.clone();
|
||||
database.views.update_database_view(view_id, |view| {
|
||||
view.set_groups(vec![group_setting.into()]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let old_group_setting = old_group_settings.iter().find(|g| g.field_id == field_id);
|
||||
let has_same_content =
|
||||
old_group_setting.is_some() && old_group_setting.unwrap().content == setting_content;
|
||||
|
||||
let view_editor = self.database_views.get_view_editor(view_id).await?;
|
||||
view_editor.v_initialize_new_group(field_id).await?;
|
||||
if !view_editor.is_grouping_field(field_id).await || !has_same_content {
|
||||
view_editor.v_initialize_new_group(field_id).await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -401,15 +401,12 @@ impl DatabaseViewEditor {
|
||||
|
||||
/// Called when the user changes the grouping field
|
||||
pub async fn v_initialize_new_group(&self, field_id: &str) -> FlowyResult<()> {
|
||||
let is_grouping_field = self.is_grouping_field(field_id).await;
|
||||
if !is_grouping_field {
|
||||
self.v_group_by_field(field_id).await?;
|
||||
|
||||
if let Some(view) = self.delegate.get_view(&self.view_id).await {
|
||||
let setting = database_view_setting_pb_from_view(view);
|
||||
notify_did_update_setting(&self.view_id, setting).await;
|
||||
}
|
||||
if let Some(view) = self.delegate.get_view(&self.view_id).await {
|
||||
let setting = database_view_setting_pb_from_view(view);
|
||||
notify_did_update_setting(&self.view_id, setting).await;
|
||||
}
|
||||
|
||||
self.v_group_by_field(field_id).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@ use collab_database::rows::{new_cell_builder, Cell, Cells, Row, RowDetail};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_repr::{Deserialize_repr, Serialize_repr};
|
||||
|
||||
use flowy_error::FlowyResult;
|
||||
use flowy_error::{internal_error, FlowyResult};
|
||||
|
||||
use crate::entities::{
|
||||
FieldType, GroupPB, GroupRowsNotificationPB, InsertedGroupPB, InsertedRowPB, RowMetaPB,
|
||||
@ -27,13 +27,13 @@ pub struct DateGroupConfiguration {
|
||||
}
|
||||
|
||||
impl DateGroupConfiguration {
|
||||
fn from_json(s: &str) -> Result<Self, serde_json::Error> {
|
||||
pub fn from_json(s: &str) -> Result<Self, serde_json::Error> {
|
||||
serde_json::from_str(s)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn to_json(&self) -> Result<String, serde_json::Error> {
|
||||
serde_json::to_string(self)
|
||||
pub fn to_json(&self) -> FlowyResult<String> {
|
||||
serde_json::to_string(self).map_err(internal_error)
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user