mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: rename trait
This commit is contained in:
@ -26,7 +26,7 @@ impl TextBlockEditorTest {
|
||||
pub async fn new() -> Self {
|
||||
let sdk = FlowySDKTest::default();
|
||||
let _ = sdk.init_user().await;
|
||||
let test = ViewTest::new_grid_view(&sdk).await;
|
||||
let test = ViewTest::new_text_block_view(&sdk).await;
|
||||
let editor = sdk.text_block_manager.open_block(&test.view.id).await.unwrap();
|
||||
Self { sdk, editor }
|
||||
}
|
||||
|
@ -171,7 +171,6 @@ impl ViewController {
|
||||
data_type: view.data_type,
|
||||
data: delta_str,
|
||||
view_id: uuid(),
|
||||
ext_data: view.ext_data,
|
||||
plugin_type: view.plugin_type,
|
||||
};
|
||||
|
||||
|
@ -350,8 +350,8 @@ pub async fn create_view(sdk: &FlowySDKTest, app_id: &str, name: &str, desc: &st
|
||||
desc: desc.to_string(),
|
||||
thumbnail: None,
|
||||
data_type,
|
||||
ext_data: "".to_string(),
|
||||
plugin_type: 0,
|
||||
data: "".to_string(),
|
||||
};
|
||||
let view = FolderEventBuilder::new(sdk.clone())
|
||||
.event(CreateView)
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::manager::GridManager;
|
||||
use flowy_error::FlowyError;
|
||||
use flowy_grid_data_model::entities::{
|
||||
Cell, Grid, GridId, QueryFieldPayload, QueryRowPayload, RepeatedField, RepeatedRow,
|
||||
Cell, Field, Grid, GridId, QueryFieldPayload, QueryRowPayload, RepeatedField, RepeatedRow,
|
||||
};
|
||||
use lib_dispatch::prelude::{data_result, AppData, Data, DataResult};
|
||||
use std::sync::Arc;
|
||||
@ -13,7 +13,7 @@ pub(crate) async fn get_grid_data_handler(
|
||||
) -> DataResult<Grid, FlowyError> {
|
||||
let grid_id: GridId = data.into_inner();
|
||||
let editor = manager.open_grid(grid_id).await?;
|
||||
let grid = editor.grid_data().await;
|
||||
let grid = editor.grid_data().await?;
|
||||
data_result(grid)
|
||||
}
|
||||
|
||||
@ -35,7 +35,12 @@ pub(crate) async fn get_fields_handler(
|
||||
) -> DataResult<RepeatedField, FlowyError> {
|
||||
let payload: QueryFieldPayload = data.into_inner();
|
||||
let editor = manager.get_grid_editor(&payload.grid_id)?;
|
||||
let repeated_field: RepeatedField = editor.get_fields(Some(payload.field_orders)).await?.into();
|
||||
let field_metas = editor.get_field_metas(Some(payload.field_orders)).await?;
|
||||
let repeated_field: RepeatedField = field_metas
|
||||
.into_iter()
|
||||
.map(|field_meta| Field::from(field_meta))
|
||||
.collect::<Vec<_>>()
|
||||
.into();
|
||||
data_result(repeated_field)
|
||||
}
|
||||
|
||||
|
@ -9,9 +9,9 @@ macro_rules! impl_from_and_to_type_option {
|
||||
#[macro_export]
|
||||
macro_rules! impl_from_field_type_option {
|
||||
($target: ident) => {
|
||||
impl std::convert::From<&Field> for $target {
|
||||
fn from(field: &Field) -> $target {
|
||||
match serde_json::from_str(&field.type_options) {
|
||||
impl std::convert::From<&FieldMeta> for $target {
|
||||
fn from(field_meta: &FieldMeta) -> $target {
|
||||
match serde_json::from_str(&field_meta.type_options) {
|
||||
Ok(obj) => obj,
|
||||
Err(err) => {
|
||||
tracing::error!("{} convert from any data failed, {:?}", stringify!($target), err);
|
||||
|
@ -119,11 +119,11 @@ impl GridBlockMetaEditorManager {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn get_all_rows(&self, grid_blocks: Vec<GridBlock>) -> FlowyResult<Vec<RowMeta>> {
|
||||
pub(crate) async fn get_all_rows(&self, grid_blocks: Vec<GridBlock>) -> FlowyResult<Vec<Arc<RowMeta>>> {
|
||||
let mut row_metas = vec![];
|
||||
for grid_block in grid_blocks {
|
||||
let editor = self.get_editor(&grid_block.id).await?;
|
||||
let new_row_metas = editor.get_rows(None).await?;
|
||||
let new_row_metas = editor.get_row_metas(None).await?;
|
||||
new_row_metas.iter().for_each(|row_meta| {
|
||||
self.block_id_by_row_id
|
||||
.insert(row_meta.id.clone(), row_meta.block_id.clone());
|
||||
@ -134,12 +134,23 @@ impl GridBlockMetaEditorManager {
|
||||
Ok(row_metas)
|
||||
}
|
||||
|
||||
pub(crate) async fn get_rows(&self, row_orders: &RepeatedRowOrder) -> FlowyResult<Vec<RowMeta>> {
|
||||
pub(crate) async fn get_row_orders(&self, grid_blocks: Vec<GridBlock>) -> FlowyResult<Vec<RowOrder>> {
|
||||
let mut row_orders = vec![];
|
||||
for grid_block in grid_blocks {
|
||||
let editor = self.get_editor(&grid_block.id).await?;
|
||||
let row_metas = editor.get_row_metas(None).await?;
|
||||
let block_row_orders = row_metas.iter().map(|row_meta| RowOrder::from(row_meta));
|
||||
row_orders.extend(block_row_orders);
|
||||
}
|
||||
Ok(row_orders)
|
||||
}
|
||||
|
||||
pub(crate) async fn get_rows(&self, row_orders: &RepeatedRowOrder) -> FlowyResult<Vec<Arc<RowMeta>>> {
|
||||
let row_ids_per_blocks = make_row_ids_per_block(row_orders);
|
||||
let mut row_metas = vec![];
|
||||
for row_ids_per_block in row_ids_per_blocks {
|
||||
let editor = self.get_editor(&row_ids_per_block.block_id).await?;
|
||||
let new_row_metas = editor.get_rows(Some(row_ids_per_block.row_ids)).await?;
|
||||
let new_row_metas = editor.get_row_metas(Some(row_ids_per_block.row_ids)).await?;
|
||||
new_row_metas.iter().for_each(|row_meta| {
|
||||
self.block_id_by_row_id
|
||||
.insert(row_meta.id.clone(), row_meta.block_id.clone());
|
||||
@ -234,14 +245,21 @@ impl ClientGridBlockMetaEditor {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn get_rows(&self, row_ids: Option<Vec<String>>) -> FlowyResult<Vec<RowMeta>> {
|
||||
match row_ids {
|
||||
None => Ok(self.meta_pad.read().await.all_rows()),
|
||||
Some(row_ids) => {
|
||||
let rows = self.meta_pad.read().await.get_rows(row_ids)?;
|
||||
Ok(rows)
|
||||
}
|
||||
}
|
||||
pub async fn get_row_metas(&self, row_ids: Option<Vec<String>>) -> FlowyResult<Vec<Arc<RowMeta>>> {
|
||||
let row_metas = self.meta_pad.read().await.get_rows(row_ids)?;
|
||||
Ok(row_metas)
|
||||
}
|
||||
|
||||
pub async fn get_row_orders(&self) -> FlowyResult<Vec<RowOrder>> {
|
||||
let row_orders = self
|
||||
.meta_pad
|
||||
.read()
|
||||
.await
|
||||
.get_rows(None)?
|
||||
.iter()
|
||||
.map(|row_meta| RowOrder::from(row_meta))
|
||||
.collect::<Vec<RowOrder>>();
|
||||
Ok(row_orders)
|
||||
}
|
||||
|
||||
async fn modify<F>(&self, f: F) -> FlowyResult<()>
|
||||
|
@ -1,8 +1,8 @@
|
||||
use crate::impl_from_and_to_type_option;
|
||||
use crate::services::row::StringifyCellData;
|
||||
use crate::services::row::CellDataSerde;
|
||||
use flowy_derive::ProtoBuf;
|
||||
use flowy_error::FlowyError;
|
||||
use flowy_grid_data_model::entities::{Field, FieldType};
|
||||
use flowy_grid_data_model::entities::{FieldMeta, FieldType};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default, ProtoBuf)]
|
||||
@ -12,13 +12,13 @@ pub struct CheckboxDescription {
|
||||
}
|
||||
impl_from_and_to_type_option!(CheckboxDescription, FieldType::Checkbox);
|
||||
|
||||
impl StringifyCellData for CheckboxDescription {
|
||||
fn str_from_cell_data(&self, data: String) -> String {
|
||||
impl CellDataSerde for CheckboxDescription {
|
||||
fn deserialize_cell_data(&self, data: String) -> String {
|
||||
data
|
||||
}
|
||||
|
||||
fn str_to_cell_data(&self, s: &str) -> Result<String, FlowyError> {
|
||||
let s = match string_to_bool(s) {
|
||||
fn serialize_cell_data(&self, data: &str) -> Result<String, FlowyError> {
|
||||
let s = match string_to_bool(data) {
|
||||
true => "1",
|
||||
false => "0",
|
||||
};
|
||||
@ -42,19 +42,19 @@ fn string_to_bool(bool_str: &str) -> bool {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::services::cell::CheckboxDescription;
|
||||
use crate::services::row::StringifyCellData;
|
||||
use crate::services::row::CellDataSerde;
|
||||
|
||||
#[test]
|
||||
fn checkout_box_description_test() {
|
||||
let description = CheckboxDescription::default();
|
||||
assert_eq!(description.str_to_cell_data("true").unwrap(), "1".to_owned());
|
||||
assert_eq!(description.str_to_cell_data("1").unwrap(), "1".to_owned());
|
||||
assert_eq!(description.str_to_cell_data("yes").unwrap(), "1".to_owned());
|
||||
assert_eq!(description.serialize_cell_data("true").unwrap(), "1".to_owned());
|
||||
assert_eq!(description.serialize_cell_data("1").unwrap(), "1".to_owned());
|
||||
assert_eq!(description.serialize_cell_data("yes").unwrap(), "1".to_owned());
|
||||
|
||||
assert_eq!(description.str_to_cell_data("false").unwrap(), "0".to_owned());
|
||||
assert_eq!(description.str_to_cell_data("no").unwrap(), "0".to_owned());
|
||||
assert_eq!(description.str_to_cell_data("123").unwrap(), "0".to_owned());
|
||||
assert_eq!(description.serialize_cell_data("false").unwrap(), "0".to_owned());
|
||||
assert_eq!(description.serialize_cell_data("no").unwrap(), "0".to_owned());
|
||||
assert_eq!(description.serialize_cell_data("123").unwrap(), "0".to_owned());
|
||||
|
||||
assert_eq!(description.str_from_cell_data("1".to_owned()), "1".to_owned());
|
||||
assert_eq!(description.deserialize_cell_data("1".to_owned()), "1".to_owned());
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
use crate::impl_from_and_to_type_option;
|
||||
use crate::services::row::StringifyCellData;
|
||||
use crate::services::row::CellDataSerde;
|
||||
|
||||
use chrono::format::strftime::StrftimeItems;
|
||||
use chrono::NaiveDateTime;
|
||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||
use flowy_error::FlowyError;
|
||||
use flowy_grid_data_model::entities::{Field, FieldType};
|
||||
use flowy_grid_data_model::entities::{FieldMeta, FieldType};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use strum_macros::EnumIter;
|
||||
@ -38,8 +38,8 @@ impl DateDescription {
|
||||
}
|
||||
}
|
||||
|
||||
impl StringifyCellData for DateDescription {
|
||||
fn str_from_cell_data(&self, data: String) -> String {
|
||||
impl CellDataSerde for DateDescription {
|
||||
fn deserialize_cell_data(&self, data: String) -> String {
|
||||
match data.parse::<i64>() {
|
||||
Ok(timestamp) => {
|
||||
let native = NaiveDateTime::from_timestamp(timestamp, 0);
|
||||
@ -52,11 +52,11 @@ impl StringifyCellData for DateDescription {
|
||||
}
|
||||
}
|
||||
|
||||
fn str_to_cell_data(&self, s: &str) -> Result<String, FlowyError> {
|
||||
let timestamp = match s.parse::<i64>() {
|
||||
fn serialize_cell_data(&self, data: &str) -> Result<String, FlowyError> {
|
||||
let timestamp = match data.parse::<i64>() {
|
||||
Ok(timestamp) => timestamp,
|
||||
Err(e) => {
|
||||
tracing::error!("Parse {} to i64 failed: {}", s, e);
|
||||
tracing::error!("Parse {} to i64 failed: {}", data, e);
|
||||
chrono::Utc::now().timestamp()
|
||||
}
|
||||
};
|
||||
@ -149,7 +149,7 @@ impl std::default::Default for TimeFormat {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::services::cell::{DateDescription, DateFormat, TimeFormat};
|
||||
use crate::services::row::StringifyCellData;
|
||||
use crate::services::row::CellDataSerde;
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
#[test]
|
||||
@ -167,7 +167,7 @@ mod tests {
|
||||
);
|
||||
assert_eq!(
|
||||
"Mar 14,2022 17:56".to_owned(),
|
||||
description.str_from_cell_data("1647251762".to_owned())
|
||||
description.deserialize_cell_data("1647251762".to_owned())
|
||||
);
|
||||
}
|
||||
DateFormat::US => {
|
||||
@ -177,7 +177,7 @@ mod tests {
|
||||
);
|
||||
assert_eq!(
|
||||
"2022/03/14 17:56".to_owned(),
|
||||
description.str_from_cell_data("1647251762".to_owned())
|
||||
description.deserialize_cell_data("1647251762".to_owned())
|
||||
);
|
||||
}
|
||||
DateFormat::ISO => {
|
||||
@ -187,7 +187,7 @@ mod tests {
|
||||
);
|
||||
assert_eq!(
|
||||
"2022-03-14 17:56".to_owned(),
|
||||
description.str_from_cell_data("1647251762".to_owned())
|
||||
description.deserialize_cell_data("1647251762".to_owned())
|
||||
);
|
||||
}
|
||||
DateFormat::Local => {
|
||||
@ -197,7 +197,7 @@ mod tests {
|
||||
);
|
||||
assert_eq!(
|
||||
"2022/03/14 17:56".to_owned(),
|
||||
description.str_from_cell_data("1647251762".to_owned())
|
||||
description.deserialize_cell_data("1647251762".to_owned())
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -217,7 +217,7 @@ mod tests {
|
||||
);
|
||||
assert_eq!(
|
||||
"Mar 14,2022 17:56".to_owned(),
|
||||
description.str_from_cell_data("1647251762".to_owned())
|
||||
description.deserialize_cell_data("1647251762".to_owned())
|
||||
);
|
||||
}
|
||||
TimeFormat::TwelveHour => {
|
||||
@ -227,7 +227,7 @@ mod tests {
|
||||
);
|
||||
assert_eq!(
|
||||
"Mar 14,2022 05:56:02 PM".to_owned(),
|
||||
description.str_from_cell_data("1647251762".to_owned())
|
||||
description.deserialize_cell_data("1647251762".to_owned())
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -237,6 +237,6 @@ mod tests {
|
||||
#[test]
|
||||
fn date_description_invalid_data_test() {
|
||||
let description = DateDescription::default();
|
||||
description.str_to_cell_data("he").unwrap();
|
||||
description.serialize_cell_data("he").unwrap();
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
use crate::impl_from_and_to_type_option;
|
||||
use crate::services::row::StringifyCellData;
|
||||
use crate::services::row::CellDataSerde;
|
||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||
use flowy_error::FlowyError;
|
||||
use flowy_grid_data_model::entities::{Field, FieldType};
|
||||
use flowy_grid_data_model::entities::{FieldMeta, FieldType};
|
||||
use lazy_static::lazy_static;
|
||||
use rust_decimal::prelude::Zero;
|
||||
use rust_decimal::Decimal;
|
||||
@ -119,8 +119,8 @@ impl NumberDescription {
|
||||
}
|
||||
}
|
||||
|
||||
impl StringifyCellData for NumberDescription {
|
||||
fn str_from_cell_data(&self, data: String) -> String {
|
||||
impl CellDataSerde for NumberDescription {
|
||||
fn deserialize_cell_data(&self, data: String) -> String {
|
||||
match self.format {
|
||||
NumberFormat::Number => data,
|
||||
NumberFormat::USD => self.money_from_str(&data, USD),
|
||||
@ -129,8 +129,8 @@ impl StringifyCellData for NumberDescription {
|
||||
}
|
||||
}
|
||||
|
||||
fn str_to_cell_data(&self, s: &str) -> Result<String, FlowyError> {
|
||||
Ok(self.strip_symbol(s))
|
||||
fn serialize_cell_data(&self, data: &str) -> Result<String, FlowyError> {
|
||||
Ok(self.strip_symbol(data))
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,30 +145,42 @@ fn make_strip_symbol() -> Vec<String> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::services::cell::{NumberDescription, NumberFormat};
|
||||
use crate::services::row::StringifyCellData;
|
||||
use crate::services::row::CellDataSerde;
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
#[test]
|
||||
fn number_description_test() {
|
||||
let mut description = NumberDescription::default();
|
||||
assert_eq!(description.str_to_cell_data("¥18,443").unwrap(), "18443".to_owned());
|
||||
assert_eq!(description.str_to_cell_data("$18,443").unwrap(), "18443".to_owned());
|
||||
assert_eq!(description.str_to_cell_data("€18.443").unwrap(), "18443".to_owned());
|
||||
assert_eq!(description.serialize_cell_data("¥18,443").unwrap(), "18443".to_owned());
|
||||
assert_eq!(description.serialize_cell_data("$18,443").unwrap(), "18443".to_owned());
|
||||
assert_eq!(description.serialize_cell_data("€18.443").unwrap(), "18443".to_owned());
|
||||
|
||||
for format in NumberFormat::iter() {
|
||||
description.format = format;
|
||||
match format {
|
||||
NumberFormat::Number => {
|
||||
assert_eq!(description.str_from_cell_data("18443".to_owned()), "18443".to_owned());
|
||||
assert_eq!(
|
||||
description.deserialize_cell_data("18443".to_owned()),
|
||||
"18443".to_owned()
|
||||
);
|
||||
}
|
||||
NumberFormat::USD => {
|
||||
assert_eq!(description.str_from_cell_data("18443".to_owned()), "$18,443".to_owned());
|
||||
assert_eq!(
|
||||
description.deserialize_cell_data("18443".to_owned()),
|
||||
"$18,443".to_owned()
|
||||
);
|
||||
}
|
||||
NumberFormat::CNY => {
|
||||
assert_eq!(description.str_from_cell_data("18443".to_owned()), "¥18,443".to_owned());
|
||||
assert_eq!(
|
||||
description.deserialize_cell_data("18443".to_owned()),
|
||||
"¥18,443".to_owned()
|
||||
);
|
||||
}
|
||||
NumberFormat::EUR => {
|
||||
assert_eq!(description.str_from_cell_data("18443".to_owned()), "€18.443".to_owned());
|
||||
assert_eq!(
|
||||
description.deserialize_cell_data("18443".to_owned()),
|
||||
"€18.443".to_owned()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -183,23 +195,26 @@ mod tests {
|
||||
description.format = format;
|
||||
match format {
|
||||
NumberFormat::Number => {
|
||||
assert_eq!(description.str_from_cell_data("18443".to_owned()), "18443".to_owned());
|
||||
assert_eq!(
|
||||
description.deserialize_cell_data("18443".to_owned()),
|
||||
"18443".to_owned()
|
||||
);
|
||||
}
|
||||
NumberFormat::USD => {
|
||||
assert_eq!(
|
||||
description.str_from_cell_data("18443".to_owned()),
|
||||
description.deserialize_cell_data("18443".to_owned()),
|
||||
"$1,844.3".to_owned()
|
||||
);
|
||||
}
|
||||
NumberFormat::CNY => {
|
||||
assert_eq!(
|
||||
description.str_from_cell_data("18443".to_owned()),
|
||||
description.deserialize_cell_data("18443".to_owned()),
|
||||
"¥1,844.3".to_owned()
|
||||
);
|
||||
}
|
||||
NumberFormat::EUR => {
|
||||
assert_eq!(
|
||||
description.str_from_cell_data("18443".to_owned()),
|
||||
description.deserialize_cell_data("18443".to_owned()),
|
||||
"€1.844,3".to_owned()
|
||||
);
|
||||
}
|
||||
@ -216,23 +231,26 @@ mod tests {
|
||||
description.format = format;
|
||||
match format {
|
||||
NumberFormat::Number => {
|
||||
assert_eq!(description.str_from_cell_data("18443".to_owned()), "18443".to_owned());
|
||||
assert_eq!(
|
||||
description.deserialize_cell_data("18443".to_owned()),
|
||||
"18443".to_owned()
|
||||
);
|
||||
}
|
||||
NumberFormat::USD => {
|
||||
assert_eq!(
|
||||
description.str_from_cell_data("18443".to_owned()),
|
||||
description.deserialize_cell_data("18443".to_owned()),
|
||||
"-$18,443".to_owned()
|
||||
);
|
||||
}
|
||||
NumberFormat::CNY => {
|
||||
assert_eq!(
|
||||
description.str_from_cell_data("18443".to_owned()),
|
||||
description.deserialize_cell_data("18443".to_owned()),
|
||||
"-¥18,443".to_owned()
|
||||
);
|
||||
}
|
||||
NumberFormat::EUR => {
|
||||
assert_eq!(
|
||||
description.str_from_cell_data("18443".to_owned()),
|
||||
description.deserialize_cell_data("18443".to_owned()),
|
||||
"-€18.443".to_owned()
|
||||
);
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
use crate::impl_from_and_to_type_option;
|
||||
use crate::services::row::StringifyCellData;
|
||||
use crate::services::row::CellDataSerde;
|
||||
use crate::services::util::*;
|
||||
use flowy_derive::ProtoBuf;
|
||||
use flowy_error::FlowyError;
|
||||
use flowy_grid_data_model::entities::{Field, FieldType};
|
||||
use flowy_grid_data_model::entities::{FieldMeta, FieldType};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
// Single select
|
||||
@ -17,13 +17,13 @@ pub struct SingleSelectDescription {
|
||||
}
|
||||
impl_from_and_to_type_option!(SingleSelectDescription, FieldType::SingleSelect);
|
||||
|
||||
impl StringifyCellData for SingleSelectDescription {
|
||||
fn str_from_cell_data(&self, data: String) -> String {
|
||||
impl CellDataSerde for SingleSelectDescription {
|
||||
fn deserialize_cell_data(&self, data: String) -> String {
|
||||
data
|
||||
}
|
||||
|
||||
fn str_to_cell_data(&self, s: &str) -> Result<String, FlowyError> {
|
||||
Ok(select_option_id_from_data(s.to_owned(), true))
|
||||
fn serialize_cell_data(&self, data: &str) -> Result<String, FlowyError> {
|
||||
Ok(select_option_id_from_data(data.to_owned(), true))
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,13 +37,13 @@ pub struct MultiSelectDescription {
|
||||
pub disable_color: bool,
|
||||
}
|
||||
impl_from_and_to_type_option!(MultiSelectDescription, FieldType::MultiSelect);
|
||||
impl StringifyCellData for MultiSelectDescription {
|
||||
fn str_from_cell_data(&self, data: String) -> String {
|
||||
impl CellDataSerde for MultiSelectDescription {
|
||||
fn deserialize_cell_data(&self, data: String) -> String {
|
||||
data
|
||||
}
|
||||
|
||||
fn str_to_cell_data(&self, s: &str) -> Result<String, FlowyError> {
|
||||
Ok(select_option_id_from_data(s.to_owned(), false))
|
||||
fn serialize_cell_data(&self, data: &str) -> Result<String, FlowyError> {
|
||||
Ok(select_option_id_from_data(data.to_owned(), false))
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,14 +84,14 @@ impl SelectOption {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::services::cell::{MultiSelectDescription, SingleSelectDescription};
|
||||
use crate::services::row::StringifyCellData;
|
||||
use crate::services::row::CellDataSerde;
|
||||
|
||||
#[test]
|
||||
fn selection_description_test() {
|
||||
let description = SingleSelectDescription::default();
|
||||
assert_eq!(description.str_to_cell_data("1,2,3").unwrap(), "1".to_owned());
|
||||
assert_eq!(description.serialize_cell_data("1,2,3").unwrap(), "1".to_owned());
|
||||
|
||||
let description = MultiSelectDescription::default();
|
||||
assert_eq!(description.str_to_cell_data("1,2,3").unwrap(), "1,2,3".to_owned());
|
||||
assert_eq!(description.serialize_cell_data("1,2,3").unwrap(), "1,2,3".to_owned());
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
use crate::impl_from_and_to_type_option;
|
||||
use crate::services::row::StringifyCellData;
|
||||
use crate::services::row::CellDataSerde;
|
||||
|
||||
use flowy_derive::ProtoBuf;
|
||||
use flowy_error::FlowyError;
|
||||
use flowy_grid_data_model::entities::{Field, FieldType};
|
||||
use flowy_grid_data_model::entities::{FieldMeta, FieldType};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)]
|
||||
@ -13,12 +13,12 @@ pub struct RichTextDescription {
|
||||
}
|
||||
impl_from_and_to_type_option!(RichTextDescription, FieldType::RichText);
|
||||
|
||||
impl StringifyCellData for RichTextDescription {
|
||||
fn str_from_cell_data(&self, data: String) -> String {
|
||||
impl CellDataSerde for RichTextDescription {
|
||||
fn deserialize_cell_data(&self, data: String) -> String {
|
||||
data
|
||||
}
|
||||
|
||||
fn str_to_cell_data(&self, s: &str) -> Result<String, FlowyError> {
|
||||
Ok(s.to_owned())
|
||||
fn serialize_cell_data(&self, data: &str) -> Result<String, FlowyError> {
|
||||
Ok(data.to_owned())
|
||||
}
|
||||
}
|
||||
|
@ -1,55 +1,55 @@
|
||||
use flowy_grid_data_model::entities::{Field, FieldType};
|
||||
use flowy_grid_data_model::entities::{FieldMeta, FieldType};
|
||||
|
||||
pub struct FieldBuilder {
|
||||
field: Field,
|
||||
field_meta: FieldMeta,
|
||||
type_options_builder: Box<dyn TypeOptionsBuilder>,
|
||||
}
|
||||
|
||||
impl FieldBuilder {
|
||||
pub fn new<T: TypeOptionsBuilder + 'static>(type_options_builder: T) -> Self {
|
||||
let field = Field::new("Name", "", FieldType::RichText);
|
||||
let field_meta = FieldMeta::new("Name", "", FieldType::RichText);
|
||||
Self {
|
||||
field,
|
||||
field_meta,
|
||||
type_options_builder: Box::new(type_options_builder),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn name(mut self, name: &str) -> Self {
|
||||
self.field.name = name.to_owned();
|
||||
self.field_meta.name = name.to_owned();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn desc(mut self, desc: &str) -> Self {
|
||||
self.field.desc = desc.to_owned();
|
||||
self.field_meta.desc = desc.to_owned();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn field_type(mut self, field_type: FieldType) -> Self {
|
||||
self.field.field_type = field_type;
|
||||
self.field_meta.field_type = field_type;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn visibility(mut self, visibility: bool) -> Self {
|
||||
self.field.visibility = visibility;
|
||||
self.field_meta.visibility = visibility;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn width(mut self, width: i32) -> Self {
|
||||
self.field.width = width;
|
||||
self.field_meta.width = width;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn frozen(mut self, frozen: bool) -> Self {
|
||||
self.field.frozen = frozen;
|
||||
self.field_meta.frozen = frozen;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(mut self) -> Field {
|
||||
assert_eq!(self.field.field_type, self.type_options_builder.field_type());
|
||||
pub fn build(mut self) -> FieldMeta {
|
||||
assert_eq!(self.field_meta.field_type, self.type_options_builder.field_type());
|
||||
|
||||
let type_options = self.type_options_builder.build();
|
||||
self.field.type_options = type_options;
|
||||
self.field
|
||||
self.field_meta.type_options = type_options;
|
||||
self.field_meta
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@ use flowy_collaboration::entities::revision::Revision;
|
||||
use flowy_collaboration::util::make_delta_from_revisions;
|
||||
use flowy_error::{FlowyError, FlowyResult};
|
||||
use flowy_grid_data_model::entities::{
|
||||
CellMetaChangeset, Field, FieldChangeset, Grid, GridBlock, GridBlockChangeset, RepeatedFieldOrder,
|
||||
CellMetaChangeset, Field, FieldChangeset, FieldMeta, Grid, GridBlock, GridBlockChangeset, RepeatedFieldOrder,
|
||||
RepeatedRowOrder, Row, RowMeta, RowMetaChangeset,
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
@ -56,8 +56,8 @@ impl ClientGridEditor {
|
||||
}))
|
||||
}
|
||||
|
||||
pub async fn create_field(&self, field: Field) -> FlowyResult<()> {
|
||||
let _ = self.modify(|grid| Ok(grid.create_field(field)?)).await?;
|
||||
pub async fn create_field(&self, field_meta: FieldMeta) -> FlowyResult<()> {
|
||||
let _ = self.modify(|grid| Ok(grid.create_field(field_meta)?)).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -82,9 +82,9 @@ impl ClientGridEditor {
|
||||
}
|
||||
|
||||
pub async fn create_row(&self) -> FlowyResult<()> {
|
||||
let fields = self.grid_meta_pad.read().await.get_fields(None)?;
|
||||
let field_metas = self.grid_meta_pad.read().await.get_field_metas(None)?;
|
||||
let block_id = self.last_block_id().await?;
|
||||
let row = row_meta_from_context(&block_id, CreateRowContextBuilder::new(&fields).build());
|
||||
let row = row_meta_from_context(&block_id, CreateRowContextBuilder::new(&field_metas).build());
|
||||
let row_count = self.block_meta_manager.create_row(row).await?;
|
||||
let changeset = GridBlockChangeset::from_row_count(&block_id, row_count);
|
||||
let _ = self.update_block(changeset).await?;
|
||||
@ -119,12 +119,12 @@ impl ClientGridEditor {
|
||||
}
|
||||
|
||||
pub async fn get_rows(&self, row_orders: Option<RepeatedRowOrder>) -> FlowyResult<Vec<Row>> {
|
||||
let row_metas = self.get_row_metas(&row_orders).await?;
|
||||
let fields = self.grid_meta_pad.read().await.get_fields(None)?;
|
||||
let row_metas = self.get_row_metas(row_orders.as_ref()).await?;
|
||||
let field_meta = self.grid_meta_pad.read().await.get_field_metas(None)?;
|
||||
match row_orders {
|
||||
None => Ok(make_rows(&fields, row_metas)),
|
||||
None => Ok(make_rows(&field_meta, row_metas)),
|
||||
Some(row_orders) => {
|
||||
let mut row_map: HashMap<String, Row> = make_row_by_row_id(&fields, row_metas);
|
||||
let mut row_map: HashMap<String, Row> = make_row_by_row_id(&field_meta, row_metas);
|
||||
let rows = row_orders
|
||||
.iter()
|
||||
.flat_map(|row_order| row_map.remove(&row_order.row_id))
|
||||
@ -134,7 +134,7 @@ impl ClientGridEditor {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get_row_metas(&self, row_orders: &Option<RepeatedRowOrder>) -> FlowyResult<Vec<RowMeta>> {
|
||||
pub async fn get_row_metas(&self, row_orders: Option<&RepeatedRowOrder>) -> FlowyResult<Vec<Arc<RowMeta>>> {
|
||||
match row_orders {
|
||||
None => {
|
||||
let grid_blocks = self.grid_meta_pad.read().await.get_blocks();
|
||||
@ -156,13 +156,20 @@ impl ClientGridEditor {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn grid_data(&self) -> Grid {
|
||||
todo!()
|
||||
pub async fn grid_data(&self) -> FlowyResult<Grid> {
|
||||
let field_orders = self.grid_meta_pad.read().await.get_field_orders();
|
||||
let grid_blocks = self.grid_meta_pad.read().await.get_blocks();
|
||||
let row_orders = self.block_meta_manager.get_row_orders(grid_blocks).await?;
|
||||
Ok(Grid {
|
||||
id: self.grid_id.clone(),
|
||||
field_orders,
|
||||
row_orders,
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn get_fields(&self, field_orders: Option<RepeatedFieldOrder>) -> FlowyResult<Vec<Field>> {
|
||||
let fields = self.grid_meta_pad.read().await.get_fields(field_orders)?;
|
||||
Ok(fields)
|
||||
pub async fn get_field_metas(&self, field_orders: Option<RepeatedFieldOrder>) -> FlowyResult<Vec<FieldMeta>> {
|
||||
let field_meta = self.grid_meta_pad.read().await.get_field_metas(field_orders)?;
|
||||
Ok(field_meta)
|
||||
}
|
||||
|
||||
pub async fn get_blocks(&self) -> FlowyResult<Vec<GridBlock>> {
|
||||
|
@ -0,0 +1,32 @@
|
||||
use crate::services::cell::*;
|
||||
use flowy_error::FlowyError;
|
||||
use flowy_grid_data_model::entities::{FieldMeta, FieldType};
|
||||
|
||||
pub trait CellDataSerde {
|
||||
fn deserialize_cell_data(&self, data: String) -> String;
|
||||
fn serialize_cell_data(&self, data: &str) -> Result<String, FlowyError>;
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn serialize_cell_data(data: &str, field: &FieldMeta) -> Result<String, FlowyError> {
|
||||
match field.field_type {
|
||||
FieldType::RichText => RichTextDescription::from(field).serialize_cell_data(data),
|
||||
FieldType::Number => NumberDescription::from(field).serialize_cell_data(data),
|
||||
FieldType::DateTime => DateDescription::from(field).serialize_cell_data(data),
|
||||
FieldType::SingleSelect => SingleSelectDescription::from(field).serialize_cell_data(data),
|
||||
FieldType::MultiSelect => MultiSelectDescription::from(field).serialize_cell_data(data),
|
||||
FieldType::Checkbox => CheckboxDescription::from(field).serialize_cell_data(data),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deserialize_cell_data(data: String, field: &FieldMeta) -> Result<String, FlowyError> {
|
||||
let s = match field.field_type {
|
||||
FieldType::RichText => RichTextDescription::from(field).deserialize_cell_data(data),
|
||||
FieldType::Number => NumberDescription::from(field).deserialize_cell_data(data),
|
||||
FieldType::DateTime => DateDescription::from(field).deserialize_cell_data(data),
|
||||
FieldType::SingleSelect => SingleSelectDescription::from(field).deserialize_cell_data(data),
|
||||
FieldType::MultiSelect => MultiSelectDescription::from(field).deserialize_cell_data(data),
|
||||
FieldType::Checkbox => CheckboxDescription::from(field).deserialize_cell_data(data),
|
||||
};
|
||||
Ok(s)
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
use crate::services::cell::*;
|
||||
use flowy_error::FlowyError;
|
||||
use flowy_grid_data_model::entities::{Field, FieldType};
|
||||
|
||||
pub trait StringifyCellData {
|
||||
fn str_from_cell_data(&self, data: String) -> String;
|
||||
fn str_to_cell_data(&self, s: &str) -> Result<String, FlowyError>;
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn stringify_serialize(field: &Field, s: &str) -> Result<String, FlowyError> {
|
||||
match field.field_type {
|
||||
FieldType::RichText => RichTextDescription::from(field).str_to_cell_data(s),
|
||||
FieldType::Number => NumberDescription::from(field).str_to_cell_data(s),
|
||||
FieldType::DateTime => DateDescription::from(field).str_to_cell_data(s),
|
||||
FieldType::SingleSelect => SingleSelectDescription::from(field).str_to_cell_data(s),
|
||||
FieldType::MultiSelect => MultiSelectDescription::from(field).str_to_cell_data(s),
|
||||
FieldType::Checkbox => CheckboxDescription::from(field).str_to_cell_data(s),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn stringify_deserialize(data: String, field: &Field) -> Result<String, FlowyError> {
|
||||
// let _ = check_type_id(&data, field)?;
|
||||
let s = match field.field_type {
|
||||
FieldType::RichText => RichTextDescription::from(field).str_from_cell_data(data),
|
||||
FieldType::Number => NumberDescription::from(field).str_from_cell_data(data),
|
||||
FieldType::DateTime => DateDescription::from(field).str_from_cell_data(data),
|
||||
FieldType::SingleSelect => SingleSelectDescription::from(field).str_from_cell_data(data),
|
||||
FieldType::MultiSelect => MultiSelectDescription::from(field).str_from_cell_data(data),
|
||||
FieldType::Checkbox => CheckboxDescription::from(field).str_from_cell_data(data),
|
||||
};
|
||||
Ok(s)
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
mod cell_stringify;
|
||||
mod cell_data_serde;
|
||||
mod row_builder;
|
||||
mod row_loader;
|
||||
|
||||
pub use cell_stringify::*;
|
||||
pub use cell_data_serde::*;
|
||||
pub use row_builder::*;
|
||||
pub(crate) use row_loader::*;
|
||||
|
@ -1,14 +1,14 @@
|
||||
use flowy_grid_data_model::entities::{CellMeta, Field, RowMeta, DEFAULT_ROW_HEIGHT};
|
||||
use flowy_grid_data_model::entities::{CellMeta, FieldMeta, RowMeta, DEFAULT_ROW_HEIGHT};
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub struct CreateRowContextBuilder<'a> {
|
||||
#[allow(dead_code)]
|
||||
fields: &'a [Field],
|
||||
fields: &'a [FieldMeta],
|
||||
ctx: CreateRowContext,
|
||||
}
|
||||
|
||||
impl<'a> CreateRowContextBuilder<'a> {
|
||||
pub fn new(fields: &'a [Field]) -> Self {
|
||||
pub fn new(fields: &'a [FieldMeta]) -> Self {
|
||||
let ctx = CreateRowContext {
|
||||
row_id: uuid::Uuid::new_v4().to_string(),
|
||||
cell_by_field_id: Default::default(),
|
||||
|
@ -1,7 +1,8 @@
|
||||
use crate::services::row::stringify_deserialize;
|
||||
use flowy_grid_data_model::entities::{Cell, CellMeta, Field, Row, RowMeta, RowOrder};
|
||||
use crate::services::row::deserialize_cell_data;
|
||||
use flowy_grid_data_model::entities::{Cell, CellMeta, FieldMeta, Row, RowMeta, RowOrder};
|
||||
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub(crate) struct RowIdsPerBlock {
|
||||
pub(crate) block_id: String,
|
||||
@ -21,15 +22,16 @@ pub(crate) fn make_row_ids_per_block(row_orders: &[RowOrder]) -> Vec<RowIdsPerBl
|
||||
map.into_values().collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
pub(crate) fn make_rows(fields: &[Field], row_metas: Vec<RowMeta>) -> Vec<Row> {
|
||||
pub(crate) fn make_rows(fields: &[FieldMeta], row_metas: Vec<Arc<RowMeta>>) -> Vec<Row> {
|
||||
let field_map = fields
|
||||
.iter()
|
||||
.map(|field| (&field.id, field))
|
||||
.collect::<HashMap<&String, &Field>>();
|
||||
.collect::<HashMap<&String, &FieldMeta>>();
|
||||
|
||||
let make_row = |row_meta: RowMeta| {
|
||||
let make_row = |row_meta: Arc<RowMeta>| {
|
||||
let cell_by_field_id = row_meta
|
||||
.cell_by_field_id
|
||||
.clone()
|
||||
.into_par_iter()
|
||||
.flat_map(|(field_id, raw_cell)| make_cell(&field_map, field_id, raw_cell))
|
||||
.collect::<HashMap<String, Cell>>();
|
||||
@ -45,9 +47,9 @@ pub(crate) fn make_rows(fields: &[Field], row_metas: Vec<RowMeta>) -> Vec<Row> {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn make_cell(field_map: &HashMap<&String, &Field>, field_id: String, raw_cell: CellMeta) -> Option<(String, Cell)> {
|
||||
let field = field_map.get(&field_id)?;
|
||||
match stringify_deserialize(raw_cell.data, field) {
|
||||
fn make_cell(field_map: &HashMap<&String, &FieldMeta>, field_id: String, raw_cell: CellMeta) -> Option<(String, Cell)> {
|
||||
let field_meta = field_map.get(&field_id)?;
|
||||
match deserialize_cell_data(raw_cell.data, field_meta) {
|
||||
Ok(content) => {
|
||||
let cell = Cell::new(&field_id, content);
|
||||
Some((field_id, cell))
|
||||
@ -59,15 +61,16 @@ fn make_cell(field_map: &HashMap<&String, &Field>, field_id: String, raw_cell: C
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn make_row_by_row_id(fields: &[Field], row_metas: Vec<RowMeta>) -> HashMap<String, Row> {
|
||||
pub(crate) fn make_row_by_row_id(fields: &[FieldMeta], row_metas: Vec<Arc<RowMeta>>) -> HashMap<String, Row> {
|
||||
let field_map = fields
|
||||
.iter()
|
||||
.map(|field| (&field.id, field))
|
||||
.collect::<HashMap<&String, &Field>>();
|
||||
.collect::<HashMap<&String, &FieldMeta>>();
|
||||
|
||||
let make_row = |row_meta: RowMeta| {
|
||||
let make_row = |row_meta: Arc<RowMeta>| {
|
||||
let cell_by_field_id = row_meta
|
||||
.cell_by_field_id
|
||||
.clone()
|
||||
.into_par_iter()
|
||||
.flat_map(|(field_id, raw_cell)| make_cell(&field_map, field_id, raw_cell))
|
||||
.collect::<HashMap<String, Cell>>();
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::grid::script::EditorScript::*;
|
||||
use crate::grid::script::*;
|
||||
use flowy_grid::services::cell::*;
|
||||
use flowy_grid::services::row::{CreateRowContextBuilder, StringifyCellData};
|
||||
use flowy_grid::services::row::{deserialize_cell_data, serialize_cell_data, CellDataSerde, CreateRowContextBuilder};
|
||||
use flowy_grid_data_model::entities::{FieldChangeset, FieldType, GridBlock, GridBlockChangeset, RowMetaChangeset};
|
||||
|
||||
#[tokio::test]
|
||||
@ -17,19 +17,19 @@ async fn grid_create_field() {
|
||||
let scripts = vec![
|
||||
AssertFieldCount(2),
|
||||
CreateField {
|
||||
field: text_field.clone(),
|
||||
field_meta: text_field.clone(),
|
||||
},
|
||||
AssertFieldEqual {
|
||||
field_index: 2,
|
||||
field: text_field,
|
||||
field_meta: text_field,
|
||||
},
|
||||
AssertFieldCount(3),
|
||||
CreateField {
|
||||
field: single_select_field.clone(),
|
||||
field_meta: single_select_field.clone(),
|
||||
},
|
||||
AssertFieldEqual {
|
||||
field_index: 3,
|
||||
field: single_select_field,
|
||||
field_meta: single_select_field,
|
||||
},
|
||||
AssertFieldCount(4),
|
||||
];
|
||||
@ -42,11 +42,11 @@ async fn grid_create_duplicate_field() {
|
||||
let scripts = vec![
|
||||
AssertFieldCount(2),
|
||||
CreateField {
|
||||
field: text_field.clone(),
|
||||
field_meta: text_field.clone(),
|
||||
},
|
||||
AssertFieldCount(3),
|
||||
CreateField {
|
||||
field: text_field.clone(),
|
||||
field_meta: text_field.clone(),
|
||||
},
|
||||
AssertFieldCount(3),
|
||||
];
|
||||
@ -69,12 +69,12 @@ async fn grid_update_field_with_empty_change() {
|
||||
|
||||
let scripts = vec![
|
||||
CreateField {
|
||||
field: single_select_field.clone(),
|
||||
field_meta: single_select_field.clone(),
|
||||
},
|
||||
UpdateField { changeset },
|
||||
AssertFieldEqual {
|
||||
field_index: 2,
|
||||
field: single_select_field,
|
||||
field_meta: single_select_field,
|
||||
},
|
||||
];
|
||||
GridEditorTest::new().await.run_scripts(scripts).await;
|
||||
@ -105,12 +105,12 @@ async fn grid_update_field() {
|
||||
|
||||
let scripts = vec![
|
||||
CreateField {
|
||||
field: single_select_field.clone(),
|
||||
field_meta: single_select_field.clone(),
|
||||
},
|
||||
UpdateField { changeset },
|
||||
AssertFieldEqual {
|
||||
field_index: 2,
|
||||
field: cloned_field,
|
||||
field_meta: cloned_field,
|
||||
},
|
||||
AssertGridMetaPad,
|
||||
];
|
||||
@ -122,10 +122,10 @@ async fn grid_delete_field() {
|
||||
let text_field = create_text_field();
|
||||
let scripts = vec![
|
||||
CreateField {
|
||||
field: text_field.clone(),
|
||||
field_meta: text_field.clone(),
|
||||
},
|
||||
AssertFieldCount(3),
|
||||
DeleteField { field: text_field },
|
||||
DeleteField { field_meta: text_field },
|
||||
AssertFieldCount(2),
|
||||
];
|
||||
GridEditorTest::new().await.run_scripts(scripts).await;
|
||||
@ -177,7 +177,7 @@ async fn grid_create_row() {
|
||||
#[tokio::test]
|
||||
async fn grid_create_row2() {
|
||||
let mut test = GridEditorTest::new().await;
|
||||
let create_row_context = CreateRowContextBuilder::new(&test.fields).build();
|
||||
let create_row_context = CreateRowContextBuilder::new(&test.field_metas).build();
|
||||
let scripts = vec![
|
||||
AssertRowCount(3),
|
||||
CreateRow {
|
||||
@ -191,7 +191,7 @@ async fn grid_create_row2() {
|
||||
#[tokio::test]
|
||||
async fn grid_update_row() {
|
||||
let mut test = GridEditorTest::new().await;
|
||||
let context = CreateRowContextBuilder::new(&test.fields).build();
|
||||
let context = CreateRowContextBuilder::new(&test.field_metas).build();
|
||||
let changeset = RowMetaChangeset {
|
||||
row_id: context.row_id.clone(),
|
||||
height: None,
|
||||
@ -214,8 +214,8 @@ async fn grid_update_row() {
|
||||
#[tokio::test]
|
||||
async fn grid_delete_row() {
|
||||
let mut test = GridEditorTest::new().await;
|
||||
let context_1 = CreateRowContextBuilder::new(&test.fields).build();
|
||||
let context_2 = CreateRowContextBuilder::new(&test.fields).build();
|
||||
let context_1 = CreateRowContextBuilder::new(&test.field_metas).build();
|
||||
let context_2 = CreateRowContextBuilder::new(&test.field_metas).build();
|
||||
let row_ids = vec![context_1.row_id.clone(), context_2.row_id.clone()];
|
||||
let scripts = vec![
|
||||
AssertRowCount(3),
|
||||
@ -240,26 +240,26 @@ async fn grid_delete_row() {
|
||||
#[tokio::test]
|
||||
async fn grid_update_cell() {
|
||||
let mut test = GridEditorTest::new().await;
|
||||
let mut builder = CreateRowContextBuilder::new(&test.fields);
|
||||
for field in &test.fields {
|
||||
let mut builder = CreateRowContextBuilder::new(&test.field_metas);
|
||||
for field in &test.field_metas {
|
||||
match field.field_type {
|
||||
FieldType::RichText => {
|
||||
builder = builder.add_cell(&field.id, "hello world".to_owned());
|
||||
let data = serialize_cell_data("hello world", field).unwrap();
|
||||
builder = builder.add_cell(&field.id, data);
|
||||
}
|
||||
FieldType::Number => {
|
||||
let description = NumberDescription::from(field);
|
||||
let data = description.str_to_cell_data("¥18,443").unwrap();
|
||||
let data = serialize_cell_data("¥18,443", field).unwrap();
|
||||
builder = builder.add_cell(&field.id, data);
|
||||
}
|
||||
FieldType::DateTime => {
|
||||
let description = DateDescription::from(field);
|
||||
let data = description.str_to_cell_data("1647251762").unwrap();
|
||||
let data = serialize_cell_data("1647251762", field).unwrap();
|
||||
builder = builder.add_cell(&field.id, data);
|
||||
}
|
||||
FieldType::SingleSelect => {
|
||||
let description = SingleSelectDescription::from(field);
|
||||
let options = description.options.first().unwrap();
|
||||
let data = description.str_to_cell_data(&options.id).unwrap();
|
||||
|
||||
let data = description.serialize_cell_data(&options.id).unwrap();
|
||||
builder = builder.add_cell(&field.id, data);
|
||||
}
|
||||
FieldType::MultiSelect => {
|
||||
@ -270,12 +270,11 @@ async fn grid_update_cell() {
|
||||
.map(|option| option.id.clone())
|
||||
.collect::<Vec<_>>()
|
||||
.join(",");
|
||||
let data = description.str_to_cell_data(&options).unwrap();
|
||||
let data = description.serialize_cell_data(&options).unwrap();
|
||||
builder = builder.add_cell(&field.id, data);
|
||||
}
|
||||
FieldType::Checkbox => {
|
||||
let description = CheckboxDescription::from(field);
|
||||
let data = description.str_to_cell_data("false").unwrap();
|
||||
let data = serialize_cell_data("false", field).unwrap();
|
||||
builder = builder.add_cell(&field.id, data);
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ use flowy_grid::services::field::*;
|
||||
use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder};
|
||||
use flowy_grid::services::row::CreateRowContext;
|
||||
use flowy_grid_data_model::entities::{
|
||||
CellMetaChangeset, Field, FieldChangeset, FieldType, GridBlock, GridBlockChangeset, RowMeta, RowMetaChangeset,
|
||||
CellMetaChangeset, FieldChangeset, FieldMeta, FieldType, GridBlock, GridBlockChangeset, RowMeta, RowMetaChangeset,
|
||||
};
|
||||
use flowy_sync::REVISION_WRITE_INTERVAL_IN_MILLIS;
|
||||
use flowy_test::helper::ViewTest;
|
||||
@ -14,18 +14,18 @@ use tokio::time::sleep;
|
||||
|
||||
pub enum EditorScript {
|
||||
CreateField {
|
||||
field: Field,
|
||||
field_meta: FieldMeta,
|
||||
},
|
||||
UpdateField {
|
||||
changeset: FieldChangeset,
|
||||
},
|
||||
DeleteField {
|
||||
field: Field,
|
||||
field_meta: FieldMeta,
|
||||
},
|
||||
AssertFieldCount(usize),
|
||||
AssertFieldEqual {
|
||||
field_index: usize,
|
||||
field: Field,
|
||||
field_meta: FieldMeta,
|
||||
},
|
||||
CreateBlock {
|
||||
block: GridBlock,
|
||||
@ -68,27 +68,31 @@ pub struct GridEditorTest {
|
||||
pub sdk: FlowySDKTest,
|
||||
pub grid_id: String,
|
||||
pub editor: Arc<ClientGridEditor>,
|
||||
pub fields: Vec<Field>,
|
||||
pub field_metas: Vec<FieldMeta>,
|
||||
pub grid_blocks: Vec<GridBlock>,
|
||||
pub row_metas: Vec<RowMeta>,
|
||||
pub row_metas: Vec<Arc<RowMeta>>,
|
||||
}
|
||||
|
||||
impl GridEditorTest {
|
||||
pub async fn new() -> Self {
|
||||
Self::with_data("".to_owned()).await
|
||||
}
|
||||
|
||||
pub async fn with_data(data: String) -> Self {
|
||||
let sdk = FlowySDKTest::default();
|
||||
let _ = sdk.init_user().await;
|
||||
let test = ViewTest::new_grid_view(&sdk).await;
|
||||
let test = ViewTest::new_grid_view(&sdk, data).await;
|
||||
let editor = sdk.grid_manager.open_grid(&test.view.id).await.unwrap();
|
||||
let fields = editor.get_fields(None).await.unwrap();
|
||||
let fields = editor.get_field_metas(None).await.unwrap();
|
||||
let grid_blocks = editor.get_blocks().await.unwrap();
|
||||
let row_metas = editor.get_row_metas(&None).await.unwrap();
|
||||
let row_metas = editor.get_row_metas(None).await.unwrap();
|
||||
|
||||
let grid_id = test.view.id;
|
||||
Self {
|
||||
sdk,
|
||||
grid_id,
|
||||
editor,
|
||||
fields,
|
||||
field_metas: fields,
|
||||
grid_blocks,
|
||||
row_metas,
|
||||
}
|
||||
@ -107,26 +111,28 @@ impl GridEditorTest {
|
||||
let _cache = rev_manager.revision_cache().await;
|
||||
|
||||
match script {
|
||||
EditorScript::CreateField { field } => {
|
||||
EditorScript::CreateField { field_meta: field } => {
|
||||
self.editor.create_field(field).await.unwrap();
|
||||
self.fields = self.editor.get_fields(None).await.unwrap();
|
||||
self.field_metas = self.editor.get_field_metas(None).await.unwrap();
|
||||
}
|
||||
EditorScript::UpdateField { changeset: change } => {
|
||||
self.editor.update_field(change).await.unwrap();
|
||||
self.fields = self.editor.get_fields(None).await.unwrap();
|
||||
self.field_metas = self.editor.get_field_metas(None).await.unwrap();
|
||||
}
|
||||
EditorScript::DeleteField { field } => {
|
||||
EditorScript::DeleteField { field_meta: field } => {
|
||||
self.editor.delete_field(&field.id).await.unwrap();
|
||||
self.fields = self.editor.get_fields(None).await.unwrap();
|
||||
self.field_metas = self.editor.get_field_metas(None).await.unwrap();
|
||||
}
|
||||
EditorScript::AssertFieldCount(count) => {
|
||||
assert_eq!(self.editor.get_fields(None).await.unwrap().len(), count);
|
||||
assert_eq!(self.editor.get_field_metas(None).await.unwrap().len(), count);
|
||||
}
|
||||
|
||||
EditorScript::AssertFieldEqual { field_index, field } => {
|
||||
let repeated_fields = self.editor.get_fields(None).await.unwrap();
|
||||
let compared_field = repeated_fields[field_index].clone();
|
||||
assert_eq!(compared_field, field);
|
||||
EditorScript::AssertFieldEqual {
|
||||
field_index,
|
||||
field_meta,
|
||||
} => {
|
||||
let field_metas = self.editor.get_field_metas(None).await.unwrap();
|
||||
assert_eq!(field_metas[field_index].clone(), field_meta);
|
||||
}
|
||||
EditorScript::CreateBlock { block } => {
|
||||
self.editor.create_block(block).await.unwrap();
|
||||
@ -153,18 +159,18 @@ impl GridEditorTest {
|
||||
}
|
||||
EditorScript::CreateEmptyRow => {
|
||||
self.editor.create_row().await.unwrap();
|
||||
self.row_metas = self.editor.get_row_metas(&None).await.unwrap();
|
||||
self.row_metas = self.editor.get_row_metas(None).await.unwrap();
|
||||
self.grid_blocks = self.editor.get_blocks().await.unwrap();
|
||||
}
|
||||
EditorScript::CreateRow { context } => {
|
||||
self.editor.insert_rows(vec![context]).await.unwrap();
|
||||
self.row_metas = self.editor.get_row_metas(&None).await.unwrap();
|
||||
self.row_metas = self.editor.get_row_metas(None).await.unwrap();
|
||||
self.grid_blocks = self.editor.get_blocks().await.unwrap();
|
||||
}
|
||||
EditorScript::UpdateRow { changeset: change } => self.editor.update_row(change).await.unwrap(),
|
||||
EditorScript::DeleteRow { row_ids } => {
|
||||
self.editor.delete_rows(row_ids).await.unwrap();
|
||||
self.row_metas = self.editor.get_row_metas(&None).await.unwrap();
|
||||
self.row_metas = self.editor.get_row_metas(None).await.unwrap();
|
||||
self.grid_blocks = self.editor.get_blocks().await.unwrap();
|
||||
}
|
||||
EditorScript::AssertRow { changeset } => {
|
||||
@ -180,7 +186,7 @@ impl GridEditorTest {
|
||||
}
|
||||
EditorScript::UpdateCell { changeset } => {
|
||||
self.editor.update_cell(changeset).await.unwrap();
|
||||
self.row_metas = self.editor.get_row_metas(&None).await.unwrap();
|
||||
self.row_metas = self.editor.get_row_metas(None).await.unwrap();
|
||||
}
|
||||
EditorScript::AssertRowCount(count) => {
|
||||
assert_eq!(self.editor.get_rows(None).await.unwrap().len(), count);
|
||||
@ -195,7 +201,7 @@ impl GridEditorTest {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_text_field() -> Field {
|
||||
pub fn create_text_field() -> FieldMeta {
|
||||
FieldBuilder::new(RichTextTypeOptionsBuilder::default())
|
||||
.name("Name")
|
||||
.visibility(true)
|
||||
@ -203,7 +209,7 @@ pub fn create_text_field() -> Field {
|
||||
.build()
|
||||
}
|
||||
|
||||
pub fn create_single_select_field() -> Field {
|
||||
pub fn create_single_select_field() -> FieldMeta {
|
||||
let single_select = SingleSelectTypeOptionsBuilder::default()
|
||||
.option(SelectOption::new("Done"))
|
||||
.option(SelectOption::new("Progress"));
|
||||
|
@ -308,7 +308,7 @@ impl FolderCouldServiceV1 for LocalServer {
|
||||
belongings: RepeatedView::default(),
|
||||
modified_time: time,
|
||||
create_time: time,
|
||||
ext_data: params.ext_data,
|
||||
ext_data: "".to_string(),
|
||||
thumbnail: params.thumbnail,
|
||||
plugin_type: params.plugin_type,
|
||||
};
|
||||
|
@ -26,11 +26,11 @@ pub struct ViewTest {
|
||||
|
||||
impl ViewTest {
|
||||
#[allow(dead_code)]
|
||||
pub async fn new(sdk: &FlowySDKTest, data_type: ViewDataType) -> Self {
|
||||
pub async fn new(sdk: &FlowySDKTest, data_type: ViewDataType, data: String) -> Self {
|
||||
let workspace = create_workspace(sdk, "Workspace", "").await;
|
||||
open_workspace(sdk, &workspace.id).await;
|
||||
let app = create_app(sdk, "App", "AppFlowy GitHub Project", &workspace.id).await;
|
||||
let view = create_view(sdk, &app.id, data_type).await;
|
||||
let view = create_view(sdk, &app.id, data_type, data).await;
|
||||
Self {
|
||||
sdk: sdk.clone(),
|
||||
workspace,
|
||||
@ -39,14 +39,12 @@ impl ViewTest {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub async fn new_grid_view(sdk: &FlowySDKTest) -> Self {
|
||||
Self::new(sdk, ViewDataType::Grid).await
|
||||
pub async fn new_grid_view(sdk: &FlowySDKTest, data: String) -> Self {
|
||||
Self::new(sdk, ViewDataType::Grid, data).await
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub async fn new_text_block_view(sdk: &FlowySDKTest) -> Self {
|
||||
Self::new(sdk, ViewDataType::TextBlock).await
|
||||
Self::new(sdk, ViewDataType::TextBlock, "".to_owned()).await
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,15 +91,15 @@ async fn create_app(sdk: &FlowySDKTest, name: &str, desc: &str, workspace_id: &s
|
||||
app
|
||||
}
|
||||
|
||||
async fn create_view(sdk: &FlowySDKTest, app_id: &str, data_type: ViewDataType) -> View {
|
||||
async fn create_view(sdk: &FlowySDKTest, app_id: &str, data_type: ViewDataType, data: String) -> View {
|
||||
let request = CreateViewPayload {
|
||||
belong_to_id: app_id.to_string(),
|
||||
name: "View A".to_string(),
|
||||
desc: "".to_string(),
|
||||
thumbnail: Some("http://1.png".to_string()),
|
||||
data_type,
|
||||
ext_data: "".to_string(),
|
||||
plugin_type: 0,
|
||||
data,
|
||||
};
|
||||
|
||||
let view = FolderEventBuilder::new(sdk.clone())
|
||||
|
Reference in New Issue
Block a user