2022-03-10 04:01:31 +00:00
|
|
|
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use std::collections::HashMap;
|
2022-03-16 02:02:37 +00:00
|
|
|
|
2022-03-15 11:00:28 +00:00
|
|
|
use strum_macros::{Display, EnumCount as EnumCountMacro, EnumIter, EnumString};
|
2022-03-10 04:01:31 +00:00
|
|
|
|
|
|
|
pub const DEFAULT_ROW_HEIGHT: i32 = 36;
|
|
|
|
pub const DEFAULT_FIELD_WIDTH: i32 = 150;
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)]
|
|
|
|
pub struct GridMeta {
|
|
|
|
#[pb(index = 1)]
|
|
|
|
pub grid_id: String,
|
|
|
|
|
|
|
|
#[pb(index = 2)]
|
2022-03-15 03:07:18 +00:00
|
|
|
pub fields: Vec<FieldMeta>,
|
2022-03-10 04:01:31 +00:00
|
|
|
|
|
|
|
#[pb(index = 3)]
|
2022-03-11 13:36:00 +00:00
|
|
|
pub blocks: Vec<GridBlock>,
|
2022-03-10 04:01:31 +00:00
|
|
|
}
|
|
|
|
|
2022-03-13 03:06:28 +00:00
|
|
|
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, ProtoBuf)]
|
2022-03-11 13:36:00 +00:00
|
|
|
pub struct GridBlock {
|
2022-03-10 04:01:31 +00:00
|
|
|
#[pb(index = 1)]
|
|
|
|
pub id: String,
|
|
|
|
|
2022-03-10 09:14:10 +00:00
|
|
|
#[pb(index = 2)]
|
|
|
|
pub start_row_index: i32,
|
|
|
|
|
|
|
|
#[pb(index = 3)]
|
|
|
|
pub row_count: i32,
|
|
|
|
}
|
|
|
|
|
2022-03-15 03:07:18 +00:00
|
|
|
impl GridBlock {
|
|
|
|
pub fn len(&self) -> i32 {
|
|
|
|
self.start_row_index + self.row_count
|
|
|
|
}
|
2022-03-16 02:02:37 +00:00
|
|
|
|
|
|
|
pub fn is_empty(&self) -> bool {
|
|
|
|
self.row_count == 0
|
|
|
|
}
|
2022-03-15 03:07:18 +00:00
|
|
|
}
|
|
|
|
|
2022-03-12 01:30:13 +00:00
|
|
|
impl GridBlock {
|
|
|
|
pub fn new() -> Self {
|
|
|
|
GridBlock {
|
|
|
|
id: uuid::Uuid::new_v4().to_string(),
|
|
|
|
..Default::default()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-11 13:36:00 +00:00
|
|
|
pub struct GridBlockChangeset {
|
|
|
|
pub block_id: String,
|
|
|
|
pub start_row_index: Option<i32>,
|
|
|
|
pub row_count: Option<i32>,
|
|
|
|
}
|
|
|
|
|
2022-03-13 03:06:28 +00:00
|
|
|
impl GridBlockChangeset {
|
|
|
|
pub fn from_row_count(block_id: &str, row_count: i32) -> Self {
|
|
|
|
Self {
|
|
|
|
block_id: block_id.to_string(),
|
|
|
|
start_row_index: None,
|
|
|
|
row_count: Some(row_count),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-10 09:14:10 +00:00
|
|
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)]
|
2022-03-11 13:36:00 +00:00
|
|
|
pub struct GridBlockMeta {
|
2022-03-10 09:14:10 +00:00
|
|
|
#[pb(index = 1)]
|
|
|
|
pub block_id: String,
|
|
|
|
|
2022-03-10 04:01:31 +00:00
|
|
|
#[pb(index = 2)]
|
|
|
|
pub rows: Vec<RowMeta>,
|
|
|
|
}
|
|
|
|
|
2022-03-12 14:52:24 +00:00
|
|
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf, PartialEq, Eq)]
|
2022-03-15 03:07:18 +00:00
|
|
|
pub struct FieldMeta {
|
2022-03-10 04:01:31 +00:00
|
|
|
#[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)]
|
2022-03-12 14:52:24 +00:00
|
|
|
pub type_options: String,
|
2022-03-10 04:01:31 +00:00
|
|
|
}
|
|
|
|
|
2022-03-15 03:07:18 +00:00
|
|
|
impl FieldMeta {
|
2022-03-12 01:30:13 +00:00
|
|
|
pub fn new(name: &str, desc: &str, field_type: FieldType) -> Self {
|
2022-03-10 04:01:31 +00:00
|
|
|
Self {
|
2022-03-12 01:30:13 +00:00
|
|
|
id: uuid::Uuid::new_v4().to_string(),
|
2022-03-10 04:01:31 +00:00
|
|
|
name: name.to_string(),
|
|
|
|
desc: desc.to_string(),
|
|
|
|
field_type,
|
|
|
|
frozen: false,
|
|
|
|
visibility: true,
|
|
|
|
width: DEFAULT_FIELD_WIDTH,
|
|
|
|
type_options: Default::default(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-11 13:36:00 +00:00
|
|
|
#[derive(Debug, Clone, Default, ProtoBuf)]
|
|
|
|
pub struct FieldChangeset {
|
|
|
|
#[pb(index = 1)]
|
|
|
|
pub field_id: String,
|
|
|
|
|
|
|
|
#[pb(index = 2, one_of)]
|
|
|
|
pub name: Option<String>,
|
|
|
|
|
|
|
|
#[pb(index = 3, one_of)]
|
|
|
|
pub desc: Option<String>,
|
|
|
|
|
|
|
|
#[pb(index = 4, one_of)]
|
|
|
|
pub field_type: Option<FieldType>,
|
|
|
|
|
|
|
|
#[pb(index = 5, one_of)]
|
|
|
|
pub frozen: Option<bool>,
|
|
|
|
|
|
|
|
#[pb(index = 6, one_of)]
|
|
|
|
pub visibility: Option<bool>,
|
|
|
|
|
|
|
|
#[pb(index = 7, one_of)]
|
|
|
|
pub width: Option<i32>,
|
|
|
|
|
|
|
|
#[pb(index = 8, one_of)]
|
2022-03-12 14:52:24 +00:00
|
|
|
pub type_options: Option<String>,
|
2022-03-11 13:36:00 +00:00
|
|
|
}
|
|
|
|
|
2022-03-15 11:00:28 +00:00
|
|
|
#[derive(
|
|
|
|
Debug, Clone, PartialEq, Eq, ProtoBuf_Enum, EnumCountMacro, EnumString, EnumIter, Display, Serialize, Deserialize,
|
|
|
|
)]
|
2022-03-10 04:01:31 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-12 13:06:15 +00:00
|
|
|
impl AsRef<FieldType> for FieldType {
|
|
|
|
fn as_ref(&self) -> &FieldType {
|
2022-03-13 15:16:52 +00:00
|
|
|
self
|
2022-03-12 13:06:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-13 15:16:52 +00:00
|
|
|
impl From<&FieldType> for FieldType {
|
2022-03-15 03:07:18 +00:00
|
|
|
fn from(field_type: &FieldType) -> Self {
|
|
|
|
field_type.clone()
|
2022-03-12 13:06:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-10 04:01:31 +00:00
|
|
|
impl FieldType {
|
|
|
|
pub fn type_id(&self) -> String {
|
|
|
|
let ty = self.clone();
|
|
|
|
format!("{}", ty as u8)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn from_type_id(type_id: &str) -> Result<FieldType, String> {
|
|
|
|
match type_id {
|
|
|
|
"0" => Ok(FieldType::RichText),
|
|
|
|
"1" => Ok(FieldType::Number),
|
|
|
|
"2" => Ok(FieldType::DateTime),
|
|
|
|
"3" => Ok(FieldType::SingleSelect),
|
|
|
|
"4" => Ok(FieldType::MultiSelect),
|
|
|
|
"5" => Ok(FieldType::Checkbox),
|
|
|
|
_ => Err(format!("Invalid type_id: {}", type_id)),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, Default, ProtoBuf)]
|
|
|
|
pub struct AnyData {
|
|
|
|
#[pb(index = 1)]
|
|
|
|
pub type_id: String,
|
|
|
|
|
|
|
|
#[pb(index = 2)]
|
|
|
|
pub value: Vec<u8>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl AnyData {
|
2022-03-12 13:06:15 +00:00
|
|
|
pub fn from_str<F: Into<FieldType>>(field_type: F, s: &str) -> AnyData {
|
2022-03-10 04:01:31 +00:00
|
|
|
Self::from_bytes(field_type, s.as_bytes().to_vec())
|
|
|
|
}
|
|
|
|
|
2022-03-12 13:06:15 +00:00
|
|
|
pub fn from_bytes<T: AsRef<[u8]>, F: Into<FieldType>>(field_type: F, bytes: T) -> AnyData {
|
2022-03-10 04:01:31 +00:00
|
|
|
AnyData {
|
2022-03-12 13:06:15 +00:00
|
|
|
type_id: field_type.into().type_id(),
|
2022-03-10 04:01:31 +00:00
|
|
|
value: bytes.as_ref().to_vec(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ToString for AnyData {
|
|
|
|
fn to_string(&self) -> String {
|
|
|
|
match String::from_utf8(self.value.clone()) {
|
|
|
|
Ok(s) => s,
|
|
|
|
Err(_) => "".to_owned(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-13 03:06:28 +00:00
|
|
|
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, ProtoBuf)]
|
2022-03-10 04:01:31 +00:00
|
|
|
pub struct RowMeta {
|
|
|
|
#[pb(index = 1)]
|
|
|
|
pub id: String,
|
|
|
|
|
|
|
|
#[pb(index = 2)]
|
2022-03-10 13:43:23 +00:00
|
|
|
pub block_id: String,
|
2022-03-10 04:01:31 +00:00
|
|
|
|
|
|
|
#[pb(index = 3)]
|
|
|
|
pub cell_by_field_id: HashMap<String, CellMeta>,
|
|
|
|
|
|
|
|
#[pb(index = 4)]
|
|
|
|
pub height: i32,
|
|
|
|
|
|
|
|
#[pb(index = 5)]
|
|
|
|
pub visibility: bool,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl RowMeta {
|
2022-03-13 03:06:28 +00:00
|
|
|
pub fn new(block_id: &str) -> Self {
|
2022-03-10 04:01:31 +00:00
|
|
|
Self {
|
2022-03-12 01:30:13 +00:00
|
|
|
id: uuid::Uuid::new_v4().to_string(),
|
2022-03-11 13:36:00 +00:00
|
|
|
block_id: block_id.to_owned(),
|
2022-03-13 03:06:28 +00:00
|
|
|
cell_by_field_id: Default::default(),
|
2022-03-10 04:01:31 +00:00
|
|
|
height: DEFAULT_ROW_HEIGHT,
|
|
|
|
visibility: true,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-10 13:43:23 +00:00
|
|
|
#[derive(Debug, Clone, Default, ProtoBuf)]
|
|
|
|
pub struct RowMetaChangeset {
|
|
|
|
#[pb(index = 1)]
|
|
|
|
pub row_id: String,
|
|
|
|
|
|
|
|
#[pb(index = 2, one_of)]
|
|
|
|
pub height: Option<i32>,
|
|
|
|
|
|
|
|
#[pb(index = 3, one_of)]
|
|
|
|
pub visibility: Option<bool>,
|
|
|
|
|
|
|
|
#[pb(index = 4)]
|
|
|
|
pub cell_by_field_id: HashMap<String, CellMeta>,
|
|
|
|
}
|
|
|
|
|
2022-03-13 03:06:28 +00:00
|
|
|
#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize, ProtoBuf)]
|
2022-03-10 04:01:31 +00:00
|
|
|
pub struct CellMeta {
|
|
|
|
#[pb(index = 1)]
|
|
|
|
pub field_id: String,
|
|
|
|
|
2022-03-13 03:06:28 +00:00
|
|
|
#[pb(index = 2)]
|
|
|
|
pub data: String,
|
|
|
|
}
|
2022-03-10 04:01:31 +00:00
|
|
|
|
2022-03-13 03:06:28 +00:00
|
|
|
impl CellMeta {
|
|
|
|
pub fn new(field_id: &str, data: String) -> Self {
|
|
|
|
Self {
|
|
|
|
field_id: field_id.to_string(),
|
|
|
|
data,
|
|
|
|
}
|
|
|
|
}
|
2022-03-10 04:01:31 +00:00
|
|
|
}
|
2022-03-14 09:24:25 +00:00
|
|
|
|
|
|
|
#[derive(Debug, Clone, Default, ProtoBuf)]
|
|
|
|
pub struct CellMetaChangeset {
|
|
|
|
#[pb(index = 1)]
|
|
|
|
pub row_id: String,
|
|
|
|
|
|
|
|
#[pb(index = 2)]
|
|
|
|
pub field_id: String,
|
|
|
|
|
|
|
|
#[pb(index = 3, one_of)]
|
|
|
|
pub data: Option<String>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl std::convert::From<CellMetaChangeset> for RowMetaChangeset {
|
|
|
|
fn from(changeset: CellMetaChangeset) -> Self {
|
|
|
|
let mut cell_by_field_id = HashMap::with_capacity(1);
|
|
|
|
if let Some(data) = changeset.data {
|
|
|
|
let field_id = changeset.field_id;
|
|
|
|
let cell_meta = CellMeta {
|
|
|
|
field_id: field_id.clone(),
|
|
|
|
data,
|
|
|
|
};
|
|
|
|
cell_by_field_id.insert(field_id, cell_meta);
|
|
|
|
}
|
|
|
|
|
|
|
|
RowMetaChangeset {
|
|
|
|
row_id: changeset.row_id,
|
|
|
|
height: None,
|
|
|
|
visibility: None,
|
|
|
|
cell_by_field_id,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-03-15 11:00:28 +00:00
|
|
|
|
|
|
|
#[derive(Clone, ProtoBuf)]
|
|
|
|
pub struct BuildGridContext {
|
|
|
|
#[pb(index = 1)]
|
|
|
|
pub field_metas: Vec<FieldMeta>,
|
|
|
|
|
|
|
|
#[pb(index = 2)]
|
|
|
|
pub grid_block: GridBlock,
|
|
|
|
|
|
|
|
#[pb(index = 3)]
|
|
|
|
pub grid_block_meta: GridBlockMeta,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl std::default::Default for BuildGridContext {
|
|
|
|
fn default() -> Self {
|
|
|
|
let grid_block = GridBlock::new();
|
|
|
|
let grid_block_meta = GridBlockMeta {
|
|
|
|
block_id: grid_block.id.clone(),
|
|
|
|
rows: vec![],
|
|
|
|
};
|
|
|
|
|
|
|
|
Self {
|
|
|
|
field_metas: vec![],
|
|
|
|
grid_block,
|
|
|
|
grid_block_meta,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|