use crate::entities::{CellMeta, FieldMeta, RowMeta, RowMetaChangeset}; use crate::parser::NotEmptyStr; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error_code::ErrorCode; use serde_repr::*; use std::collections::HashMap; use std::sync::Arc; use strum_macros::{Display, EnumCount as EnumCountMacro, EnumIter, EnumString}; #[derive(Debug, Clone, Default, ProtoBuf)] pub struct Grid { #[pb(index = 1)] pub id: String, #[pb(index = 2)] pub field_orders: Vec, #[pb(index = 3)] pub block_orders: Vec, } #[derive(Debug, Clone, Default, ProtoBuf)] pub struct Field { #[pb(index = 1)] pub id: String, #[pb(index = 2)] pub name: String, #[pb(index = 3)] pub desc: String, #[pb(index = 4)] pub field_type: FieldType, #[pb(index = 5)] pub frozen: bool, #[pb(index = 6)] pub visibility: bool, #[pb(index = 7)] pub width: i32, #[pb(index = 8)] pub is_primary: bool, } impl std::convert::From for Field { fn from(field_meta: FieldMeta) -> Self { Self { id: field_meta.id, name: field_meta.name, desc: field_meta.desc, field_type: field_meta.field_type, frozen: field_meta.frozen, visibility: field_meta.visibility, width: field_meta.width, is_primary: field_meta.is_primary, } } } #[derive(Debug, Clone, Default, ProtoBuf)] pub struct FieldOrder { #[pb(index = 1)] pub field_id: String, } impl std::convert::From<&FieldMeta> for FieldOrder { fn from(field_meta: &FieldMeta) -> Self { Self { field_id: field_meta.id.clone(), } } } impl std::convert::From<&str> for FieldOrder { fn from(s: &str) -> Self { FieldOrder { field_id: s.to_owned() } } } impl std::convert::From for FieldOrder { fn from(s: String) -> Self { FieldOrder { field_id: s } } } #[derive(Debug, Clone, Default, ProtoBuf)] pub struct GridFieldChangeset { #[pb(index = 1)] pub grid_id: String, #[pb(index = 2)] pub inserted_fields: Vec, #[pb(index = 3)] pub deleted_fields: Vec, #[pb(index = 4)] pub updated_fields: Vec, } impl GridFieldChangeset { pub fn insert(grid_id: &str, inserted_fields: Vec) -> Self { Self { grid_id: grid_id.to_owned(), inserted_fields, deleted_fields: vec![], updated_fields: vec![], } } pub fn delete(grid_id: &str, deleted_fields: Vec) -> Self { Self { grid_id: grid_id.to_string(), inserted_fields: vec![], deleted_fields, updated_fields: vec![], } } pub fn update(grid_id: &str, updated_fields: Vec) -> Self { Self { grid_id: grid_id.to_string(), inserted_fields: vec![], deleted_fields: vec![], updated_fields, } } } #[derive(Debug, Clone, Default, ProtoBuf)] pub struct IndexField { #[pb(index = 1)] pub field: Field, #[pb(index = 2)] pub index: i32, } impl IndexField { pub fn from_field_meta(field_meta: &FieldMeta, index: usize) -> Self { Self { field: Field::from(field_meta.clone()), index: index as i32, } } } #[derive(Debug, Default, ProtoBuf)] pub struct GetEditFieldContextPayload { #[pb(index = 1)] pub grid_id: String, #[pb(index = 2, one_of)] pub field_id: Option, #[pb(index = 3)] pub field_type: FieldType, } #[derive(Debug, Default, ProtoBuf)] pub struct EditFieldPayload { #[pb(index = 1)] pub grid_id: String, #[pb(index = 2, one_of)] pub field_id: Option, #[pb(index = 3)] pub field_type: FieldType, } pub struct EditFieldParams { pub grid_id: String, pub field_id: Option, pub field_type: FieldType, } impl TryInto for EditFieldPayload { type Error = ErrorCode; fn try_into(self) -> Result { let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; // let field_id = NotEmptyStr::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?; Ok(EditFieldParams { grid_id: grid_id.0, field_id: self.field_id, field_type: self.field_type, }) } } #[derive(Debug, Default, ProtoBuf)] pub struct EditFieldContext { #[pb(index = 1)] pub grid_id: String, #[pb(index = 2)] pub grid_field: Field, #[pb(index = 3)] pub type_option_data: Vec, } #[derive(Debug, Default, ProtoBuf)] pub struct FieldTypeOptionData { #[pb(index = 1)] pub field_id: String, #[pb(index = 2)] pub type_option_data: Vec, } #[derive(Debug, Default, ProtoBuf)] pub struct RepeatedField { #[pb(index = 1)] pub items: Vec, } impl std::ops::Deref for RepeatedField { type Target = Vec; fn deref(&self) -> &Self::Target { &self.items } } impl std::ops::DerefMut for RepeatedField { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.items } } impl std::convert::From> for RepeatedField { fn from(items: Vec) -> Self { Self { items } } } #[derive(Debug, Clone, Default, ProtoBuf)] pub struct RepeatedFieldOrder { #[pb(index = 1)] pub items: Vec, } impl std::ops::Deref for RepeatedFieldOrder { type Target = Vec; fn deref(&self) -> &Self::Target { &self.items } } impl std::convert::From> for RepeatedFieldOrder { fn from(field_orders: Vec) -> Self { RepeatedFieldOrder { items: field_orders } } } impl std::convert::From for RepeatedFieldOrder { fn from(s: String) -> Self { RepeatedFieldOrder { items: vec![FieldOrder::from(s)], } } } #[derive(Debug, Default, Clone, ProtoBuf)] pub struct RowOrder { #[pb(index = 1)] pub row_id: String, #[pb(index = 2)] pub block_id: String, #[pb(index = 3)] pub height: i32, } impl std::convert::From<&RowMeta> for RowOrder { fn from(row: &RowMeta) -> Self { Self { row_id: row.id.clone(), block_id: row.block_id.clone(), height: row.height, } } } impl std::convert::From<&Arc> for RowOrder { fn from(row: &Arc) -> Self { Self { row_id: row.id.clone(), block_id: row.block_id.clone(), height: row.height, } } } #[derive(Debug, Default, ProtoBuf)] pub struct Row { #[pb(index = 1)] pub id: String, #[pb(index = 2)] pub cell_by_field_id: HashMap, #[pb(index = 3)] pub height: i32, } #[derive(Debug, Default, ProtoBuf)] pub struct RepeatedRow { #[pb(index = 1)] pub items: Vec, } impl std::convert::From> for RepeatedRow { fn from(items: Vec) -> Self { Self { items } } } #[derive(Debug, Default, ProtoBuf)] pub struct RepeatedGridBlock { #[pb(index = 1)] pub items: Vec, } impl std::convert::From> for RepeatedGridBlock { fn from(items: Vec) -> Self { Self { items } } } #[derive(Debug, Clone, Default, ProtoBuf)] pub struct GridBlockOrder { #[pb(index = 1)] pub block_id: String, #[pb(index = 2)] pub row_orders: Vec, } impl GridBlockOrder { pub fn new(block_id: &str) -> Self { GridBlockOrder { block_id: block_id.to_owned(), row_orders: vec![], } } } #[derive(Debug, Clone, Default, ProtoBuf)] pub struct IndexRowOrder { #[pb(index = 1)] pub row_order: RowOrder, #[pb(index = 2, one_of)] pub index: Option, } #[derive(Debug, Default, ProtoBuf)] pub struct UpdatedRowOrder { #[pb(index = 1)] pub row_order: RowOrder, #[pb(index = 2)] pub row: Row, } impl UpdatedRowOrder { pub fn new(row_meta: &RowMeta, row: Row) -> Self { Self { row_order: RowOrder::from(row_meta), row, } } } #[derive(Debug, Default, ProtoBuf)] pub struct GridRowsChangeset { #[pb(index = 1)] pub block_id: String, #[pb(index = 2)] pub inserted_rows: Vec, #[pb(index = 3)] pub deleted_rows: Vec, #[pb(index = 4)] pub updated_rows: Vec, } impl std::convert::From for IndexRowOrder { fn from(row_order: RowOrder) -> Self { Self { row_order, index: None } } } impl std::convert::From<&RowMeta> for IndexRowOrder { fn from(row: &RowMeta) -> Self { let row_order = RowOrder::from(row); Self::from(row_order) } } impl GridRowsChangeset { pub fn insert(block_id: &str, inserted_rows: Vec) -> Self { Self { block_id: block_id.to_owned(), inserted_rows, deleted_rows: vec![], updated_rows: vec![], } } pub fn delete(block_id: &str, deleted_rows: Vec) -> Self { Self { block_id: block_id.to_owned(), inserted_rows: vec![], deleted_rows, updated_rows: vec![], } } pub fn update(block_id: &str, updated_rows: Vec) -> Self { Self { block_id: block_id.to_owned(), inserted_rows: vec![], deleted_rows: vec![], updated_rows, } } } #[derive(Debug, Default, ProtoBuf)] pub struct GridBlock { #[pb(index = 1)] pub id: String, #[pb(index = 2)] pub row_orders: Vec, } impl GridBlock { pub fn new(block_id: &str, row_orders: Vec) -> Self { Self { id: block_id.to_owned(), row_orders, } } } #[derive(Debug, Default, ProtoBuf)] pub struct Cell { #[pb(index = 1)] pub field_id: String, #[pb(index = 2)] pub content: String, } impl Cell { pub fn new(field_id: &str, content: String) -> Self { Self { field_id: field_id.to_owned(), content, } } } #[derive(Debug, Default, ProtoBuf)] pub struct RepeatedCell { #[pb(index = 1)] pub items: Vec, } impl std::ops::Deref for RepeatedCell { type Target = Vec; fn deref(&self) -> &Self::Target { &self.items } } impl std::ops::DerefMut for RepeatedCell { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.items } } impl std::convert::From> for RepeatedCell { fn from(items: Vec) -> Self { Self { items } } } #[derive(ProtoBuf, Default)] pub struct CreateGridPayload { #[pb(index = 1)] pub name: String, } #[derive(Clone, ProtoBuf, Default, Debug)] pub struct GridId { #[pb(index = 1)] pub value: String, } impl AsRef for GridId { fn as_ref(&self) -> &str { &self.value } } #[derive(Clone, ProtoBuf, Default, Debug)] pub struct GridBlockId { #[pb(index = 1)] pub value: String, } impl AsRef for GridBlockId { fn as_ref(&self) -> &str { &self.value } } impl std::convert::From<&str> for GridBlockId { fn from(s: &str) -> Self { GridBlockId { value: s.to_owned() } } } #[derive(ProtoBuf, Default)] pub struct CreateRowPayload { #[pb(index = 1)] pub grid_id: String, #[pb(index = 2, one_of)] pub start_row_id: Option, } #[derive(Default)] pub struct CreateRowParams { pub grid_id: String, pub start_row_id: Option, } impl TryInto for CreateRowPayload { type Error = ErrorCode; fn try_into(self) -> Result { let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; Ok(CreateRowParams { grid_id: grid_id.0, start_row_id: self.start_row_id, }) } } #[derive(ProtoBuf, Default)] pub struct InsertFieldPayload { #[pb(index = 1)] pub grid_id: String, #[pb(index = 2)] pub field: Field, #[pb(index = 3)] pub type_option_data: Vec, #[pb(index = 4, one_of)] pub start_field_id: Option, } #[derive(Clone)] pub struct InsertFieldParams { pub grid_id: String, pub field: Field, pub type_option_data: Vec, pub start_field_id: Option, } impl TryInto for InsertFieldPayload { type Error = ErrorCode; fn try_into(self) -> Result { let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; let _ = NotEmptyStr::parse(self.field.id.clone()).map_err(|_| ErrorCode::FieldIdIsEmpty)?; let start_field_id = match self.start_field_id { None => None, Some(id) => Some(NotEmptyStr::parse(id).map_err(|_| ErrorCode::FieldIdIsEmpty)?.0), }; Ok(InsertFieldParams { grid_id: grid_id.0, field: self.field, type_option_data: self.type_option_data, start_field_id, }) } } #[derive(ProtoBuf, Default)] pub struct QueryFieldPayload { #[pb(index = 1)] pub grid_id: String, #[pb(index = 2)] pub field_orders: RepeatedFieldOrder, } pub struct QueryFieldParams { pub grid_id: String, pub field_orders: RepeatedFieldOrder, } impl TryInto for QueryFieldPayload { type Error = ErrorCode; fn try_into(self) -> Result { let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; Ok(QueryFieldParams { grid_id: grid_id.0, field_orders: self.field_orders, }) } } #[derive(ProtoBuf, Default)] pub struct QueryGridBlocksPayload { #[pb(index = 1)] pub grid_id: String, #[pb(index = 2)] pub block_orders: Vec, } pub struct QueryGridBlocksParams { pub grid_id: String, pub block_orders: Vec, } impl TryInto for QueryGridBlocksPayload { type Error = ErrorCode; fn try_into(self) -> Result { let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; Ok(QueryGridBlocksParams { grid_id: grid_id.0, block_orders: self.block_orders, }) } } #[derive(Debug, Clone, Default, ProtoBuf)] pub struct FieldChangesetPayload { #[pb(index = 1)] pub field_id: String, #[pb(index = 2)] pub grid_id: String, #[pb(index = 3, one_of)] pub name: Option, #[pb(index = 4, one_of)] pub desc: Option, #[pb(index = 5, one_of)] pub field_type: Option, #[pb(index = 6, one_of)] pub frozen: Option, #[pb(index = 7, one_of)] pub visibility: Option, #[pb(index = 8, one_of)] pub width: Option, #[pb(index = 9, one_of)] pub type_option_data: Option>, } #[derive(Debug, Clone, Default)] pub struct FieldChangesetParams { pub field_id: String, pub grid_id: String, pub name: Option, pub desc: Option, pub field_type: Option, pub frozen: Option, pub visibility: Option, pub width: Option, pub type_option_data: Option>, } impl TryInto for FieldChangesetPayload { type Error = ErrorCode; fn try_into(self) -> Result { let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; let field_id = NotEmptyStr::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?; if let Some(type_option_data) = self.type_option_data.as_ref() { if type_option_data.is_empty() { return Err(ErrorCode::TypeOptionDataIsEmpty); } } Ok(FieldChangesetParams { field_id: field_id.0, grid_id: grid_id.0, name: self.name, desc: self.desc, field_type: self.field_type, frozen: self.frozen, visibility: self.visibility, width: self.width, type_option_data: self.type_option_data, }) } } #[derive(Debug, Clone, ProtoBuf_Enum)] pub enum MoveItemType { MoveField = 0, MoveRow = 1, } impl std::default::Default for MoveItemType { fn default() -> Self { MoveItemType::MoveField } } #[derive(Debug, Clone, Default, ProtoBuf)] pub struct MoveItemPayload { #[pb(index = 1)] pub grid_id: String, #[pb(index = 2)] pub item_id: String, #[pb(index = 3)] pub from_index: i32, #[pb(index = 4)] pub to_index: i32, #[pb(index = 5)] pub ty: MoveItemType, } #[derive(Clone)] pub struct MoveItemParams { pub grid_id: String, pub item_id: String, pub from_index: i32, pub to_index: i32, pub ty: MoveItemType, } impl TryInto for MoveItemPayload { type Error = ErrorCode; fn try_into(self) -> Result { let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?; let item_id = NotEmptyStr::parse(self.item_id).map_err(|_| ErrorCode::InvalidData)?; Ok(MoveItemParams { grid_id: grid_id.0, item_id: item_id.0, from_index: self.from_index, to_index: self.to_index, ty: self.ty, }) } } #[derive( Debug, Clone, PartialEq, Eq, ProtoBuf_Enum, EnumCountMacro, EnumString, EnumIter, Display, Serialize_repr, Deserialize_repr, )] #[repr(u8)] pub enum FieldType { RichText = 0, Number = 1, DateTime = 2, SingleSelect = 3, MultiSelect = 4, Checkbox = 5, } impl std::default::Default for FieldType { fn default() -> Self { FieldType::RichText } } impl AsRef for FieldType { fn as_ref(&self) -> &FieldType { self } } impl From<&FieldType> for FieldType { fn from(field_type: &FieldType) -> Self { field_type.clone() } } impl FieldType { pub fn type_id(&self) -> String { let ty = self.clone(); format!("{}", ty as u8) } pub fn default_cell_width(&self) -> i32 { match self { FieldType::DateTime => 180, _ => 150, } } } #[derive(Debug, Clone, Default, ProtoBuf)] pub struct CellChangeset { #[pb(index = 1)] pub grid_id: String, #[pb(index = 2)] pub row_id: String, #[pb(index = 3)] pub field_id: String, #[pb(index = 4, one_of)] pub data: Option, } impl std::convert::From for RowMetaChangeset { fn from(changeset: CellChangeset) -> Self { let mut cell_by_field_id = HashMap::with_capacity(1); let field_id = changeset.field_id; let cell_meta = CellMeta { data: changeset.data.unwrap_or_else(|| "".to_owned()), }; cell_by_field_id.insert(field_id, cell_meta); RowMetaChangeset { row_id: changeset.row_id, height: None, visibility: None, cell_by_field_id, } } }