mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
refactor: move entities from flowy-grid-data-model to flowy-grid crate
This commit is contained in:
208
frontend/rust-lib/flowy-grid/src/entities/block_entities.rs
Normal file
208
frontend/rust-lib/flowy-grid/src/entities/block_entities.rs
Normal file
@ -0,0 +1,208 @@
|
||||
use flowy_derive::ProtoBuf;
|
||||
use flowy_error::ErrorCode;
|
||||
use flowy_grid_data_model::parser::NotEmptyStr;
|
||||
use flowy_grid_data_model::revision::RowRevision;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(Debug, Clone, Default, ProtoBuf)]
|
||||
pub struct GridBlock {
|
||||
#[pb(index = 1)]
|
||||
pub id: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub row_orders: Vec<RowOrder>,
|
||||
}
|
||||
|
||||
impl GridBlock {
|
||||
pub fn new(block_id: &str, row_orders: Vec<RowOrder>) -> Self {
|
||||
Self {
|
||||
id: block_id.to_owned(),
|
||||
row_orders,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[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<&RowRevision> for RowOrder {
|
||||
fn from(row: &RowRevision) -> Self {
|
||||
Self {
|
||||
row_id: row.id.clone(),
|
||||
block_id: row.block_id.clone(),
|
||||
height: row.height,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<&Arc<RowRevision>> for RowOrder {
|
||||
fn from(row: &Arc<RowRevision>) -> 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 height: i32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, ProtoBuf)]
|
||||
pub struct OptionalRow {
|
||||
#[pb(index = 1, one_of)]
|
||||
pub row: Option<Row>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, ProtoBuf)]
|
||||
pub struct RepeatedRow {
|
||||
#[pb(index = 1)]
|
||||
pub items: Vec<Row>,
|
||||
}
|
||||
|
||||
impl std::convert::From<Vec<Row>> for RepeatedRow {
|
||||
fn from(items: Vec<Row>) -> Self {
|
||||
Self { items }
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Default, ProtoBuf)]
|
||||
pub struct RepeatedGridBlock {
|
||||
#[pb(index = 1)]
|
||||
pub items: Vec<GridBlock>,
|
||||
}
|
||||
|
||||
impl std::convert::From<Vec<GridBlock>> for RepeatedGridBlock {
|
||||
fn from(items: Vec<GridBlock>) -> Self {
|
||||
Self { items }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, ProtoBuf)]
|
||||
pub struct IndexRowOrder {
|
||||
#[pb(index = 1)]
|
||||
pub row_order: RowOrder,
|
||||
|
||||
#[pb(index = 2, one_of)]
|
||||
pub index: Option<i32>,
|
||||
}
|
||||
|
||||
#[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_rev: &RowRevision, row: Row) -> Self {
|
||||
Self {
|
||||
row_order: RowOrder::from(row_rev),
|
||||
row,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<RowOrder> for IndexRowOrder {
|
||||
fn from(row_order: RowOrder) -> Self {
|
||||
Self { row_order, index: None }
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<&RowRevision> for IndexRowOrder {
|
||||
fn from(row: &RowRevision) -> Self {
|
||||
let row_order = RowOrder::from(row);
|
||||
Self::from(row_order)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf, Default)]
|
||||
pub struct GridBlockNotification {
|
||||
#[pb(index = 1)]
|
||||
hide_rows: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, ProtoBuf)]
|
||||
pub struct GridRowsChangeset {
|
||||
#[pb(index = 1)]
|
||||
pub block_id: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub inserted_rows: Vec<IndexRowOrder>,
|
||||
|
||||
#[pb(index = 3)]
|
||||
pub deleted_rows: Vec<RowOrder>,
|
||||
|
||||
#[pb(index = 4)]
|
||||
pub updated_rows: Vec<UpdatedRowOrder>,
|
||||
}
|
||||
impl GridRowsChangeset {
|
||||
pub fn insert(block_id: &str, inserted_rows: Vec<IndexRowOrder>) -> 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<RowOrder>) -> 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<UpdatedRowOrder>) -> Self {
|
||||
Self {
|
||||
block_id: block_id.to_owned(),
|
||||
inserted_rows: vec![],
|
||||
deleted_rows: vec![],
|
||||
updated_rows,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf, Default)]
|
||||
pub struct QueryGridBlocksPayload {
|
||||
#[pb(index = 1)]
|
||||
pub grid_id: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub block_ids: Vec<String>,
|
||||
}
|
||||
|
||||
pub struct QueryGridBlocksParams {
|
||||
pub grid_id: String,
|
||||
pub block_ids: Vec<String>,
|
||||
}
|
||||
|
||||
impl TryInto<QueryGridBlocksParams> for QueryGridBlocksPayload {
|
||||
type Error = ErrorCode;
|
||||
|
||||
fn try_into(self) -> Result<QueryGridBlocksParams, Self::Error> {
|
||||
let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
|
||||
Ok(QueryGridBlocksParams {
|
||||
grid_id: grid_id.0,
|
||||
block_ids: self.block_ids,
|
||||
})
|
||||
}
|
||||
}
|
@ -2,6 +2,8 @@ use crate::entities::{FieldIdentifier, FieldIdentifierPayload};
|
||||
use flowy_derive::ProtoBuf;
|
||||
use flowy_error::ErrorCode;
|
||||
use flowy_grid_data_model::parser::NotEmptyStr;
|
||||
use flowy_grid_data_model::revision::{CellRevision, RowMetaChangeset};
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(ProtoBuf, Default)]
|
||||
pub struct CreateSelectOptionPayload {
|
||||
@ -70,3 +72,85 @@ impl TryInto<CellIdentifier> for CellIdentifierPayload {
|
||||
})
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Default, ProtoBuf)]
|
||||
pub struct Cell {
|
||||
#[pb(index = 1)]
|
||||
pub field_id: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub data: Vec<u8>,
|
||||
}
|
||||
|
||||
impl Cell {
|
||||
pub fn new(field_id: &str, data: Vec<u8>) -> Self {
|
||||
Self {
|
||||
field_id: field_id.to_owned(),
|
||||
data,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn empty(field_id: &str) -> Self {
|
||||
Self {
|
||||
field_id: field_id.to_owned(),
|
||||
data: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, ProtoBuf)]
|
||||
pub struct RepeatedCell {
|
||||
#[pb(index = 1)]
|
||||
pub items: Vec<Cell>,
|
||||
}
|
||||
|
||||
impl std::ops::Deref for RepeatedCell {
|
||||
type Target = Vec<Cell>;
|
||||
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<Vec<Cell>> for RepeatedCell {
|
||||
fn from(items: Vec<Cell>) -> Self {
|
||||
Self { items }
|
||||
}
|
||||
}
|
||||
|
||||
#[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 cell_content_changeset: Option<String>,
|
||||
}
|
||||
|
||||
impl std::convert::From<CellChangeset> 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_rev = CellRevision {
|
||||
data: changeset.cell_content_changeset.unwrap_or_else(|| "".to_owned()),
|
||||
};
|
||||
cell_by_field_id.insert(field_id, cell_rev);
|
||||
|
||||
RowMetaChangeset {
|
||||
row_id: changeset.row_id,
|
||||
height: None,
|
||||
visibility: None,
|
||||
cell_by_field_id,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,571 @@
|
||||
use flowy_derive::ProtoBuf;
|
||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||
use flowy_error::ErrorCode;
|
||||
use flowy_grid_data_model::parser::NotEmptyStr;
|
||||
use flowy_grid_data_model::revision::{FieldRevision, FieldTypeRevision};
|
||||
use flowy_sync::entities::grid::FieldChangesetParams;
|
||||
use serde_repr::*;
|
||||
use std::sync::Arc;
|
||||
|
||||
use strum_macros::{Display, EnumCount as EnumCountMacro, EnumIter, EnumString};
|
||||
|
||||
#[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<FieldRevision> for Field {
|
||||
fn from(field_rev: FieldRevision) -> Self {
|
||||
Self {
|
||||
id: field_rev.id,
|
||||
name: field_rev.name,
|
||||
desc: field_rev.desc,
|
||||
field_type: field_rev.field_type_rev.into(),
|
||||
frozen: field_rev.frozen,
|
||||
visibility: field_rev.visibility,
|
||||
width: field_rev.width,
|
||||
is_primary: field_rev.is_primary,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<Arc<FieldRevision>> for Field {
|
||||
fn from(field_rev: Arc<FieldRevision>) -> Self {
|
||||
let field_rev = field_rev.as_ref().clone();
|
||||
Field::from(field_rev)
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Clone, Default, ProtoBuf)]
|
||||
pub struct FieldOrder {
|
||||
#[pb(index = 1)]
|
||||
pub field_id: String,
|
||||
}
|
||||
|
||||
impl std::convert::From<&str> for FieldOrder {
|
||||
fn from(s: &str) -> Self {
|
||||
FieldOrder { field_id: s.to_owned() }
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<String> for FieldOrder {
|
||||
fn from(s: String) -> Self {
|
||||
FieldOrder { field_id: s }
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<&Arc<FieldRevision>> for FieldOrder {
|
||||
fn from(field_rev: &Arc<FieldRevision>) -> Self {
|
||||
Self {
|
||||
field_id: field_rev.id.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Clone, Default, ProtoBuf)]
|
||||
pub struct GridFieldChangeset {
|
||||
#[pb(index = 1)]
|
||||
pub grid_id: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub inserted_fields: Vec<IndexField>,
|
||||
|
||||
#[pb(index = 3)]
|
||||
pub deleted_fields: Vec<FieldOrder>,
|
||||
|
||||
#[pb(index = 4)]
|
||||
pub updated_fields: Vec<Field>,
|
||||
}
|
||||
|
||||
impl GridFieldChangeset {
|
||||
pub fn insert(grid_id: &str, inserted_fields: Vec<IndexField>) -> 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<FieldOrder>) -> 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<Field>) -> 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_rev(field_rev: &Arc<FieldRevision>, index: usize) -> Self {
|
||||
Self {
|
||||
field: Field::from(field_rev.as_ref().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<String>,
|
||||
|
||||
#[pb(index = 3)]
|
||||
pub field_type: FieldType,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, ProtoBuf)]
|
||||
pub struct EditFieldPayload {
|
||||
#[pb(index = 1)]
|
||||
pub grid_id: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub field_id: String,
|
||||
|
||||
#[pb(index = 3)]
|
||||
pub field_type: FieldType,
|
||||
|
||||
#[pb(index = 4)]
|
||||
pub create_if_not_exist: bool,
|
||||
}
|
||||
|
||||
pub struct EditFieldParams {
|
||||
pub grid_id: String,
|
||||
pub field_id: String,
|
||||
pub field_type: FieldType,
|
||||
}
|
||||
|
||||
impl TryInto<EditFieldParams> for EditFieldPayload {
|
||||
type Error = ErrorCode;
|
||||
|
||||
fn try_into(self) -> Result<EditFieldParams, Self::Error> {
|
||||
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: field_id.0,
|
||||
field_type: self.field_type,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CreateFieldParams {
|
||||
pub grid_id: String,
|
||||
pub field_type: FieldType,
|
||||
}
|
||||
|
||||
impl TryInto<CreateFieldParams> for EditFieldPayload {
|
||||
type Error = ErrorCode;
|
||||
|
||||
fn try_into(self) -> Result<CreateFieldParams, Self::Error> {
|
||||
let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
|
||||
|
||||
Ok(CreateFieldParams {
|
||||
grid_id: grid_id.0,
|
||||
field_type: self.field_type,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, ProtoBuf)]
|
||||
pub struct FieldTypeOptionContext {
|
||||
#[pb(index = 1)]
|
||||
pub grid_id: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub grid_field: Field,
|
||||
|
||||
#[pb(index = 3)]
|
||||
pub type_option_data: Vec<u8>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, ProtoBuf)]
|
||||
pub struct FieldTypeOptionData {
|
||||
#[pb(index = 1)]
|
||||
pub grid_id: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub field: Field,
|
||||
|
||||
#[pb(index = 3)]
|
||||
pub type_option_data: Vec<u8>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, ProtoBuf)]
|
||||
pub struct RepeatedField {
|
||||
#[pb(index = 1)]
|
||||
pub items: Vec<Field>,
|
||||
}
|
||||
impl std::ops::Deref for RepeatedField {
|
||||
type Target = Vec<Field>;
|
||||
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<Vec<Field>> for RepeatedField {
|
||||
fn from(items: Vec<Field>) -> Self {
|
||||
Self { items }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, ProtoBuf)]
|
||||
pub struct RepeatedFieldOrder {
|
||||
#[pb(index = 1)]
|
||||
pub items: Vec<FieldOrder>,
|
||||
}
|
||||
|
||||
impl std::ops::Deref for RepeatedFieldOrder {
|
||||
type Target = Vec<FieldOrder>;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.items
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<Vec<FieldOrder>> for RepeatedFieldOrder {
|
||||
fn from(field_orders: Vec<FieldOrder>) -> Self {
|
||||
RepeatedFieldOrder { items: field_orders }
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<String> for RepeatedFieldOrder {
|
||||
fn from(s: String) -> Self {
|
||||
RepeatedFieldOrder {
|
||||
items: vec![FieldOrder::from(s)],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[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<u8>,
|
||||
|
||||
#[pb(index = 4, one_of)]
|
||||
pub start_field_id: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct InsertFieldParams {
|
||||
pub grid_id: String,
|
||||
pub field: Field,
|
||||
pub type_option_data: Vec<u8>,
|
||||
pub start_field_id: Option<String>,
|
||||
}
|
||||
|
||||
impl TryInto<InsertFieldParams> for InsertFieldPayload {
|
||||
type Error = ErrorCode;
|
||||
|
||||
fn try_into(self) -> Result<InsertFieldParams, Self::Error> {
|
||||
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 UpdateFieldTypeOptionPayload {
|
||||
#[pb(index = 1)]
|
||||
pub grid_id: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub field_id: String,
|
||||
|
||||
#[pb(index = 3)]
|
||||
pub type_option_data: Vec<u8>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct UpdateFieldTypeOptionParams {
|
||||
pub grid_id: String,
|
||||
pub field_id: String,
|
||||
pub type_option_data: Vec<u8>,
|
||||
}
|
||||
|
||||
impl TryInto<UpdateFieldTypeOptionParams> for UpdateFieldTypeOptionPayload {
|
||||
type Error = ErrorCode;
|
||||
|
||||
fn try_into(self) -> Result<UpdateFieldTypeOptionParams, Self::Error> {
|
||||
let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
|
||||
let _ = NotEmptyStr::parse(self.field_id.clone()).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
|
||||
|
||||
Ok(UpdateFieldTypeOptionParams {
|
||||
grid_id: grid_id.0,
|
||||
field_id: self.field_id,
|
||||
type_option_data: self.type_option_data,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[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<QueryFieldParams> for QueryFieldPayload {
|
||||
type Error = ErrorCode;
|
||||
|
||||
fn try_into(self) -> Result<QueryFieldParams, Self::Error> {
|
||||
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(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<String>,
|
||||
|
||||
#[pb(index = 4, one_of)]
|
||||
pub desc: Option<String>,
|
||||
|
||||
#[pb(index = 5, one_of)]
|
||||
pub field_type: Option<FieldType>,
|
||||
|
||||
#[pb(index = 6, one_of)]
|
||||
pub frozen: Option<bool>,
|
||||
|
||||
#[pb(index = 7, one_of)]
|
||||
pub visibility: Option<bool>,
|
||||
|
||||
#[pb(index = 8, one_of)]
|
||||
pub width: Option<i32>,
|
||||
|
||||
#[pb(index = 9, one_of)]
|
||||
pub type_option_data: Option<Vec<u8>>,
|
||||
}
|
||||
|
||||
impl TryInto<FieldChangesetParams> for FieldChangesetPayload {
|
||||
type Error = ErrorCode;
|
||||
|
||||
fn try_into(self) -> Result<FieldChangesetParams, Self::Error> {
|
||||
let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
|
||||
let field_id = NotEmptyStr::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
|
||||
let field_type = self.field_type.map(FieldTypeRevision::from);
|
||||
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,
|
||||
frozen: self.frozen,
|
||||
visibility: self.visibility,
|
||||
width: self.width,
|
||||
type_option_data: self.type_option_data,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Debug,
|
||||
Clone,
|
||||
PartialEq,
|
||||
Hash,
|
||||
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,
|
||||
URL = 6,
|
||||
}
|
||||
|
||||
impl std::default::Default for FieldType {
|
||||
fn default() -> Self {
|
||||
FieldType::RichText
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<FieldType> 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 {
|
||||
(self.clone() as u8).to_string()
|
||||
}
|
||||
|
||||
pub fn default_cell_width(&self) -> i32 {
|
||||
match self {
|
||||
FieldType::DateTime => 180,
|
||||
_ => 150,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_number(&self) -> bool {
|
||||
self == &FieldType::Number
|
||||
}
|
||||
|
||||
pub fn is_text(&self) -> bool {
|
||||
self == &FieldType::RichText
|
||||
}
|
||||
|
||||
pub fn is_checkbox(&self) -> bool {
|
||||
self == &FieldType::Checkbox
|
||||
}
|
||||
|
||||
pub fn is_date(&self) -> bool {
|
||||
self == &FieldType::DateTime
|
||||
}
|
||||
|
||||
pub fn is_single_select(&self) -> bool {
|
||||
self == &FieldType::SingleSelect
|
||||
}
|
||||
|
||||
pub fn is_multi_select(&self) -> bool {
|
||||
self == &FieldType::MultiSelect
|
||||
}
|
||||
|
||||
pub fn is_url(&self) -> bool {
|
||||
self == &FieldType::URL
|
||||
}
|
||||
|
||||
pub fn is_select_option(&self) -> bool {
|
||||
self == &FieldType::MultiSelect || self == &FieldType::SingleSelect
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<&FieldType> for FieldTypeRevision {
|
||||
fn from(ty: &FieldType) -> Self {
|
||||
ty.clone() as u8
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<FieldType> for FieldTypeRevision {
|
||||
fn from(ty: FieldType) -> Self {
|
||||
ty as u8
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<&FieldTypeRevision> for FieldType {
|
||||
fn from(ty: &FieldTypeRevision) -> Self {
|
||||
FieldType::from(*ty)
|
||||
}
|
||||
}
|
||||
impl std::convert::From<FieldTypeRevision> for FieldType {
|
||||
fn from(ty: FieldTypeRevision) -> Self {
|
||||
match ty {
|
||||
0 => FieldType::RichText,
|
||||
1 => FieldType::Number,
|
||||
2 => FieldType::DateTime,
|
||||
3 => FieldType::SingleSelect,
|
||||
4 => FieldType::MultiSelect,
|
||||
5 => FieldType::Checkbox,
|
||||
6 => FieldType::URL,
|
||||
_ => {
|
||||
tracing::error!("Can't parser FieldTypeRevision: {} to FieldType", ty);
|
||||
FieldType::RichText
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Clone, Default, ProtoBuf)]
|
||||
pub struct FieldIdentifierPayload {
|
||||
#[pb(index = 1)]
|
||||
|
393
frontend/rust-lib/flowy-grid/src/entities/filter_entities.rs
Normal file
393
frontend/rust-lib/flowy-grid/src/entities/filter_entities.rs
Normal file
@ -0,0 +1,393 @@
|
||||
use crate::entities::FieldType;
|
||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||
use flowy_error::ErrorCode;
|
||||
use flowy_grid_data_model::parser::NotEmptyStr;
|
||||
use flowy_grid_data_model::revision::{FieldRevision, GridFilterRevision};
|
||||
use flowy_sync::entities::grid::{CreateGridFilterParams, DeleteFilterParams};
|
||||
use std::convert::TryInto;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
|
||||
pub struct GridFilter {
|
||||
#[pb(index = 1)]
|
||||
pub id: String,
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
|
||||
pub struct RepeatedGridFilter {
|
||||
#[pb(index = 1)]
|
||||
pub items: Vec<GridFilter>,
|
||||
}
|
||||
|
||||
impl std::convert::From<&Arc<GridFilterRevision>> for GridFilter {
|
||||
fn from(rev: &Arc<GridFilterRevision>) -> Self {
|
||||
Self { id: rev.id.clone() }
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<&Vec<Arc<GridFilterRevision>>> for RepeatedGridFilter {
|
||||
fn from(revs: &Vec<Arc<GridFilterRevision>>) -> Self {
|
||||
RepeatedGridFilter {
|
||||
items: revs.iter().map(|rev| rev.into()).collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<Vec<GridFilter>> for RepeatedGridFilter {
|
||||
fn from(items: Vec<GridFilter>) -> Self {
|
||||
Self { items }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf, Debug, Default, Clone)]
|
||||
pub struct DeleteFilterPayload {
|
||||
#[pb(index = 1)]
|
||||
pub filter_id: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub field_type: FieldType,
|
||||
}
|
||||
|
||||
impl TryInto<DeleteFilterParams> for DeleteFilterPayload {
|
||||
type Error = ErrorCode;
|
||||
|
||||
fn try_into(self) -> Result<DeleteFilterParams, Self::Error> {
|
||||
let filter_id = NotEmptyStr::parse(self.filter_id)
|
||||
.map_err(|_| ErrorCode::UnexpectedEmptyString)?
|
||||
.0;
|
||||
Ok(DeleteFilterParams {
|
||||
filter_id,
|
||||
field_type_rev: self.field_type.into(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf, Debug, Default, Clone)]
|
||||
pub struct CreateGridFilterPayload {
|
||||
#[pb(index = 1)]
|
||||
pub field_id: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub field_type: FieldType,
|
||||
|
||||
#[pb(index = 3)]
|
||||
pub condition: i32,
|
||||
|
||||
#[pb(index = 4, one_of)]
|
||||
pub content: Option<String>,
|
||||
}
|
||||
|
||||
impl CreateGridFilterPayload {
|
||||
#[allow(dead_code)]
|
||||
pub fn new<T: Into<i32>>(field_rev: &FieldRevision, condition: T, content: Option<String>) -> Self {
|
||||
Self {
|
||||
field_id: field_rev.id.clone(),
|
||||
field_type: field_rev.field_type_rev.into(),
|
||||
condition: condition.into(),
|
||||
content,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryInto<CreateGridFilterParams> for CreateGridFilterPayload {
|
||||
type Error = ErrorCode;
|
||||
|
||||
fn try_into(self) -> Result<CreateGridFilterParams, Self::Error> {
|
||||
let field_id = NotEmptyStr::parse(self.field_id)
|
||||
.map_err(|_| ErrorCode::FieldIdIsEmpty)?
|
||||
.0;
|
||||
let condition = self.condition as u8;
|
||||
match self.field_type {
|
||||
FieldType::RichText | FieldType::URL => {
|
||||
let _ = TextFilterCondition::try_from(condition)?;
|
||||
}
|
||||
FieldType::Checkbox => {
|
||||
let _ = CheckboxCondition::try_from(condition)?;
|
||||
}
|
||||
FieldType::Number => {
|
||||
let _ = NumberFilterCondition::try_from(condition)?;
|
||||
}
|
||||
FieldType::DateTime => {
|
||||
let _ = DateFilterCondition::try_from(condition)?;
|
||||
}
|
||||
FieldType::SingleSelect | FieldType::MultiSelect => {
|
||||
let _ = SelectOptionCondition::try_from(condition)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(CreateGridFilterParams {
|
||||
field_id,
|
||||
field_type_rev: self.field_type.into(),
|
||||
condition,
|
||||
content: self.content,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
|
||||
pub struct GridTextFilter {
|
||||
#[pb(index = 1)]
|
||||
pub condition: TextFilterCondition,
|
||||
|
||||
#[pb(index = 2, one_of)]
|
||||
pub content: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum)]
|
||||
#[repr(u8)]
|
||||
pub enum TextFilterCondition {
|
||||
Is = 0,
|
||||
IsNot = 1,
|
||||
Contains = 2,
|
||||
DoesNotContain = 3,
|
||||
StartsWith = 4,
|
||||
EndsWith = 5,
|
||||
TextIsEmpty = 6,
|
||||
TextIsNotEmpty = 7,
|
||||
}
|
||||
impl std::convert::From<TextFilterCondition> for i32 {
|
||||
fn from(value: TextFilterCondition) -> Self {
|
||||
value as i32
|
||||
}
|
||||
}
|
||||
|
||||
impl std::default::Default for TextFilterCondition {
|
||||
fn default() -> Self {
|
||||
TextFilterCondition::Is
|
||||
}
|
||||
}
|
||||
impl std::convert::TryFrom<u8> for TextFilterCondition {
|
||||
type Error = ErrorCode;
|
||||
|
||||
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
0 => Ok(TextFilterCondition::Is),
|
||||
1 => Ok(TextFilterCondition::IsNot),
|
||||
2 => Ok(TextFilterCondition::Contains),
|
||||
3 => Ok(TextFilterCondition::DoesNotContain),
|
||||
4 => Ok(TextFilterCondition::StartsWith),
|
||||
5 => Ok(TextFilterCondition::EndsWith),
|
||||
6 => Ok(TextFilterCondition::TextIsEmpty),
|
||||
7 => Ok(TextFilterCondition::TextIsNotEmpty),
|
||||
_ => Err(ErrorCode::InvalidData),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<Arc<GridFilterRevision>> for GridTextFilter {
|
||||
fn from(rev: Arc<GridFilterRevision>) -> Self {
|
||||
GridTextFilter {
|
||||
condition: TextFilterCondition::try_from(rev.condition).unwrap_or(TextFilterCondition::Is),
|
||||
content: rev.content.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
|
||||
pub struct GridNumberFilter {
|
||||
#[pb(index = 1)]
|
||||
pub condition: NumberFilterCondition,
|
||||
|
||||
#[pb(index = 2, one_of)]
|
||||
pub content: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum)]
|
||||
#[repr(u8)]
|
||||
pub enum NumberFilterCondition {
|
||||
Equal = 0,
|
||||
NotEqual = 1,
|
||||
GreaterThan = 2,
|
||||
LessThan = 3,
|
||||
GreaterThanOrEqualTo = 4,
|
||||
LessThanOrEqualTo = 5,
|
||||
NumberIsEmpty = 6,
|
||||
NumberIsNotEmpty = 7,
|
||||
}
|
||||
impl std::default::Default for NumberFilterCondition {
|
||||
fn default() -> Self {
|
||||
NumberFilterCondition::Equal
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<NumberFilterCondition> for i32 {
|
||||
fn from(value: NumberFilterCondition) -> Self {
|
||||
value as i32
|
||||
}
|
||||
}
|
||||
impl std::convert::TryFrom<u8> for NumberFilterCondition {
|
||||
type Error = ErrorCode;
|
||||
|
||||
fn try_from(n: u8) -> Result<Self, Self::Error> {
|
||||
match n {
|
||||
0 => Ok(NumberFilterCondition::Equal),
|
||||
1 => Ok(NumberFilterCondition::NotEqual),
|
||||
2 => Ok(NumberFilterCondition::GreaterThan),
|
||||
3 => Ok(NumberFilterCondition::LessThan),
|
||||
4 => Ok(NumberFilterCondition::GreaterThanOrEqualTo),
|
||||
5 => Ok(NumberFilterCondition::LessThanOrEqualTo),
|
||||
6 => Ok(NumberFilterCondition::NumberIsEmpty),
|
||||
7 => Ok(NumberFilterCondition::NumberIsNotEmpty),
|
||||
_ => Err(ErrorCode::InvalidData),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<Arc<GridFilterRevision>> for GridNumberFilter {
|
||||
fn from(rev: Arc<GridFilterRevision>) -> Self {
|
||||
GridNumberFilter {
|
||||
condition: NumberFilterCondition::try_from(rev.condition).unwrap_or(NumberFilterCondition::Equal),
|
||||
content: rev.content.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
|
||||
pub struct GridSelectOptionFilter {
|
||||
#[pb(index = 1)]
|
||||
pub condition: SelectOptionCondition,
|
||||
|
||||
#[pb(index = 2, one_of)]
|
||||
pub content: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum)]
|
||||
#[repr(u8)]
|
||||
pub enum SelectOptionCondition {
|
||||
OptionIs = 0,
|
||||
OptionIsNot = 1,
|
||||
OptionIsEmpty = 2,
|
||||
OptionIsNotEmpty = 3,
|
||||
}
|
||||
|
||||
impl std::convert::From<SelectOptionCondition> for i32 {
|
||||
fn from(value: SelectOptionCondition) -> Self {
|
||||
value as i32
|
||||
}
|
||||
}
|
||||
|
||||
impl std::default::Default for SelectOptionCondition {
|
||||
fn default() -> Self {
|
||||
SelectOptionCondition::OptionIs
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::TryFrom<u8> for SelectOptionCondition {
|
||||
type Error = ErrorCode;
|
||||
|
||||
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
0 => Ok(SelectOptionCondition::OptionIs),
|
||||
1 => Ok(SelectOptionCondition::OptionIsNot),
|
||||
2 => Ok(SelectOptionCondition::OptionIsEmpty),
|
||||
3 => Ok(SelectOptionCondition::OptionIsNotEmpty),
|
||||
_ => Err(ErrorCode::InvalidData),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<Arc<GridFilterRevision>> for GridSelectOptionFilter {
|
||||
fn from(rev: Arc<GridFilterRevision>) -> Self {
|
||||
GridSelectOptionFilter {
|
||||
condition: SelectOptionCondition::try_from(rev.condition).unwrap_or(SelectOptionCondition::OptionIs),
|
||||
content: rev.content.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
|
||||
pub struct GridDateFilter {
|
||||
#[pb(index = 1)]
|
||||
pub condition: DateFilterCondition,
|
||||
|
||||
#[pb(index = 2, one_of)]
|
||||
pub content: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum)]
|
||||
#[repr(u8)]
|
||||
pub enum DateFilterCondition {
|
||||
DateIs = 0,
|
||||
DateBefore = 1,
|
||||
DateAfter = 2,
|
||||
DateOnOrBefore = 3,
|
||||
DateOnOrAfter = 4,
|
||||
DateWithIn = 5,
|
||||
DateIsEmpty = 6,
|
||||
}
|
||||
|
||||
impl std::default::Default for DateFilterCondition {
|
||||
fn default() -> Self {
|
||||
DateFilterCondition::DateIs
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::TryFrom<u8> for DateFilterCondition {
|
||||
type Error = ErrorCode;
|
||||
|
||||
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
0 => Ok(DateFilterCondition::DateIs),
|
||||
1 => Ok(DateFilterCondition::DateBefore),
|
||||
2 => Ok(DateFilterCondition::DateAfter),
|
||||
3 => Ok(DateFilterCondition::DateOnOrBefore),
|
||||
4 => Ok(DateFilterCondition::DateOnOrAfter),
|
||||
5 => Ok(DateFilterCondition::DateWithIn),
|
||||
6 => Ok(DateFilterCondition::DateIsEmpty),
|
||||
_ => Err(ErrorCode::InvalidData),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl std::convert::From<Arc<GridFilterRevision>> for GridDateFilter {
|
||||
fn from(rev: Arc<GridFilterRevision>) -> Self {
|
||||
GridDateFilter {
|
||||
condition: DateFilterCondition::try_from(rev.condition).unwrap_or(DateFilterCondition::DateIs),
|
||||
content: rev.content.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
|
||||
pub struct GridCheckboxFilter {
|
||||
#[pb(index = 1)]
|
||||
pub condition: CheckboxCondition,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum)]
|
||||
#[repr(u8)]
|
||||
pub enum CheckboxCondition {
|
||||
IsChecked = 0,
|
||||
IsUnChecked = 1,
|
||||
}
|
||||
|
||||
impl std::convert::From<CheckboxCondition> for i32 {
|
||||
fn from(value: CheckboxCondition) -> Self {
|
||||
value as i32
|
||||
}
|
||||
}
|
||||
|
||||
impl std::default::Default for CheckboxCondition {
|
||||
fn default() -> Self {
|
||||
CheckboxCondition::IsChecked
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::TryFrom<u8> for CheckboxCondition {
|
||||
type Error = ErrorCode;
|
||||
|
||||
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
0 => Ok(CheckboxCondition::IsChecked),
|
||||
1 => Ok(CheckboxCondition::IsUnChecked),
|
||||
_ => Err(ErrorCode::InvalidData),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<Arc<GridFilterRevision>> for GridCheckboxFilter {
|
||||
fn from(rev: Arc<GridFilterRevision>) -> Self {
|
||||
GridCheckboxFilter {
|
||||
condition: CheckboxCondition::try_from(rev.condition).unwrap_or(CheckboxCondition::IsChecked),
|
||||
}
|
||||
}
|
||||
}
|
106
frontend/rust-lib/flowy-grid/src/entities/grid_entities.rs
Normal file
106
frontend/rust-lib/flowy-grid/src/entities/grid_entities.rs
Normal file
@ -0,0 +1,106 @@
|
||||
use crate::entities::{FieldOrder, GridBlock};
|
||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||
use flowy_error::ErrorCode;
|
||||
use flowy_grid_data_model::parser::NotEmptyStr;
|
||||
#[derive(Debug, Clone, Default, ProtoBuf)]
|
||||
pub struct Grid {
|
||||
#[pb(index = 1)]
|
||||
pub id: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub field_orders: Vec<FieldOrder>,
|
||||
|
||||
#[pb(index = 3)]
|
||||
pub blocks: Vec<GridBlock>,
|
||||
}
|
||||
|
||||
#[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<str> 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<str> 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(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<MoveItemParams> for MoveItemPayload {
|
||||
type Error = ErrorCode;
|
||||
|
||||
fn try_into(self) -> Result<MoveItemParams, Self::Error> {
|
||||
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,
|
||||
})
|
||||
}
|
||||
}
|
75
frontend/rust-lib/flowy-grid/src/entities/group_entities.rs
Normal file
75
frontend/rust-lib/flowy-grid/src/entities/group_entities.rs
Normal file
@ -0,0 +1,75 @@
|
||||
use flowy_derive::ProtoBuf;
|
||||
use flowy_error::ErrorCode;
|
||||
use flowy_grid_data_model::parser::NotEmptyStr;
|
||||
use flowy_grid_data_model::revision::GridGroupRevision;
|
||||
use flowy_sync::entities::grid::CreateGridGroupParams;
|
||||
use std::convert::TryInto;
|
||||
|
||||
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
|
||||
pub struct GridGroup {
|
||||
#[pb(index = 1)]
|
||||
pub id: String,
|
||||
|
||||
#[pb(index = 2, one_of)]
|
||||
pub group_field_id: Option<String>,
|
||||
|
||||
#[pb(index = 3, one_of)]
|
||||
pub sub_group_field_id: Option<String>,
|
||||
}
|
||||
|
||||
impl std::convert::From<&GridGroupRevision> for GridGroup {
|
||||
fn from(rev: &GridGroupRevision) -> Self {
|
||||
GridGroup {
|
||||
id: rev.id.clone(),
|
||||
group_field_id: rev.field_id.clone(),
|
||||
sub_group_field_id: rev.sub_field_id.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
|
||||
pub struct RepeatedGridGroup {
|
||||
#[pb(index = 1)]
|
||||
pub items: Vec<GridGroup>,
|
||||
}
|
||||
|
||||
impl std::convert::From<Vec<GridGroup>> for RepeatedGridGroup {
|
||||
fn from(items: Vec<GridGroup>) -> Self {
|
||||
Self { items }
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<&Vec<GridGroupRevision>> for RepeatedGridGroup {
|
||||
fn from(revs: &Vec<GridGroupRevision>) -> Self {
|
||||
RepeatedGridGroup {
|
||||
items: revs.iter().map(|rev| rev.into()).collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
|
||||
pub struct CreateGridGroupPayload {
|
||||
#[pb(index = 1, one_of)]
|
||||
pub field_id: Option<String>,
|
||||
|
||||
#[pb(index = 2, one_of)]
|
||||
pub sub_field_id: Option<String>,
|
||||
}
|
||||
|
||||
impl TryInto<CreateGridGroupParams> for CreateGridGroupPayload {
|
||||
type Error = ErrorCode;
|
||||
|
||||
fn try_into(self) -> Result<CreateGridGroupParams, Self::Error> {
|
||||
let field_id = match self.field_id {
|
||||
None => None,
|
||||
Some(field_id) => Some(NotEmptyStr::parse(field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?.0),
|
||||
};
|
||||
|
||||
let sub_field_id = match self.sub_field_id {
|
||||
None => None,
|
||||
Some(field_id) => Some(NotEmptyStr::parse(field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?.0),
|
||||
};
|
||||
|
||||
Ok(CreateGridGroupParams { field_id, sub_field_id })
|
||||
}
|
||||
}
|
@ -1,7 +1,19 @@
|
||||
mod block_entities;
|
||||
mod cell_entities;
|
||||
mod field_entities;
|
||||
mod filter_entities;
|
||||
mod grid_entities;
|
||||
mod group_entities;
|
||||
mod row_entities;
|
||||
mod setting_entities;
|
||||
mod sort_entities;
|
||||
|
||||
pub use block_entities::*;
|
||||
pub use cell_entities::*;
|
||||
pub use field_entities::*;
|
||||
pub use filter_entities::*;
|
||||
pub use grid_entities::*;
|
||||
pub use group_entities::*;
|
||||
pub use row_entities::*;
|
||||
pub use setting_entities::*;
|
||||
pub use sort_entities::*;
|
||||
|
@ -29,3 +29,30 @@ impl TryInto<RowIdentifier> for RowIdentifierPayload {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf, Default)]
|
||||
pub struct CreateRowPayload {
|
||||
#[pb(index = 1)]
|
||||
pub grid_id: String,
|
||||
|
||||
#[pb(index = 2, one_of)]
|
||||
pub start_row_id: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct CreateRowParams {
|
||||
pub grid_id: String,
|
||||
pub start_row_id: Option<String>,
|
||||
}
|
||||
|
||||
impl TryInto<CreateRowParams> for CreateRowPayload {
|
||||
type Error = ErrorCode;
|
||||
|
||||
fn try_into(self) -> Result<CreateRowParams, Self::Error> {
|
||||
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,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
161
frontend/rust-lib/flowy-grid/src/entities/setting_entities.rs
Normal file
161
frontend/rust-lib/flowy-grid/src/entities/setting_entities.rs
Normal file
@ -0,0 +1,161 @@
|
||||
use crate::entities::{
|
||||
CreateGridFilterPayload, CreateGridGroupPayload, CreateGridSortPayload, DeleteFilterPayload, 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_sync::entities::grid::GridSettingChangesetParams;
|
||||
use std::collections::HashMap;
|
||||
use std::convert::TryInto;
|
||||
|
||||
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
|
||||
pub struct GridSetting {
|
||||
#[pb(index = 1)]
|
||||
pub filters_by_layout_ty: HashMap<String, RepeatedGridFilter>,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub groups_by_layout_ty: HashMap<String, RepeatedGridGroup>,
|
||||
|
||||
#[pb(index = 3)]
|
||||
pub sorts_by_layout_ty: HashMap<String, RepeatedGridSort>,
|
||||
}
|
||||
|
||||
//
|
||||
// impl std::convert::From<&GridSettingRevision> for GridSetting {
|
||||
// fn from(rev: &GridSettingRevision) -> Self {
|
||||
// let filters_by_layout_ty: HashMap<String, RepeatedGridFilter> = rev
|
||||
// .filters
|
||||
// .iter()
|
||||
// .map(|(layout_rev, filter_revs)| (layout_rev.to_string(), filter_revs.into()))
|
||||
// .collect();
|
||||
//
|
||||
// let groups_by_layout_ty: HashMap<String, RepeatedGridGroup> = rev
|
||||
// .groups
|
||||
// .iter()
|
||||
// .map(|(layout_rev, group_revs)| (layout_rev.to_string(), group_revs.into()))
|
||||
// .collect();
|
||||
//
|
||||
// let sorts_by_layout_ty: HashMap<String, RepeatedGridSort> = 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)]
|
||||
#[repr(u8)]
|
||||
pub enum GridLayoutType {
|
||||
Table = 0,
|
||||
Board = 1,
|
||||
}
|
||||
|
||||
impl std::default::Default for GridLayoutType {
|
||||
fn default() -> Self {
|
||||
GridLayoutType::Table
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<GridLayoutRevision> for GridLayoutType {
|
||||
fn from(rev: GridLayoutRevision) -> Self {
|
||||
match rev {
|
||||
GridLayoutRevision::Table => GridLayoutType::Table,
|
||||
GridLayoutRevision::Board => GridLayoutType::Board,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<GridLayoutType> for GridLayoutRevision {
|
||||
fn from(layout: GridLayoutType) -> Self {
|
||||
match layout {
|
||||
GridLayoutType::Table => GridLayoutRevision::Table,
|
||||
GridLayoutType::Board => GridLayoutRevision::Board,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, ProtoBuf)]
|
||||
pub struct GridSettingChangesetPayload {
|
||||
#[pb(index = 1)]
|
||||
pub grid_id: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub layout_type: GridLayoutType,
|
||||
|
||||
#[pb(index = 3, one_of)]
|
||||
pub insert_filter: Option<CreateGridFilterPayload>,
|
||||
|
||||
#[pb(index = 4, one_of)]
|
||||
pub delete_filter: Option<DeleteFilterPayload>,
|
||||
|
||||
#[pb(index = 5, one_of)]
|
||||
pub insert_group: Option<CreateGridGroupPayload>,
|
||||
|
||||
#[pb(index = 6, one_of)]
|
||||
pub delete_group: Option<String>,
|
||||
|
||||
#[pb(index = 7, one_of)]
|
||||
pub insert_sort: Option<CreateGridSortPayload>,
|
||||
|
||||
#[pb(index = 8, one_of)]
|
||||
pub delete_sort: Option<String>,
|
||||
}
|
||||
|
||||
impl TryInto<GridSettingChangesetParams> for GridSettingChangesetPayload {
|
||||
type Error = ErrorCode;
|
||||
|
||||
fn try_into(self) -> Result<GridSettingChangesetParams, Self::Error> {
|
||||
let view_id = NotEmptyStr::parse(self.grid_id)
|
||||
.map_err(|_| ErrorCode::FieldIdIsEmpty)?
|
||||
.0;
|
||||
|
||||
let insert_filter = match self.insert_filter {
|
||||
None => None,
|
||||
Some(payload) => Some(payload.try_into()?),
|
||||
};
|
||||
|
||||
let delete_filter = match self.delete_filter {
|
||||
None => None,
|
||||
Some(payload) => Some(payload.try_into()?),
|
||||
};
|
||||
|
||||
let insert_group = match self.insert_group {
|
||||
Some(payload) => Some(payload.try_into()?),
|
||||
None => None,
|
||||
};
|
||||
|
||||
let delete_group = match self.delete_group {
|
||||
None => None,
|
||||
Some(filter_id) => Some(NotEmptyStr::parse(filter_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?.0),
|
||||
};
|
||||
|
||||
let insert_sort = match self.insert_sort {
|
||||
None => None,
|
||||
Some(payload) => Some(payload.try_into()?),
|
||||
};
|
||||
|
||||
let delete_sort = match self.delete_sort {
|
||||
None => None,
|
||||
Some(filter_id) => Some(NotEmptyStr::parse(filter_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?.0),
|
||||
};
|
||||
|
||||
Ok(GridSettingChangesetParams {
|
||||
grid_id: view_id,
|
||||
layout_type: self.layout_type.into(),
|
||||
insert_filter,
|
||||
delete_filter,
|
||||
insert_group,
|
||||
delete_group,
|
||||
insert_sort,
|
||||
delete_sort,
|
||||
})
|
||||
}
|
||||
}
|
64
frontend/rust-lib/flowy-grid/src/entities/sort_entities.rs
Normal file
64
frontend/rust-lib/flowy-grid/src/entities/sort_entities.rs
Normal file
@ -0,0 +1,64 @@
|
||||
use flowy_derive::ProtoBuf;
|
||||
use flowy_error::ErrorCode;
|
||||
use flowy_grid_data_model::parser::NotEmptyStr;
|
||||
use flowy_grid_data_model::revision::GridSortRevision;
|
||||
use flowy_sync::entities::grid::CreateGridSortParams;
|
||||
use std::convert::TryInto;
|
||||
|
||||
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
|
||||
pub struct GridSort {
|
||||
#[pb(index = 1)]
|
||||
pub id: String,
|
||||
|
||||
#[pb(index = 2, one_of)]
|
||||
pub field_id: Option<String>,
|
||||
}
|
||||
|
||||
impl std::convert::From<&GridSortRevision> for GridSort {
|
||||
fn from(rev: &GridSortRevision) -> Self {
|
||||
GridSort {
|
||||
id: rev.id.clone(),
|
||||
|
||||
field_id: rev.field_id.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
|
||||
pub struct RepeatedGridSort {
|
||||
#[pb(index = 1)]
|
||||
pub items: Vec<GridSort>,
|
||||
}
|
||||
|
||||
impl std::convert::From<&Vec<GridSortRevision>> for RepeatedGridSort {
|
||||
fn from(revs: &Vec<GridSortRevision>) -> Self {
|
||||
RepeatedGridSort {
|
||||
items: revs.iter().map(|rev| rev.into()).collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<Vec<GridSort>> for RepeatedGridSort {
|
||||
fn from(items: Vec<GridSort>) -> Self {
|
||||
Self { items }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf, Debug, Default, Clone)]
|
||||
pub struct CreateGridSortPayload {
|
||||
#[pb(index = 1, one_of)]
|
||||
pub field_id: Option<String>,
|
||||
}
|
||||
|
||||
impl TryInto<CreateGridSortParams> for CreateGridSortPayload {
|
||||
type Error = ErrorCode;
|
||||
|
||||
fn try_into(self) -> Result<CreateGridSortParams, Self::Error> {
|
||||
let field_id = match self.field_id {
|
||||
None => None,
|
||||
Some(field_id) => Some(NotEmptyStr::parse(field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?.0),
|
||||
};
|
||||
|
||||
Ok(CreateGridSortParams { field_id })
|
||||
}
|
||||
}
|
@ -3,8 +3,8 @@ use crate::manager::GridManager;
|
||||
use crate::services::field::type_options::*;
|
||||
use crate::services::field::{default_type_option_builder_from_type, type_option_builder_from_json_str};
|
||||
use flowy_error::{ErrorCode, FlowyError, FlowyResult};
|
||||
use flowy_grid_data_model::entities::*;
|
||||
use flowy_grid_data_model::revision::FieldRevision;
|
||||
use flowy_sync::entities::grid::{FieldChangesetParams, GridSettingChangesetParams};
|
||||
use lib_dispatch::prelude::{data_result, AppData, Data, DataResult};
|
||||
use std::sync::Arc;
|
||||
|
||||
@ -59,7 +59,12 @@ pub(crate) async fn get_fields_handler(
|
||||
) -> DataResult<RepeatedField, FlowyError> {
|
||||
let params: QueryFieldParams = data.into_inner().try_into()?;
|
||||
let editor = manager.get_grid_editor(¶ms.grid_id)?;
|
||||
let field_orders = params.field_orders.items;
|
||||
let field_orders = params
|
||||
.field_orders
|
||||
.items
|
||||
.into_iter()
|
||||
.map(|field_order| field_order.field_id)
|
||||
.collect();
|
||||
let field_revs = editor.get_field_revs(Some(field_orders)).await?;
|
||||
let repeated_field: RepeatedField = field_revs.into_iter().map(Field::from).collect::<Vec<_>>().into();
|
||||
data_result(repeated_field)
|
||||
@ -160,7 +165,8 @@ pub(crate) async fn get_field_type_option_data_handler(
|
||||
match editor.get_field_rev(¶ms.field_id).await {
|
||||
None => Err(FlowyError::record_not_found()),
|
||||
Some(field_rev) => {
|
||||
let type_option_data = get_type_option_data(&field_rev, &field_rev.field_type).await?;
|
||||
let field_type = field_rev.field_type_rev.into();
|
||||
let type_option_data = get_type_option_data(&field_rev, &field_type).await?;
|
||||
let data = FieldTypeOptionData {
|
||||
grid_id: params.grid_id,
|
||||
field: field_rev.into(),
|
||||
@ -180,7 +186,8 @@ pub(crate) async fn create_field_type_option_data_handler(
|
||||
let params: CreateFieldParams = data.into_inner().try_into()?;
|
||||
let editor = manager.get_grid_editor(¶ms.grid_id)?;
|
||||
let field_rev = editor.create_next_field_rev(¶ms.field_type).await?;
|
||||
let type_option_data = get_type_option_data(&field_rev, &field_rev.field_type).await?;
|
||||
let field_type: FieldType = field_rev.field_type_rev.into();
|
||||
let type_option_data = get_type_option_data(&field_rev, &field_type).await?;
|
||||
|
||||
data_result(FieldTypeOptionData {
|
||||
grid_id: params.grid_id,
|
||||
@ -205,7 +212,8 @@ async fn get_type_option_data(field_rev: &FieldRevision, field_type: &FieldType)
|
||||
let s = field_rev
|
||||
.get_type_option_str(field_type)
|
||||
.unwrap_or_else(|| default_type_option_builder_from_type(field_type).entry().json_str());
|
||||
let builder = type_option_builder_from_json_str(&s, &field_rev.field_type);
|
||||
let field_type: FieldType = field_rev.field_type_rev.into();
|
||||
let builder = type_option_builder_from_json_str(&s, &field_type);
|
||||
let type_option_data = builder.entry().protobuf_bytes().to_vec();
|
||||
|
||||
Ok(type_option_data)
|
||||
|
@ -30,7 +30,7 @@ macro_rules! impl_type_option {
|
||||
($target: ident, $field_type:expr) => {
|
||||
impl std::convert::From<&FieldRevision> for $target {
|
||||
fn from(field_rev: &FieldRevision) -> $target {
|
||||
match field_rev.get_type_option_entry::<$target>(&$field_type) {
|
||||
match field_rev.get_type_option_entry::<$target, _>(&$field_type) {
|
||||
None => $target::default(),
|
||||
Some(target) => target,
|
||||
}
|
||||
@ -39,7 +39,7 @@ macro_rules! impl_type_option {
|
||||
|
||||
impl std::convert::From<&std::sync::Arc<FieldRevision>> for $target {
|
||||
fn from(field_rev: &std::sync::Arc<FieldRevision>) -> $target {
|
||||
match field_rev.get_type_option_entry::<$target>(&$field_type) {
|
||||
match field_rev.get_type_option_entry::<$target, _>(&$field_type) {
|
||||
None => $target::default(),
|
||||
Some(target) => target,
|
||||
}
|
||||
@ -53,10 +53,6 @@ macro_rules! impl_type_option {
|
||||
}
|
||||
|
||||
impl TypeOptionDataEntry for $target {
|
||||
fn field_type(&self) -> FieldType {
|
||||
$field_type
|
||||
}
|
||||
|
||||
fn json_str(&self) -> String {
|
||||
match serde_json::to_string(&self) {
|
||||
Ok(s) => s,
|
||||
|
@ -1,13 +1,11 @@
|
||||
use crate::dart_notification::{send_dart_notification, GridNotification};
|
||||
use crate::entities::{CellChangeset, GridRowsChangeset, IndexRowOrder, Row, RowOrder, UpdatedRowOrder};
|
||||
use crate::manager::GridUser;
|
||||
use crate::services::block_revision_editor::GridBlockRevisionEditor;
|
||||
use crate::services::persistence::block_index::BlockIndexCache;
|
||||
use crate::services::row::{block_from_row_orders, GridBlockSnapshot};
|
||||
use dashmap::DashMap;
|
||||
use flowy_error::FlowyResult;
|
||||
use flowy_grid_data_model::entities::{
|
||||
CellChangeset, GridRowsChangeset, IndexRowOrder, Row, RowOrder, UpdatedRowOrder,
|
||||
};
|
||||
use flowy_grid_data_model::revision::{
|
||||
GridBlockMetaRevision, GridBlockMetaRevisionChangeset, RowMetaChangeset, RowRevision,
|
||||
};
|
||||
|
@ -1,6 +1,5 @@
|
||||
use bytes::Bytes;
|
||||
use flowy_error::{FlowyError, FlowyResult};
|
||||
use flowy_grid_data_model::entities::RowOrder;
|
||||
use flowy_grid_data_model::revision::{CellRevision, GridBlockRevision, RowMetaChangeset, RowRevision};
|
||||
use flowy_revision::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder};
|
||||
use flowy_sync::client_grid::{GridBlockMetaChange, GridBlockRevisionPad};
|
||||
@ -11,6 +10,7 @@ use lib_ot::core::PlainTextAttributes;
|
||||
use std::borrow::Cow;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::RwLock;
|
||||
use crate::entities::RowOrder;
|
||||
|
||||
pub struct GridBlockRevisionEditor {
|
||||
user_id: String,
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::entities::{Field, FieldType};
|
||||
use crate::services::field::type_options::*;
|
||||
use bytes::Bytes;
|
||||
use flowy_grid_data_model::entities::{Field, FieldType};
|
||||
use flowy_grid_data_model::revision::{FieldRevision, TypeOptionDataEntry};
|
||||
use indexmap::IndexMap;
|
||||
|
||||
@ -14,7 +14,9 @@ pub type BoxTypeOptionBuilder = Box<dyn TypeOptionBuilder + 'static>;
|
||||
impl FieldBuilder {
|
||||
pub fn new<T: Into<BoxTypeOptionBuilder>>(type_option_builder: T) -> Self {
|
||||
let type_option_builder = type_option_builder.into();
|
||||
let field_rev = FieldRevision::new("", "", type_option_builder.field_type(), false);
|
||||
let field_type = type_option_builder.field_type();
|
||||
let width = field_type.default_cell_width();
|
||||
let field_rev = FieldRevision::new("", "", field_type, width, false);
|
||||
Self {
|
||||
field_rev,
|
||||
type_option_builder,
|
||||
@ -31,7 +33,7 @@ impl FieldBuilder {
|
||||
id: field.id,
|
||||
name: field.name,
|
||||
desc: field.desc,
|
||||
field_type: field.field_type,
|
||||
field_type_rev: field.field_type.into(),
|
||||
frozen: field.frozen,
|
||||
visibility: field.visibility,
|
||||
width: field.width,
|
||||
@ -75,7 +77,6 @@ impl FieldBuilder {
|
||||
}
|
||||
|
||||
pub fn build(self) -> FieldRevision {
|
||||
debug_assert_eq!(self.field_rev.field_type, self.type_option_builder.field_type());
|
||||
let mut field_rev = self.field_rev;
|
||||
field_rev.insert_type_option_entry(self.type_option_builder.entry());
|
||||
field_rev
|
||||
|
@ -1,10 +1,10 @@
|
||||
use crate::entities::{FieldType, GridCheckboxFilter};
|
||||
use crate::impl_type_option;
|
||||
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
|
||||
use crate::services::row::{CellContentChangeset, CellDataOperation, DecodedCellData};
|
||||
use bytes::Bytes;
|
||||
use flowy_derive::ProtoBuf;
|
||||
use flowy_error::{FlowyError, FlowyResult};
|
||||
use flowy_grid_data_model::entities::{FieldType, GridCheckboxFilter};
|
||||
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@ -22,7 +22,7 @@ impl CheckboxTypeOptionBuilder {
|
||||
|
||||
impl TypeOptionBuilder for CheckboxTypeOptionBuilder {
|
||||
fn field_type(&self) -> FieldType {
|
||||
self.0.field_type()
|
||||
FieldType::Checkbox
|
||||
}
|
||||
|
||||
fn entry(&self) -> &dyn TypeOptionDataEntry {
|
||||
@ -99,7 +99,7 @@ mod tests {
|
||||
use crate::services::field::FieldBuilder;
|
||||
use crate::services::row::{apply_cell_data_changeset, decode_cell_data};
|
||||
|
||||
use flowy_grid_data_model::entities::FieldType;
|
||||
use crate::entities::FieldType;
|
||||
|
||||
#[test]
|
||||
fn checkout_box_description_test() {
|
||||
|
@ -1,3 +1,4 @@
|
||||
use crate::entities::{CellChangeset, FieldType, GridDateFilter};
|
||||
use crate::entities::{CellIdentifier, CellIdentifierPayload};
|
||||
use crate::impl_type_option;
|
||||
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
|
||||
@ -7,7 +8,6 @@ use chrono::format::strftime::StrftimeItems;
|
||||
use chrono::{NaiveDateTime, Timelike};
|
||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||
use flowy_error::{ErrorCode, FlowyError, FlowyResult};
|
||||
use flowy_grid_data_model::entities::{CellChangeset, FieldType, GridDateFilter};
|
||||
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use strum_macros::EnumIter;
|
||||
@ -181,7 +181,7 @@ impl DateTypeOptionBuilder {
|
||||
}
|
||||
impl TypeOptionBuilder for DateTypeOptionBuilder {
|
||||
fn field_type(&self) -> FieldType {
|
||||
self.0.field_type()
|
||||
FieldType::DateTime
|
||||
}
|
||||
|
||||
fn entry(&self) -> &dyn TypeOptionDataEntry {
|
||||
@ -358,11 +358,11 @@ impl std::convert::From<DateCellContentChangeset> for CellContentChangeset {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::entities::FieldType;
|
||||
use crate::services::field::FieldBuilder;
|
||||
use crate::services::field::{DateCellContentChangeset, DateCellData, DateFormat, DateTypeOption, TimeFormat};
|
||||
use crate::services::row::CellDataOperation;
|
||||
use flowy_grid_data_model::entities::FieldType;
|
||||
use flowy_grid_data_model::revision::{FieldRevision, TypeOptionDataEntry};
|
||||
use flowy_grid_data_model::revision::FieldRevision;
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
#[test]
|
||||
@ -534,7 +534,7 @@ mod tests {
|
||||
fn date_type_option_apply_changeset_error_test() {
|
||||
let mut type_option = DateTypeOption::new();
|
||||
type_option.include_time = true;
|
||||
let field_rev = FieldBuilder::from_field_type(&type_option.field_type()).build();
|
||||
let field_rev = FieldBuilder::from_field_type(&FieldType::DateTime).build();
|
||||
let date_timestamp = "1653609600".to_owned();
|
||||
|
||||
assert_changeset_result(
|
||||
@ -543,7 +543,7 @@ mod tests {
|
||||
date: Some(date_timestamp.clone()),
|
||||
time: Some("1:".to_owned()),
|
||||
},
|
||||
&type_option.field_type(),
|
||||
&FieldType::DateTime,
|
||||
&field_rev,
|
||||
"May 27,2022 01:00",
|
||||
);
|
||||
@ -554,7 +554,7 @@ mod tests {
|
||||
date: Some(date_timestamp),
|
||||
time: Some("1:00".to_owned()),
|
||||
},
|
||||
&type_option.field_type(),
|
||||
&FieldType::DateTime,
|
||||
&field_rev,
|
||||
"May 27,2022 01:00",
|
||||
);
|
||||
@ -565,7 +565,7 @@ mod tests {
|
||||
fn date_type_option_twelve_hours_to_twenty_four_hours() {
|
||||
let mut type_option = DateTypeOption::new();
|
||||
type_option.include_time = true;
|
||||
let field_rev = FieldBuilder::from_field_type(&type_option.field_type()).build();
|
||||
let field_rev = FieldBuilder::from_field_type(&FieldType::DateTime).build();
|
||||
let date_timestamp = "1653609600".to_owned();
|
||||
|
||||
assert_changeset_result(
|
||||
@ -574,7 +574,7 @@ mod tests {
|
||||
date: Some(date_timestamp),
|
||||
time: Some("1:00 am".to_owned()),
|
||||
},
|
||||
&type_option.field_type(),
|
||||
&FieldType::DateTime,
|
||||
&field_rev,
|
||||
"May 27,2022 01:00",
|
||||
);
|
||||
|
@ -15,7 +15,7 @@ lazy_static! {
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, EnumIter, Serialize, Deserialize, ProtoBuf_Enum)]
|
||||
pub enum NumberFormat {
|
||||
Number = 0,
|
||||
Num = 0,
|
||||
USD = 1,
|
||||
CanadianDollar = 2,
|
||||
EUR = 4,
|
||||
@ -55,7 +55,7 @@ pub enum NumberFormat {
|
||||
|
||||
impl std::default::Default for NumberFormat {
|
||||
fn default() -> Self {
|
||||
NumberFormat::Number
|
||||
NumberFormat::Num
|
||||
}
|
||||
}
|
||||
|
||||
@ -400,7 +400,7 @@ define_currency_set!(
|
||||
impl NumberFormat {
|
||||
pub fn currency(&self) -> &'static number_currency::Currency {
|
||||
match self {
|
||||
NumberFormat::Number => number_currency::NUMBER,
|
||||
NumberFormat::Num => number_currency::NUMBER,
|
||||
NumberFormat::USD => number_currency::USD,
|
||||
NumberFormat::CanadianDollar => number_currency::CANADIAN_DOLLAR,
|
||||
NumberFormat::EUR => number_currency::EUR,
|
||||
|
@ -1,12 +1,12 @@
|
||||
use crate::impl_type_option;
|
||||
|
||||
use crate::entities::{FieldType, GridNumberFilter};
|
||||
use crate::services::field::type_options::number_type_option::format::*;
|
||||
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
|
||||
use crate::services::row::{CellContentChangeset, CellDataOperation, DecodedCellData};
|
||||
use bytes::Bytes;
|
||||
use flowy_derive::ProtoBuf;
|
||||
use flowy_error::{FlowyError, FlowyResult};
|
||||
use flowy_grid_data_model::entities::{FieldType, GridNumberFilter};
|
||||
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry};
|
||||
use rust_decimal::Decimal;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -41,7 +41,7 @@ impl NumberTypeOptionBuilder {
|
||||
|
||||
impl TypeOptionBuilder for NumberTypeOptionBuilder {
|
||||
fn field_type(&self) -> FieldType {
|
||||
self.0.field_type()
|
||||
FieldType::Number
|
||||
}
|
||||
|
||||
fn entry(&self) -> &dyn TypeOptionDataEntry {
|
||||
@ -76,7 +76,7 @@ impl NumberTypeOption {
|
||||
|
||||
fn cell_content_from_number_str(&self, s: &str) -> FlowyResult<String> {
|
||||
match self.format {
|
||||
NumberFormat::Number => {
|
||||
NumberFormat::Num => {
|
||||
if let Ok(v) = s.parse::<f64>() {
|
||||
return Ok(v.to_string());
|
||||
}
|
||||
@ -155,7 +155,7 @@ impl CellDataOperation<String, GridNumberFilter> for NumberTypeOption {
|
||||
|
||||
let cell_data = encoded_data.into();
|
||||
match self.format {
|
||||
NumberFormat::Number => {
|
||||
NumberFormat::Num => {
|
||||
if let Ok(v) = cell_data.parse::<f64>() {
|
||||
return Ok(DecodedCellData::new(v.to_string()));
|
||||
}
|
||||
@ -210,10 +210,10 @@ impl std::default::Default for NumberTypeOption {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::entities::FieldType;
|
||||
use crate::services::field::FieldBuilder;
|
||||
use crate::services::field::{NumberFormat, NumberTypeOption};
|
||||
use crate::services::row::CellDataOperation;
|
||||
use flowy_grid_data_model::entities::FieldType;
|
||||
use flowy_grid_data_model::revision::FieldRevision;
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
@ -245,7 +245,7 @@ mod tests {
|
||||
for format in NumberFormat::iter() {
|
||||
type_option.format = format;
|
||||
match format {
|
||||
NumberFormat::Number => {
|
||||
NumberFormat::Num => {
|
||||
assert_equal(&type_option, "18443", "18443", &field_type, &field_rev);
|
||||
}
|
||||
NumberFormat::USD => {
|
||||
@ -274,7 +274,7 @@ mod tests {
|
||||
for format in NumberFormat::iter() {
|
||||
type_option.format = format;
|
||||
match format {
|
||||
NumberFormat::Number => {
|
||||
NumberFormat::Num => {
|
||||
assert_equal(&type_option, "18443", "18443", &field_type, &field_rev);
|
||||
assert_equal(&type_option, "0.2", "0.2", &field_type, &field_rev);
|
||||
}
|
||||
@ -314,7 +314,7 @@ mod tests {
|
||||
for format in NumberFormat::iter() {
|
||||
type_option.format = format;
|
||||
match format {
|
||||
NumberFormat::Number => {
|
||||
NumberFormat::Num => {
|
||||
assert_equal(&type_option, "18443", "18443", &field_type, &field_rev);
|
||||
}
|
||||
NumberFormat::USD => {
|
||||
|
@ -1,3 +1,4 @@
|
||||
use crate::entities::{CellChangeset, FieldType, GridSelectOptionFilter};
|
||||
use crate::entities::{CellIdentifier, CellIdentifierPayload};
|
||||
use crate::impl_type_option;
|
||||
use crate::services::field::type_options::util::get_cell_data;
|
||||
@ -6,7 +7,6 @@ use crate::services::row::{CellContentChangeset, CellDataOperation, DecodedCellD
|
||||
use bytes::Bytes;
|
||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||
use flowy_error::{ErrorCode, FlowyError, FlowyResult};
|
||||
use flowy_grid_data_model::entities::{CellChangeset, FieldType, GridSelectOptionFilter};
|
||||
use flowy_grid_data_model::parser::NotEmptyStr;
|
||||
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry};
|
||||
use nanoid::nanoid;
|
||||
@ -49,7 +49,8 @@ pub trait SelectOptionOperation: TypeOptionDataEntry + Send + Sync {
|
||||
}
|
||||
|
||||
pub fn select_option_operation(field_rev: &FieldRevision) -> FlowyResult<Box<dyn SelectOptionOperation>> {
|
||||
match &field_rev.field_type {
|
||||
let field_type: FieldType = field_rev.field_type_rev.into();
|
||||
match &field_type {
|
||||
FieldType::SingleSelect => {
|
||||
let type_option = SingleSelectTypeOption::from(field_rev);
|
||||
Ok(Box::new(type_option))
|
||||
@ -159,7 +160,7 @@ impl SingleSelectTypeOptionBuilder {
|
||||
|
||||
impl TypeOptionBuilder for SingleSelectTypeOptionBuilder {
|
||||
fn field_type(&self) -> FieldType {
|
||||
self.0.field_type()
|
||||
FieldType::SingleSelect
|
||||
}
|
||||
|
||||
fn entry(&self) -> &dyn TypeOptionDataEntry {
|
||||
@ -277,7 +278,7 @@ impl MultiSelectTypeOptionBuilder {
|
||||
|
||||
impl TypeOptionBuilder for MultiSelectTypeOptionBuilder {
|
||||
fn field_type(&self) -> FieldType {
|
||||
self.0.field_type()
|
||||
FieldType::MultiSelect
|
||||
}
|
||||
|
||||
fn entry(&self) -> &dyn TypeOptionDataEntry {
|
||||
@ -510,6 +511,7 @@ fn make_select_context_from(cell_rev: &Option<CellRevision>, options: &[SelectOp
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::entities::FieldType;
|
||||
use crate::services::field::FieldBuilder;
|
||||
use crate::services::field::{
|
||||
MultiSelectTypeOption, MultiSelectTypeOptionBuilder, SelectOption, SelectOptionCellContentChangeset,
|
||||
@ -614,10 +616,11 @@ mod tests {
|
||||
field_rev: &FieldRevision,
|
||||
expected: Vec<SelectOption>,
|
||||
) {
|
||||
let field_type: FieldType = field_rev.field_type_rev.into();
|
||||
assert_eq!(
|
||||
expected,
|
||||
type_option
|
||||
.decode_cell_data(cell_data, &field_rev.field_type, field_rev)
|
||||
.decode_cell_data(cell_data, &field_type, field_rev)
|
||||
.unwrap()
|
||||
.parse::<SelectOptionCellData>()
|
||||
.unwrap()
|
||||
@ -631,10 +634,11 @@ mod tests {
|
||||
field_rev: &FieldRevision,
|
||||
expected: Vec<SelectOption>,
|
||||
) {
|
||||
let field_type: FieldType = field_rev.field_type_rev.into();
|
||||
assert_eq!(
|
||||
expected,
|
||||
type_option
|
||||
.decode_cell_data(cell_data, &field_rev.field_type, field_rev)
|
||||
.decode_cell_data(cell_data, &field_type, field_rev)
|
||||
.unwrap()
|
||||
.parse::<SelectOptionCellData>()
|
||||
.unwrap()
|
||||
|
@ -1,10 +1,10 @@
|
||||
use crate::entities::{FieldType, GridTextFilter};
|
||||
use crate::impl_type_option;
|
||||
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
|
||||
use crate::services::row::{try_decode_cell_data, CellContentChangeset, CellDataOperation, DecodedCellData};
|
||||
use bytes::Bytes;
|
||||
use flowy_derive::ProtoBuf;
|
||||
use flowy_error::{FlowyError, FlowyResult};
|
||||
use flowy_grid_data_model::entities::{FieldType, GridTextFilter};
|
||||
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@ -15,7 +15,7 @@ impl_builder_from_json_str_and_from_bytes!(RichTextTypeOptionBuilder, RichTextTy
|
||||
|
||||
impl TypeOptionBuilder for RichTextTypeOptionBuilder {
|
||||
fn field_type(&self) -> FieldType {
|
||||
self.0.field_type()
|
||||
FieldType::RichText
|
||||
}
|
||||
|
||||
fn entry(&self) -> &dyn TypeOptionDataEntry {
|
||||
@ -71,10 +71,10 @@ impl CellDataOperation<String, GridTextFilter> for RichTextTypeOption {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::entities::FieldType;
|
||||
use crate::services::field::FieldBuilder;
|
||||
use crate::services::field::*;
|
||||
use crate::services::row::CellDataOperation;
|
||||
use flowy_grid_data_model::entities::FieldType;
|
||||
|
||||
#[test]
|
||||
fn text_description_test() {
|
||||
|
@ -1,3 +1,4 @@
|
||||
use crate::entities::{FieldType, GridTextFilter};
|
||||
use crate::impl_type_option;
|
||||
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
|
||||
use crate::services::row::{CellContentChangeset, CellDataOperation, DecodedCellData, EncodedCellData};
|
||||
@ -5,7 +6,6 @@ use bytes::Bytes;
|
||||
use fancy_regex::Regex;
|
||||
use flowy_derive::ProtoBuf;
|
||||
use flowy_error::{internal_error, FlowyError, FlowyResult};
|
||||
use flowy_grid_data_model::entities::{FieldType, GridTextFilter};
|
||||
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry};
|
||||
use lazy_static::lazy_static;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -18,7 +18,7 @@ impl_builder_from_json_str_and_from_bytes!(URLTypeOptionBuilder, URLTypeOption);
|
||||
|
||||
impl TypeOptionBuilder for URLTypeOptionBuilder {
|
||||
fn field_type(&self) -> FieldType {
|
||||
self.0.field_type()
|
||||
FieldType::URL
|
||||
}
|
||||
|
||||
fn entry(&self) -> &dyn TypeOptionDataEntry {
|
||||
@ -126,10 +126,10 @@ lazy_static! {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::entities::FieldType;
|
||||
use crate::services::field::FieldBuilder;
|
||||
use crate::services::field::{URLCellData, URLTypeOption};
|
||||
use crate::services::row::{CellDataOperation, EncodedCellData};
|
||||
use flowy_grid_data_model::entities::FieldType;
|
||||
use flowy_grid_data_model::revision::FieldRevision;
|
||||
|
||||
#[test]
|
||||
|
@ -1,24 +1,25 @@
|
||||
use crate::entities::{
|
||||
FieldType, GridCheckboxFilter, GridDateFilter, GridNumberFilter, GridSelectOptionFilter, GridTextFilter,
|
||||
};
|
||||
use crate::services::block_manager::GridBlockManager;
|
||||
use crate::services::grid_editor_task::GridServiceTaskScheduler;
|
||||
use crate::services::row::GridBlockSnapshot;
|
||||
use crate::services::tasks::{FilterTaskContext, Task, TaskContent};
|
||||
use flowy_error::FlowyResult;
|
||||
use flowy_grid_data_model::entities::{
|
||||
FieldType, GridCheckboxFilter, GridDateFilter, GridNumberFilter, GridSelectOptionFilter,
|
||||
GridSettingChangesetParams, GridTextFilter,
|
||||
};
|
||||
use flowy_grid_data_model::revision::{FieldRevision, RowRevision};
|
||||
use flowy_grid_data_model::revision::{CellRevision, FieldId, FieldRevision, RowRevision};
|
||||
use flowy_sync::client_grid::GridRevisionPad;
|
||||
use flowy_sync::entities::grid::GridSettingChangesetParams;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
pub(crate) struct GridFilterService {
|
||||
grid_id: String,
|
||||
scheduler: Arc<dyn GridServiceTaskScheduler>,
|
||||
grid_pad: Arc<RwLock<GridRevisionPad>>,
|
||||
block_manager: Arc<GridBlockManager>,
|
||||
filter_cache: Arc<RwLock<FilterCache>>,
|
||||
filter_result: Arc<RwLock<GridFilterResult>>,
|
||||
filter_result_cache: Arc<RwLock<FilterResultCache>>,
|
||||
}
|
||||
impl GridFilterService {
|
||||
pub async fn new<S: GridServiceTaskScheduler>(
|
||||
@ -26,26 +27,38 @@ impl GridFilterService {
|
||||
block_manager: Arc<GridBlockManager>,
|
||||
scheduler: S,
|
||||
) -> Self {
|
||||
let grid_id = grid_pad.read().await.grid_id();
|
||||
let filter_cache = Arc::new(RwLock::new(FilterCache::from_grid_pad(&grid_pad).await));
|
||||
let filter_result = Arc::new(RwLock::new(GridFilterResult::default()));
|
||||
let filter_result_cache = Arc::new(RwLock::new(FilterResultCache::default()));
|
||||
Self {
|
||||
grid_id,
|
||||
grid_pad,
|
||||
block_manager,
|
||||
scheduler: Arc::new(scheduler),
|
||||
filter_cache,
|
||||
filter_result,
|
||||
filter_result_cache,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn process(&self, task_context: FilterTaskContext) -> FlowyResult<()> {
|
||||
let mut filter_result = self.filter_result.write().await;
|
||||
for block in task_context.blocks {
|
||||
for row_rev in block.row_revs {
|
||||
let row_filter_result = RowFilterResult::new(&row_rev);
|
||||
let field_revs = self
|
||||
.grid_pad
|
||||
.read()
|
||||
.await
|
||||
.get_field_revs(None)?
|
||||
.into_iter()
|
||||
.map(|field_rev| (field_rev.id.clone(), field_rev))
|
||||
.collect::<HashMap<String, Arc<FieldRevision>>>();
|
||||
|
||||
filter_result.insert(&row_rev.id, row_filter_result);
|
||||
}
|
||||
let mut changes = vec![];
|
||||
for block in task_context.blocks {
|
||||
block.row_revs.iter().for_each(|row_rev| {
|
||||
if let Some(change) = filter_row(row_rev, &self.filter_cache, &self.filter_result_cache, &field_revs) {
|
||||
changes.push(change);
|
||||
}
|
||||
});
|
||||
}
|
||||
self.notify(changes).await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -86,7 +99,28 @@ impl GridFilterService {
|
||||
|
||||
task
|
||||
}
|
||||
|
||||
async fn notify(&self, _changes: Vec<FilterResult>) {
|
||||
// let notification = GridNotification {};
|
||||
// send_dart_notification(grid_id, GridNotification::DidUpdateGrid)
|
||||
// .payload(updated_field)
|
||||
// .send();
|
||||
}
|
||||
}
|
||||
|
||||
fn filter_row(
|
||||
row_rev: &Arc<RowRevision>,
|
||||
_filter_cache: &Arc<RwLock<FilterCache>>,
|
||||
_filter_result_cache: &Arc<RwLock<FilterResultCache>>,
|
||||
_field_revs: &HashMap<FieldId, Arc<FieldRevision>>,
|
||||
) -> Option<FilterResult> {
|
||||
let _filter_result = FilterResult::new(row_rev);
|
||||
row_rev.cells.iter().for_each(|(_k, cell_rev)| {
|
||||
let _cell_rev: &CellRevision = cell_rev;
|
||||
});
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub struct GridFilterChangeset {
|
||||
insert_filter: Option<FilterId>,
|
||||
delete_filter: Option<FilterId>,
|
||||
@ -102,12 +136,12 @@ impl std::convert::From<&GridSettingChangesetParams> for GridFilterChangeset {
|
||||
fn from(params: &GridSettingChangesetParams) -> Self {
|
||||
let insert_filter = params.insert_filter.as_ref().map(|insert_filter_params| FilterId {
|
||||
field_id: insert_filter_params.field_id.clone(),
|
||||
field_type: insert_filter_params.field_type.clone(),
|
||||
field_type: insert_filter_params.field_type_rev.into(),
|
||||
});
|
||||
|
||||
let delete_filter = params.delete_filter.as_ref().map(|delete_filter_params| FilterId {
|
||||
field_id: delete_filter_params.filter_id.clone(),
|
||||
field_type: delete_filter_params.field_type.clone(),
|
||||
field_type: delete_filter_params.field_type_rev.into(),
|
||||
});
|
||||
GridFilterChangeset {
|
||||
insert_filter,
|
||||
@ -117,24 +151,26 @@ impl std::convert::From<&GridSettingChangesetParams> for GridFilterChangeset {
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct GridFilterResult {
|
||||
rows: HashMap<String, RowFilterResult>,
|
||||
struct FilterResultCache {
|
||||
rows: HashMap<String, FilterResult>,
|
||||
}
|
||||
|
||||
impl GridFilterResult {
|
||||
fn insert(&mut self, row_id: &str, result: RowFilterResult) {
|
||||
impl FilterResultCache {
|
||||
fn insert(&mut self, row_id: &str, result: FilterResult) {
|
||||
self.rows.insert(row_id.to_owned(), result);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct RowFilterResult {
|
||||
struct FilterResult {
|
||||
row_id: String,
|
||||
cell_by_field_id: HashMap<String, bool>,
|
||||
}
|
||||
|
||||
impl RowFilterResult {
|
||||
impl FilterResult {
|
||||
fn new(row_rev: &RowRevision) -> Self {
|
||||
Self {
|
||||
row_id: row_rev.id.clone(),
|
||||
cell_by_field_id: row_rev.cells.iter().map(|(k, _)| (k.clone(), true)).collect(),
|
||||
}
|
||||
}
|
||||
@ -201,7 +237,8 @@ async fn reload_filter_cache(
|
||||
None => {}
|
||||
Some((_, field_rev)) => {
|
||||
let filter_id = FilterId::from(field_rev);
|
||||
match &field_rev.field_type {
|
||||
let field_type: FieldType = field_rev.field_type_rev.into();
|
||||
match &field_type {
|
||||
FieldType::RichText => {
|
||||
let _ = cache.text_filter.insert(filter_id, GridTextFilter::from(filter_rev));
|
||||
}
|
||||
@ -241,7 +278,7 @@ impl std::convert::From<&Arc<FieldRevision>> for FilterId {
|
||||
fn from(rev: &Arc<FieldRevision>) -> Self {
|
||||
Self {
|
||||
field_id: rev.id.clone(),
|
||||
field_type: rev.field_type.clone(),
|
||||
field_type: rev.field_type_rev.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,12 +7,13 @@ use crate::services::filter::{GridFilterChangeset, GridFilterService};
|
||||
use crate::services::persistence::block_index::BlockIndexCache;
|
||||
use crate::services::row::*;
|
||||
|
||||
use crate::entities::*;
|
||||
use bytes::Bytes;
|
||||
use flowy_error::{ErrorCode, FlowyError, FlowyResult};
|
||||
use flowy_grid_data_model::entities::*;
|
||||
use flowy_grid_data_model::revision::*;
|
||||
use flowy_revision::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder};
|
||||
use flowy_sync::client_grid::{GridChangeset, GridRevisionPad, JsonDeserializer};
|
||||
use flowy_sync::entities::grid::{FieldChangesetParams, GridSettingChangesetParams};
|
||||
use flowy_sync::entities::revision::Revision;
|
||||
use flowy_sync::errors::CollaborateResult;
|
||||
use flowy_sync::util::make_delta_from_revisions;
|
||||
@ -84,7 +85,7 @@ impl GridRevisionEditor {
|
||||
grid_id,
|
||||
name: Some(field.name),
|
||||
desc: Some(field.desc),
|
||||
field_type: Some(field.field_type),
|
||||
field_type: Some(field.field_type.into()),
|
||||
frozen: Some(field.frozen),
|
||||
visibility: Some(field.visibility),
|
||||
width: Some(field.width),
|
||||
@ -123,7 +124,8 @@ impl GridRevisionEditor {
|
||||
let field_rev = result.unwrap();
|
||||
let _ = self
|
||||
.modify(|grid| {
|
||||
let deserializer = TypeOptionJsonDeserializer(field_rev.field_type.clone());
|
||||
let field_type = field_rev.field_type_rev.into();
|
||||
let deserializer = TypeOptionJsonDeserializer(field_type);
|
||||
let changeset = FieldChangesetParams {
|
||||
field_id: field_id.to_owned(),
|
||||
grid_id: grid_id.to_owned(),
|
||||
@ -161,7 +163,7 @@ impl GridRevisionEditor {
|
||||
let field_id = params.field_id.clone();
|
||||
let json_deserializer = match self.grid_pad.read().await.get_field_rev(params.field_id.as_str()) {
|
||||
None => return Err(ErrorCode::FieldDoesNotExist.into()),
|
||||
Some((_, field_rev)) => TypeOptionJsonDeserializer(field_rev.field_type.clone()),
|
||||
Some((_, field_rev)) => TypeOptionJsonDeserializer(field_rev.field_type_rev.into()),
|
||||
};
|
||||
|
||||
let _ = self
|
||||
@ -201,8 +203,9 @@ impl GridRevisionEditor {
|
||||
// .get_cell_revs(block_ids, field_id, None)
|
||||
// .await?;
|
||||
|
||||
let type_option_json_builder = |field_type: &FieldType| -> String {
|
||||
return default_type_option_builder_from_type(field_type).entry().json_str();
|
||||
let type_option_json_builder = |field_type: &FieldTypeRevision| -> String {
|
||||
let field_type: FieldType = field_type.into();
|
||||
return default_type_option_builder_from_type(&field_type).entry().json_str();
|
||||
};
|
||||
|
||||
let _ = self
|
||||
@ -229,19 +232,15 @@ impl GridRevisionEditor {
|
||||
Some(field_rev)
|
||||
}
|
||||
|
||||
pub async fn get_field_revs<T>(&self, field_ids: Option<Vec<T>>) -> FlowyResult<Vec<Arc<FieldRevision>>>
|
||||
where
|
||||
T: Into<FieldOrder>,
|
||||
{
|
||||
pub async fn get_field_revs(&self, field_ids: Option<Vec<String>>) -> FlowyResult<Vec<Arc<FieldRevision>>> {
|
||||
if field_ids.is_none() {
|
||||
let field_revs = self.grid_pad.read().await.get_field_revs(None)?;
|
||||
return Ok(field_revs);
|
||||
}
|
||||
|
||||
let to_field_orders = |item: Vec<T>| item.into_iter().map(|data| data.into()).collect();
|
||||
let field_orders = field_ids.map_or(vec![], to_field_orders);
|
||||
let expected_len = field_orders.len();
|
||||
let field_revs = self.grid_pad.read().await.get_field_revs(Some(field_orders))?;
|
||||
let field_ids = field_ids.unwrap_or_default();
|
||||
let expected_len = field_ids.len();
|
||||
let field_revs = self.grid_pad.read().await.get_field_revs(Some(field_ids))?;
|
||||
if expected_len != 0 && field_revs.len() != expected_len {
|
||||
tracing::error!(
|
||||
"This is a bug. The len of the field_revs should equal to {}",
|
||||
@ -304,7 +303,7 @@ impl GridRevisionEditor {
|
||||
}
|
||||
|
||||
pub async fn update_row(&self, changeset: RowMetaChangeset) -> FlowyResult<()> {
|
||||
let field_revs = self.get_field_revs::<FieldOrder>(None).await?;
|
||||
let field_revs = self.get_field_revs(None).await?;
|
||||
self.block_manager
|
||||
.update_row(changeset, |row_rev| make_row_from_row_rev(&field_revs, row_rev))
|
||||
.await
|
||||
@ -319,7 +318,7 @@ impl GridRevisionEditor {
|
||||
debug_assert_eq!(grid_block_snapshot.len(), 1);
|
||||
if grid_block_snapshot.len() == 1 {
|
||||
let snapshot = grid_block_snapshot.pop().unwrap();
|
||||
let field_revs = self.get_field_revs::<FieldOrder>(None).await?;
|
||||
let field_revs = self.get_field_revs(None).await?;
|
||||
let rows = make_rows_from_row_revs(&field_revs, &snapshot.row_revs);
|
||||
Ok(rows.into())
|
||||
} else {
|
||||
@ -331,7 +330,7 @@ impl GridRevisionEditor {
|
||||
match self.block_manager.get_row_rev(row_id).await? {
|
||||
None => Ok(None),
|
||||
Some(row_rev) => {
|
||||
let field_revs = self.get_field_revs::<FieldOrder>(None).await?;
|
||||
let field_revs = self.get_field_revs(None).await?;
|
||||
let row_revs = vec![row_rev];
|
||||
let mut rows = make_rows_from_row_revs(&field_revs, &row_revs);
|
||||
debug_assert!(rows.len() == 1);
|
||||
@ -396,7 +395,7 @@ impl GridRevisionEditor {
|
||||
cell_rev,
|
||||
field_rev,
|
||||
)?);
|
||||
let field_revs = self.get_field_revs::<FieldOrder>(None).await?;
|
||||
let field_revs = self.get_field_revs(None).await?;
|
||||
let cell_changeset = CellChangeset {
|
||||
grid_id,
|
||||
row_id,
|
||||
@ -432,7 +431,11 @@ impl GridRevisionEditor {
|
||||
|
||||
pub async fn get_grid_data(&self) -> FlowyResult<Grid> {
|
||||
let pad_read_guard = self.grid_pad.read().await;
|
||||
let field_orders = pad_read_guard.get_field_orders();
|
||||
let field_orders = pad_read_guard
|
||||
.get_field_revs(None)?
|
||||
.iter()
|
||||
.map(FieldOrder::from)
|
||||
.collect();
|
||||
let mut block_orders = vec![];
|
||||
for block_rev in pad_read_guard.get_block_meta_revs() {
|
||||
let row_orders = self.block_manager.get_row_orders(&block_rev.block_id).await?;
|
||||
|
@ -1,12 +1,11 @@
|
||||
use crate::entities::FieldType;
|
||||
use crate::services::field::*;
|
||||
use bytes::Bytes;
|
||||
use flowy_error::{internal_error, ErrorCode, FlowyError, FlowyResult};
|
||||
use flowy_grid_data_model::entities::FieldType;
|
||||
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, GridFilterRevision};
|
||||
use flowy_grid_data_model::revision::{CellRevision, FieldRevision};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt::Formatter;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub trait CellDataOperation<D, F> {
|
||||
fn decode_cell_data<T>(
|
||||
@ -115,14 +114,6 @@ impl TypeOptionCellData {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn apply_cell_filter(
|
||||
_filter_rev: Arc<GridFilterRevision>,
|
||||
_field_rev: &FieldRevision,
|
||||
_cell_rev: Option<CellRevision>,
|
||||
) -> bool {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// The changeset will be deserialized into specific data base on the FieldType.
|
||||
/// For example, it's String on FieldType::RichText, and SelectOptionChangeset on FieldType::SingleSelect
|
||||
pub fn apply_cell_data_changeset<C: Into<CellContentChangeset>, T: AsRef<FieldRevision>>(
|
||||
@ -131,7 +122,8 @@ pub fn apply_cell_data_changeset<C: Into<CellContentChangeset>, T: AsRef<FieldRe
|
||||
field_rev: T,
|
||||
) -> Result<String, FlowyError> {
|
||||
let field_rev = field_rev.as_ref();
|
||||
let s = match field_rev.field_type {
|
||||
let field_type = field_rev.field_type_rev.into();
|
||||
let s = match field_type {
|
||||
FieldType::RichText => RichTextTypeOption::from(field_rev).apply_changeset(changeset, cell_rev),
|
||||
FieldType::Number => NumberTypeOption::from(field_rev).apply_changeset(changeset, cell_rev),
|
||||
FieldType::DateTime => DateTypeOption::from(field_rev).apply_changeset(changeset, cell_rev),
|
||||
@ -141,14 +133,14 @@ pub fn apply_cell_data_changeset<C: Into<CellContentChangeset>, T: AsRef<FieldRe
|
||||
FieldType::URL => URLTypeOption::from(field_rev).apply_changeset(changeset, cell_rev),
|
||||
}?;
|
||||
|
||||
Ok(TypeOptionCellData::new(s, field_rev.field_type.clone()).json())
|
||||
Ok(TypeOptionCellData::new(s, field_type).json())
|
||||
}
|
||||
|
||||
pub fn decode_cell_data<T: TryInto<TypeOptionCellData>>(data: T, field_rev: &FieldRevision) -> DecodedCellData {
|
||||
if let Ok(type_option_cell_data) = data.try_into() {
|
||||
let TypeOptionCellData { data, field_type } = type_option_cell_data;
|
||||
let to_field_type = &field_rev.field_type;
|
||||
match try_decode_cell_data(data, field_rev, &field_type, to_field_type) {
|
||||
let to_field_type = field_rev.field_type_rev.into();
|
||||
match try_decode_cell_data(data, field_rev, &field_type, &to_field_type) {
|
||||
Ok(cell_data) => cell_data,
|
||||
Err(e) => {
|
||||
tracing::error!("Decode cell data failed, {:?}", e);
|
||||
@ -170,25 +162,25 @@ pub fn try_decode_cell_data(
|
||||
let get_cell_data = || {
|
||||
let data = match t_field_type {
|
||||
FieldType::RichText => field_rev
|
||||
.get_type_option_entry::<RichTextTypeOption>(t_field_type)?
|
||||
.get_type_option_entry::<RichTextTypeOption, _>(t_field_type)?
|
||||
.decode_cell_data(encoded_data, s_field_type, field_rev),
|
||||
FieldType::Number => field_rev
|
||||
.get_type_option_entry::<NumberTypeOption>(t_field_type)?
|
||||
.get_type_option_entry::<NumberTypeOption, _>(t_field_type)?
|
||||
.decode_cell_data(encoded_data, s_field_type, field_rev),
|
||||
FieldType::DateTime => field_rev
|
||||
.get_type_option_entry::<DateTypeOption>(t_field_type)?
|
||||
.get_type_option_entry::<DateTypeOption, _>(t_field_type)?
|
||||
.decode_cell_data(encoded_data, s_field_type, field_rev),
|
||||
FieldType::SingleSelect => field_rev
|
||||
.get_type_option_entry::<SingleSelectTypeOption>(t_field_type)?
|
||||
.get_type_option_entry::<SingleSelectTypeOption, _>(t_field_type)?
|
||||
.decode_cell_data(encoded_data, s_field_type, field_rev),
|
||||
FieldType::MultiSelect => field_rev
|
||||
.get_type_option_entry::<MultiSelectTypeOption>(t_field_type)?
|
||||
.get_type_option_entry::<MultiSelectTypeOption, _>(t_field_type)?
|
||||
.decode_cell_data(encoded_data, s_field_type, field_rev),
|
||||
FieldType::Checkbox => field_rev
|
||||
.get_type_option_entry::<CheckboxTypeOption>(t_field_type)?
|
||||
.get_type_option_entry::<CheckboxTypeOption, _>(t_field_type)?
|
||||
.decode_cell_data(encoded_data, s_field_type, field_rev),
|
||||
FieldType::URL => field_rev
|
||||
.get_type_option_entry::<URLTypeOption>(t_field_type)?
|
||||
.get_type_option_entry::<URLTypeOption, _>(t_field_type)?
|
||||
.decode_cell_data(encoded_data, s_field_type, field_rev),
|
||||
};
|
||||
Some(data)
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::entities::{GridBlock, RepeatedGridBlock, Row, RowOrder};
|
||||
use flowy_error::FlowyResult;
|
||||
use flowy_grid_data_model::entities::{GridBlock, RepeatedGridBlock, Row, RowOrder};
|
||||
use flowy_grid_data_model::revision::{FieldRevision, RowRevision};
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
@ -1,6 +1,5 @@
|
||||
use flowy_grid_data_model::entities::{
|
||||
CreateGridFilterParams, DeleteFilterParams, GridLayoutType, GridSettingChangesetParams,
|
||||
};
|
||||
use crate::entities::GridLayoutType;
|
||||
use flowy_sync::entities::grid::{CreateGridFilterParams, DeleteFilterParams, GridSettingChangesetParams};
|
||||
|
||||
pub struct GridSettingChangesetBuilder {
|
||||
params: GridSettingChangesetParams,
|
||||
@ -10,7 +9,7 @@ impl GridSettingChangesetBuilder {
|
||||
pub fn new(grid_id: &str, layout_type: &GridLayoutType) -> Self {
|
||||
let params = GridSettingChangesetParams {
|
||||
grid_id: grid_id.to_string(),
|
||||
layout_type: layout_type.clone(),
|
||||
layout_type: layout_type.clone().into(),
|
||||
insert_filter: None,
|
||||
delete_filter: None,
|
||||
insert_group: None,
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::entities::FieldType;
|
||||
use crate::services::field::*;
|
||||
use flowy_grid_data_model::entities::FieldType;
|
||||
use flowy_grid_data_model::revision::BuildGridContext;
|
||||
use flowy_sync::client_grid::GridBuilder;
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
use crate::grid::field_util::make_date_cell_string;
|
||||
use crate::grid::script::EditorScript::*;
|
||||
use crate::grid::script::*;
|
||||
use flowy_grid::entities::{CellChangeset, FieldType};
|
||||
use flowy_grid::services::field::{MultiSelectTypeOption, SelectOptionCellContentChangeset, SingleSelectTypeOption};
|
||||
use flowy_grid_data_model::entities::{CellChangeset, FieldType};
|
||||
|
||||
#[tokio::test]
|
||||
async fn grid_cell_update() {
|
||||
@ -17,7 +17,8 @@ async fn grid_cell_update() {
|
||||
let mut scripts = vec![];
|
||||
for (_, row_rev) in row_revs.iter().enumerate() {
|
||||
for field_rev in field_revs {
|
||||
let data = match field_rev.field_type {
|
||||
let field_type: FieldType = field_rev.field_type_rev.into();
|
||||
let data = match field_type {
|
||||
FieldType::RichText => "".to_string(),
|
||||
FieldType::Number => "123".to_string(),
|
||||
FieldType::DateTime => make_date_cell_string("123"),
|
||||
|
@ -2,8 +2,8 @@ use crate::grid::field_util::*;
|
||||
use crate::grid::script::EditorScript::*;
|
||||
use crate::grid::script::*;
|
||||
use flowy_grid::services::field::{SelectOption, SingleSelectTypeOption};
|
||||
use flowy_grid_data_model::entities::FieldChangesetParams;
|
||||
use flowy_grid_data_model::revision::TypeOptionDataEntry;
|
||||
use flowy_sync::entities::grid::FieldChangesetParams;
|
||||
|
||||
#[tokio::test]
|
||||
async fn grid_create_field() {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use flowy_grid::services::field::*;
|
||||
|
||||
use flowy_grid_data_model::entities::*;
|
||||
use flowy_grid::entities::*;
|
||||
use flowy_grid_data_model::revision::*;
|
||||
|
||||
pub fn create_text_field(grid_id: &str) -> (InsertFieldParams, FieldRevision) {
|
||||
@ -12,7 +12,7 @@ pub fn create_text_field(grid_id: &str) -> (InsertFieldParams, FieldRevision) {
|
||||
let cloned_field_rev = field_rev.clone();
|
||||
|
||||
let type_option_data = field_rev
|
||||
.get_type_option_entry::<RichTextTypeOption>(&field_rev.field_type)
|
||||
.get_type_option_entry::<RichTextTypeOption, _>(field_rev.field_type_rev)
|
||||
.unwrap()
|
||||
.protobuf_bytes()
|
||||
.to_vec();
|
||||
@ -21,7 +21,7 @@ pub fn create_text_field(grid_id: &str) -> (InsertFieldParams, FieldRevision) {
|
||||
id: field_rev.id,
|
||||
name: field_rev.name,
|
||||
desc: field_rev.desc,
|
||||
field_type: field_rev.field_type,
|
||||
field_type: field_rev.field_type_rev.into(),
|
||||
frozen: field_rev.frozen,
|
||||
visibility: field_rev.visibility,
|
||||
width: field_rev.width,
|
||||
@ -44,8 +44,9 @@ pub fn create_single_select_field(grid_id: &str) -> (InsertFieldParams, FieldRev
|
||||
|
||||
let field_rev = FieldBuilder::new(single_select).name("Name").visibility(true).build();
|
||||
let cloned_field_rev = field_rev.clone();
|
||||
let field_type: FieldType = field_rev.field_type_rev.into();
|
||||
let type_option_data = field_rev
|
||||
.get_type_option_entry::<SingleSelectTypeOption>(&field_rev.field_type)
|
||||
.get_type_option_entry::<SingleSelectTypeOption, _>(&field_type)
|
||||
.unwrap()
|
||||
.protobuf_bytes()
|
||||
.to_vec();
|
||||
@ -54,7 +55,7 @@ pub fn create_single_select_field(grid_id: &str) -> (InsertFieldParams, FieldRev
|
||||
id: field_rev.id,
|
||||
name: field_rev.name,
|
||||
desc: field_rev.desc,
|
||||
field_type: field_rev.field_type,
|
||||
field_type,
|
||||
frozen: field_rev.frozen,
|
||||
visibility: field_rev.visibility,
|
||||
width: field_rev.width,
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::grid::script::EditorScript::*;
|
||||
use crate::grid::script::*;
|
||||
use flowy_grid_data_model::entities::{CreateGridFilterPayload, TextFilterCondition};
|
||||
use flowy_grid::entities::CreateGridFilterPayload;
|
||||
|
||||
#[tokio::test]
|
||||
async fn grid_filter_create_test() {
|
||||
|
@ -3,11 +3,11 @@ use crate::grid::row_util::GridRowTestBuilder;
|
||||
use crate::grid::script::EditorScript::*;
|
||||
use crate::grid::script::*;
|
||||
use chrono::NaiveDateTime;
|
||||
use flowy_grid::entities::FieldType;
|
||||
use flowy_grid::services::field::{
|
||||
DateCellData, MultiSelectTypeOption, SingleSelectTypeOption, SELECTION_IDS_SEPARATOR,
|
||||
};
|
||||
use flowy_grid::services::row::{decode_cell_data, CreateRowRevisionBuilder};
|
||||
use flowy_grid_data_model::entities::FieldType;
|
||||
use flowy_grid_data_model::revision::RowMetaChangeset;
|
||||
|
||||
#[tokio::test]
|
||||
@ -75,7 +75,8 @@ async fn grid_row_add_cells_test() {
|
||||
let mut test = GridEditorTest::new().await;
|
||||
let mut builder = CreateRowRevisionBuilder::new(&test.field_revs);
|
||||
for field in &test.field_revs {
|
||||
match field.field_type {
|
||||
let field_type: FieldType = field.field_type_rev.into();
|
||||
match field_type {
|
||||
FieldType::RichText => {
|
||||
builder.add_cell(&field.id, "hello world".to_owned()).unwrap();
|
||||
}
|
||||
@ -122,7 +123,8 @@ async fn grid_row_add_date_cell_test() {
|
||||
let mut date_field = None;
|
||||
let timestamp = 1647390674;
|
||||
for field in &test.field_revs {
|
||||
if field.field_type == FieldType::DateTime {
|
||||
let field_type: FieldType = field.field_type_rev.into();
|
||||
if field_type == FieldType::DateTime {
|
||||
date_field = Some(field.clone());
|
||||
NaiveDateTime::from_timestamp(123, 0);
|
||||
// The data should not be empty
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::grid::script::GridEditorTest;
|
||||
use flowy_grid::entities::FieldType;
|
||||
use flowy_grid::services::field::DateCellContentChangeset;
|
||||
use flowy_grid::services::row::{CreateRowRevisionBuilder, CreateRowRevisionPayload};
|
||||
use flowy_grid_data_model::entities::FieldType;
|
||||
use flowy_grid_data_model::revision::FieldRevision;
|
||||
use strum::EnumCount;
|
||||
|
||||
@ -61,7 +61,10 @@ impl<'a> GridRowTestBuilder<'a> {
|
||||
self.test
|
||||
.field_revs
|
||||
.iter()
|
||||
.find(|field_rev| &field_rev.field_type == field_type)
|
||||
.find(|field_rev| {
|
||||
let t_field_type: FieldType = field_rev.field_type_rev.into();
|
||||
&t_field_type == field_type
|
||||
})
|
||||
.unwrap()
|
||||
.as_ref()
|
||||
.clone()
|
||||
|
@ -4,7 +4,7 @@ use flowy_grid::services::field::*;
|
||||
use flowy_grid::services::grid_editor::{GridPadBuilder, GridRevisionEditor};
|
||||
use flowy_grid::services::row::CreateRowRevisionPayload;
|
||||
use flowy_grid::services::setting::GridSettingChangesetBuilder;
|
||||
use flowy_grid_data_model::entities::*;
|
||||
use flowy_grid::entities::*;
|
||||
use flowy_grid_data_model::revision::*;
|
||||
use flowy_revision::REVISION_WRITE_INTERVAL_IN_MILLIS;
|
||||
use flowy_sync::client_grid::GridBuilder;
|
||||
@ -15,6 +15,7 @@ use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use strum::EnumCount;
|
||||
use tokio::time::sleep;
|
||||
use flowy_sync::entities::grid::{CreateGridFilterParams, DeleteFilterParams, FieldChangesetParams, GridSettingChangesetParams};
|
||||
|
||||
pub enum EditorScript {
|
||||
CreateField {
|
||||
@ -106,7 +107,7 @@ impl GridEditorTest {
|
||||
let view_data: Bytes = build_context.into();
|
||||
let test = ViewTest::new_grid_view(&sdk, view_data.to_vec()).await;
|
||||
let editor = sdk.grid_manager.open_grid(&test.view.id).await.unwrap();
|
||||
let field_revs = editor.get_field_revs::<FieldOrder>(None).await.unwrap();
|
||||
let field_revs = editor.get_field_revs(None).await.unwrap();
|
||||
let block_meta_revs = editor.get_block_meta_revs().await.unwrap();
|
||||
let row_revs = editor.grid_block_snapshots(None).await.unwrap().pop().unwrap().row_revs;
|
||||
assert_eq!(row_revs.len(), 3);
|
||||
@ -148,12 +149,12 @@ impl GridEditorTest {
|
||||
}
|
||||
|
||||
self.editor.insert_field(params).await.unwrap();
|
||||
self.field_revs = self.editor.get_field_revs::<FieldOrder>(None).await.unwrap();
|
||||
self.field_revs = self.editor.get_field_revs(None).await.unwrap();
|
||||
assert_eq!(self.field_count, self.field_revs.len());
|
||||
}
|
||||
EditorScript::UpdateField { changeset: change } => {
|
||||
self.editor.update_field(change).await.unwrap();
|
||||
self.field_revs = self.editor.get_field_revs::<FieldOrder>(None).await.unwrap();
|
||||
self.field_revs = self.editor.get_field_revs(None).await.unwrap();
|
||||
}
|
||||
EditorScript::DeleteField { field_rev } => {
|
||||
if self.editor.contain_field(&field_rev.id).await {
|
||||
@ -161,17 +162,17 @@ impl GridEditorTest {
|
||||
}
|
||||
|
||||
self.editor.delete_field(&field_rev.id).await.unwrap();
|
||||
self.field_revs = self.editor.get_field_revs::<FieldOrder>(None).await.unwrap();
|
||||
self.field_revs = self.editor.get_field_revs(None).await.unwrap();
|
||||
assert_eq!(self.field_count, self.field_revs.len());
|
||||
}
|
||||
EditorScript::AssertFieldCount(count) => {
|
||||
assert_eq!(
|
||||
self.editor.get_field_revs::<FieldOrder>(None).await.unwrap().len(),
|
||||
self.editor.get_field_revs(None).await.unwrap().len(),
|
||||
count
|
||||
);
|
||||
}
|
||||
EditorScript::AssertFieldEqual { field_index, field_rev } => {
|
||||
let field_revs = self.editor.get_field_revs::<FieldOrder>(None).await.unwrap();
|
||||
let field_revs = self.editor.get_field_revs(None).await.unwrap();
|
||||
assert_eq!(field_revs[field_index].as_ref(), &field_rev);
|
||||
}
|
||||
EditorScript::CreateBlock { block } => {
|
||||
@ -269,7 +270,7 @@ impl GridEditorTest {
|
||||
EditorScript::DeleteGridTableFilter { filter_id ,field_type} => {
|
||||
let layout_type = GridLayoutType::Table;
|
||||
let params = GridSettingChangesetBuilder::new(&self.grid_id, &layout_type)
|
||||
.delete_filter(DeleteFilterParams { filter_id, field_type })
|
||||
.delete_filter(DeleteFilterParams { filter_id, field_type_rev: field_type.into() })
|
||||
.build();
|
||||
let _ = self.editor.update_grid_setting(params).await.unwrap();
|
||||
}
|
||||
@ -304,7 +305,10 @@ impl GridEditorTest {
|
||||
pub fn text_field(&self) -> &FieldRevision {
|
||||
self.field_revs
|
||||
.iter()
|
||||
.filter(|field_rev| field_rev.field_type == FieldType::RichText)
|
||||
.filter(|field_rev| {
|
||||
let t_field_type: FieldType = field_rev.field_type_rev.into();
|
||||
t_field_type == FieldType::RichText
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.pop()
|
||||
.unwrap()
|
||||
|
Reference in New Issue
Block a user