mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: update grid test
This commit is contained in:
1
frontend/rust-lib/Cargo.lock
generated
1
frontend/rust-lib/Cargo.lock
generated
@ -1147,6 +1147,7 @@ dependencies = [
|
||||
"flowy-database",
|
||||
"flowy-folder",
|
||||
"flowy-grid",
|
||||
"flowy-grid-data-model",
|
||||
"flowy-net",
|
||||
"flowy-sync",
|
||||
"flowy-user",
|
||||
|
@ -175,7 +175,7 @@ impl EditBlockQueue {
|
||||
}
|
||||
|
||||
async fn save_local_delta(&self, delta: RichTextDelta, md5: String) -> Result<RevId, FlowyError> {
|
||||
let delta_data = delta.to_bytes();
|
||||
let delta_data = delta.to_delta_bytes();
|
||||
let (base_rev_id, rev_id) = self.rev_manager.next_rev_id_pair();
|
||||
let user_id = self.user.user_id()?;
|
||||
let revision = Revision::new(
|
||||
@ -198,7 +198,7 @@ pub(crate) struct TextBlockRevisionCompactor();
|
||||
impl RevisionCompactor for TextBlockRevisionCompactor {
|
||||
fn bytes_from_revisions(&self, revisions: Vec<Revision>) -> FlowyResult<Bytes> {
|
||||
let delta = make_delta_from_revisions::<RichTextAttributes>(revisions)?;
|
||||
Ok(delta.to_bytes())
|
||||
Ok(delta.to_delta_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -245,9 +245,11 @@ pub trait ViewDataProcessor {
|
||||
|
||||
fn close_container(&self, view_id: &str) -> FutureResult<(), FlowyError>;
|
||||
|
||||
fn delta_str(&self, view_id: &str) -> FutureResult<String, FlowyError>;
|
||||
fn delta_bytes(&self, view_id: &str) -> FutureResult<Bytes, FlowyError>;
|
||||
|
||||
fn create_default_view(&self, user_id: &str, view_id: &str) -> FutureResult<String, FlowyError>;
|
||||
fn create_default_view(&self, user_id: &str, view_id: &str) -> FutureResult<Bytes, FlowyError>;
|
||||
|
||||
fn process_create_view_data(&self, user_id: &str, view_id: &str, data: Vec<u8>) -> FutureResult<Bytes, FlowyError>;
|
||||
|
||||
fn data_type(&self) -> ViewDataType;
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ impl ClientFolderEditor {
|
||||
pub(crate) fn apply_change(&self, change: FolderChange) -> FlowyResult<()> {
|
||||
let FolderChange { delta, md5 } = change;
|
||||
let (base_rev_id, rev_id) = self.rev_manager.next_rev_id_pair();
|
||||
let delta_data = delta.to_bytes();
|
||||
let delta_data = delta.to_delta_bytes();
|
||||
let revision = Revision::new(
|
||||
&self.rev_manager.object_id,
|
||||
base_rev_id,
|
||||
@ -128,6 +128,6 @@ struct FolderRevisionCompactor();
|
||||
impl RevisionCompactor for FolderRevisionCompactor {
|
||||
fn bytes_from_revisions(&self, revisions: Vec<Revision>) -> FlowyResult<Bytes> {
|
||||
let delta = make_delta_from_revisions::<PlainTextAttributes>(revisions)?;
|
||||
Ok(delta.to_bytes())
|
||||
Ok(delta.to_delta_bytes())
|
||||
}
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ impl FolderPersistence {
|
||||
|
||||
pub async fn save_folder(&self, user_id: &str, folder_id: &FolderId, folder: FolderPad) -> FlowyResult<()> {
|
||||
let pool = self.database.db_pool()?;
|
||||
let delta_data = initial_folder_delta(&folder)?.to_bytes();
|
||||
let delta_data = initial_folder_delta(&folder)?.to_delta_bytes();
|
||||
let md5 = folder.md5();
|
||||
let revision = Revision::new(folder_id.as_ref(), 0, 0, delta_data, user_id, md5);
|
||||
let record = RevisionRecord {
|
||||
|
@ -55,13 +55,14 @@ impl ViewController {
|
||||
#[tracing::instrument(level = "trace", skip(self, params), fields(name = %params.name), err)]
|
||||
pub(crate) async fn create_view_from_params(&self, mut params: CreateViewParams) -> Result<View, FlowyError> {
|
||||
let processor = self.get_data_processor(¶ms.data_type)?;
|
||||
|
||||
let user_id = self.user.user_id()?;
|
||||
if params.data.is_empty() {
|
||||
let user_id = self.user.user_id()?;
|
||||
let view_data = processor.create_default_view(&user_id, ¶ms.view_id).await?;
|
||||
params.data = view_data;
|
||||
params.data = view_data.to_vec();
|
||||
} else {
|
||||
let delta_data = Bytes::from(params.data.clone());
|
||||
let delta_data = processor
|
||||
.process_create_view_data(&user_id, ¶ms.view_id, params.data.clone())
|
||||
.await?;
|
||||
let _ = self
|
||||
.create_view(¶ms.view_id, params.data_type.clone(), delta_data)
|
||||
.await?;
|
||||
@ -162,14 +163,14 @@ impl ViewController {
|
||||
.await?;
|
||||
|
||||
let processor = self.get_data_processor(&view.data_type)?;
|
||||
let delta_str = processor.delta_str(view_id).await?;
|
||||
let delta_bytes = processor.delta_bytes(view_id).await?;
|
||||
let duplicate_params = CreateViewParams {
|
||||
belong_to_id: view.belong_to_id.clone(),
|
||||
name: format!("{} (copy)", &view.name),
|
||||
desc: view.desc,
|
||||
thumbnail: view.thumbnail,
|
||||
data_type: view.data_type,
|
||||
data: delta_str,
|
||||
data: delta_bytes.to_vec(),
|
||||
view_id: uuid(),
|
||||
plugin_type: view.plugin_type,
|
||||
};
|
||||
|
@ -1,8 +1,11 @@
|
||||
use crate::services::grid_editor::ClientGridEditor;
|
||||
use crate::services::kv_persistence::GridKVPersistence;
|
||||
use bytes::Bytes;
|
||||
use dashmap::DashMap;
|
||||
use flowy_collaboration::entities::revision::RepeatedRevision;
|
||||
use flowy_collaboration::client_grid::{make_block_meta_delta, make_grid_delta};
|
||||
use flowy_collaboration::entities::revision::{RepeatedRevision, Revision};
|
||||
use flowy_error::{FlowyError, FlowyResult};
|
||||
use flowy_grid_data_model::entities::{BuildGridContext, GridMeta};
|
||||
use flowy_sync::disk::{SQLiteGridBlockMetaRevisionPersistence, SQLiteGridRevisionPersistence};
|
||||
use flowy_sync::{RevisionManager, RevisionPersistence, RevisionWebSocket};
|
||||
use lib_sqlite::ConnectionPool;
|
||||
@ -172,3 +175,33 @@ impl GridEditorMap {
|
||||
self.inner.remove(grid_id);
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn make_grid_view_data(
|
||||
user_id: &str,
|
||||
view_id: &str,
|
||||
grid_manager: Arc<GridManager>,
|
||||
build_context: BuildGridContext,
|
||||
) -> FlowyResult<Bytes> {
|
||||
let block_id = build_context.grid_block.id.clone();
|
||||
let grid_meta = GridMeta {
|
||||
grid_id: view_id.to_string(),
|
||||
fields: build_context.field_metas,
|
||||
blocks: vec![build_context.grid_block],
|
||||
};
|
||||
|
||||
let grid_meta_delta = make_grid_delta(&grid_meta);
|
||||
let grid_delta_data = grid_meta_delta.to_delta_bytes();
|
||||
let repeated_revision: RepeatedRevision =
|
||||
Revision::initial_revision(user_id, view_id, grid_delta_data.clone()).into();
|
||||
let _ = grid_manager.create_grid(view_id, repeated_revision).await?;
|
||||
|
||||
let grid_block_meta_delta = make_block_meta_delta(&build_context.grid_block_meta);
|
||||
let block_meta_delta_data = grid_block_meta_delta.to_delta_bytes();
|
||||
let repeated_revision: RepeatedRevision =
|
||||
Revision::initial_revision(&user_id, &block_id, block_meta_delta_data).into();
|
||||
let _ = grid_manager
|
||||
.create_grid_block_meta(&block_id, repeated_revision)
|
||||
.await?;
|
||||
|
||||
Ok(grid_delta_data)
|
||||
}
|
||||
|
@ -280,7 +280,7 @@ impl ClientGridBlockMetaEditor {
|
||||
let GridBlockMetaChange { delta, md5 } = change;
|
||||
let user_id = self.user_id.clone();
|
||||
let (base_rev_id, rev_id) = self.rev_manager.next_rev_id_pair();
|
||||
let delta_data = delta.to_bytes();
|
||||
let delta_data = delta.to_delta_bytes();
|
||||
let revision = Revision::new(
|
||||
&self.rev_manager.object_id,
|
||||
base_rev_id,
|
||||
@ -323,6 +323,6 @@ struct GridBlockMetaRevisionCompactor();
|
||||
impl RevisionCompactor for GridBlockMetaRevisionCompactor {
|
||||
fn bytes_from_revisions(&self, revisions: Vec<Revision>) -> FlowyResult<Bytes> {
|
||||
let delta = make_delta_from_revisions::<PlainTextAttributes>(revisions)?;
|
||||
Ok(delta.to_bytes())
|
||||
Ok(delta.to_delta_bytes())
|
||||
}
|
||||
}
|
||||
|
@ -61,6 +61,10 @@ impl ClientGridEditor {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn contain_field(&self, field_meta: &FieldMeta) -> bool {
|
||||
self.grid_meta_pad.read().await.contain_field(&field_meta.id)
|
||||
}
|
||||
|
||||
pub async fn update_field(&self, change: FieldChangeset) -> FlowyResult<()> {
|
||||
let _ = self.modify(|grid| Ok(grid.update_field(change)?)).await?;
|
||||
Ok(())
|
||||
@ -177,8 +181,8 @@ impl ClientGridEditor {
|
||||
Ok(grid_blocks)
|
||||
}
|
||||
|
||||
pub async fn delta_str(&self) -> String {
|
||||
self.grid_meta_pad.read().await.delta_str()
|
||||
pub async fn delta_bytes(&self) -> Bytes {
|
||||
self.grid_meta_pad.read().await.delta_bytes()
|
||||
}
|
||||
|
||||
async fn modify<F>(&self, f: F) -> FlowyResult<()>
|
||||
@ -199,7 +203,7 @@ impl ClientGridEditor {
|
||||
let GridChange { delta, md5 } = change;
|
||||
let user_id = self.user.user_id()?;
|
||||
let (base_rev_id, rev_id) = self.rev_manager.next_rev_id_pair();
|
||||
let delta_data = delta.to_bytes();
|
||||
let delta_data = delta.to_delta_bytes();
|
||||
let revision = Revision::new(
|
||||
&self.rev_manager.object_id,
|
||||
base_rev_id,
|
||||
@ -256,6 +260,6 @@ struct GridRevisionCompactor();
|
||||
impl RevisionCompactor for GridRevisionCompactor {
|
||||
fn bytes_from_revisions(&self, revisions: Vec<Revision>) -> FlowyResult<Bytes> {
|
||||
let delta = make_delta_from_revisions::<PlainTextAttributes>(revisions)?;
|
||||
Ok(delta.to_bytes())
|
||||
Ok(delta.to_delta_bytes())
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
use crate::services::cell::*;
|
||||
use crate::services::field::*;
|
||||
use flowy_collaboration::client_grid::{BuildGridInfo, GridBuilder};
|
||||
use flowy_grid_data_model::entities::FieldType;
|
||||
use flowy_collaboration::client_grid::GridBuilder;
|
||||
use flowy_grid_data_model::entities::{BuildGridContext, FieldType};
|
||||
|
||||
pub fn make_default_grid(grid_id: &str) -> BuildGridInfo {
|
||||
pub fn make_default_grid() -> BuildGridContext {
|
||||
let text_field = FieldBuilder::new(RichTextTypeOptionsBuilder::default())
|
||||
.name("Name")
|
||||
.visibility(true)
|
||||
@ -20,12 +20,11 @@ pub fn make_default_grid(grid_id: &str) -> BuildGridInfo {
|
||||
.field_type(FieldType::SingleSelect)
|
||||
.build();
|
||||
|
||||
GridBuilder::new(grid_id)
|
||||
GridBuilder::default()
|
||||
.add_field(text_field)
|
||||
.add_field(single_select_field)
|
||||
.add_empty_row()
|
||||
.add_empty_row()
|
||||
.add_empty_row()
|
||||
.build()
|
||||
.unwrap()
|
||||
}
|
||||
|
@ -4,57 +4,56 @@ use flowy_grid::services::cell::*;
|
||||
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]
|
||||
async fn default_grid_test() {
|
||||
let scripts = vec![AssertFieldCount(2), AssertGridMetaPad];
|
||||
GridEditorTest::new().await.run_scripts(scripts).await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn grid_create_field() {
|
||||
let mut test = GridEditorTest::new().await;
|
||||
let text_field = create_text_field();
|
||||
let single_select_field = create_single_select_field();
|
||||
|
||||
let scripts = vec![
|
||||
AssertFieldCount(2),
|
||||
CreateField {
|
||||
field_meta: text_field.clone(),
|
||||
},
|
||||
AssertFieldEqual {
|
||||
field_index: 2,
|
||||
field_index: test.field_count,
|
||||
field_meta: text_field,
|
||||
},
|
||||
AssertFieldCount(3),
|
||||
];
|
||||
test.run_scripts(scripts).await;
|
||||
|
||||
let scripts = vec![
|
||||
CreateField {
|
||||
field_meta: single_select_field.clone(),
|
||||
},
|
||||
AssertFieldEqual {
|
||||
field_index: 3,
|
||||
field_index: test.field_count,
|
||||
field_meta: single_select_field,
|
||||
},
|
||||
AssertFieldCount(4),
|
||||
];
|
||||
GridEditorTest::new().await.run_scripts(scripts).await;
|
||||
test.run_scripts(scripts).await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn grid_create_duplicate_field() {
|
||||
let mut test = GridEditorTest::new().await;
|
||||
let text_field = create_text_field();
|
||||
let field_count = test.field_count;
|
||||
let expected_field_count = field_count + 1;
|
||||
let scripts = vec![
|
||||
AssertFieldCount(2),
|
||||
CreateField {
|
||||
field_meta: text_field.clone(),
|
||||
},
|
||||
AssertFieldCount(3),
|
||||
CreateField {
|
||||
field_meta: text_field.clone(),
|
||||
},
|
||||
AssertFieldCount(3),
|
||||
AssertFieldCount(expected_field_count),
|
||||
];
|
||||
GridEditorTest::new().await.run_scripts(scripts).await;
|
||||
test.run_scripts(scripts).await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn grid_update_field_with_empty_change() {
|
||||
let mut test = GridEditorTest::new().await;
|
||||
let single_select_field = create_single_select_field();
|
||||
let changeset = FieldChangeset {
|
||||
field_id: single_select_field.id.clone(),
|
||||
@ -73,21 +72,21 @@ async fn grid_update_field_with_empty_change() {
|
||||
},
|
||||
UpdateField { changeset },
|
||||
AssertFieldEqual {
|
||||
field_index: 2,
|
||||
field_index: test.field_count,
|
||||
field_meta: single_select_field,
|
||||
},
|
||||
];
|
||||
GridEditorTest::new().await.run_scripts(scripts).await;
|
||||
test.run_scripts(scripts).await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn grid_update_field() {
|
||||
let mut test = GridEditorTest::new().await;
|
||||
let single_select_field = create_single_select_field();
|
||||
let mut cloned_field = single_select_field.clone();
|
||||
|
||||
let mut single_select_type_options = SingleSelectDescription::from(&single_select_field);
|
||||
single_select_type_options.options.push(SelectOption::new("Unknown"));
|
||||
|
||||
let changeset = FieldChangeset {
|
||||
field_id: single_select_field.id.clone(),
|
||||
name: None,
|
||||
@ -109,26 +108,26 @@ async fn grid_update_field() {
|
||||
},
|
||||
UpdateField { changeset },
|
||||
AssertFieldEqual {
|
||||
field_index: 2,
|
||||
field_index: test.field_count,
|
||||
field_meta: cloned_field,
|
||||
},
|
||||
AssertGridMetaPad,
|
||||
];
|
||||
GridEditorTest::new().await.run_scripts(scripts).await;
|
||||
test.run_scripts(scripts).await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn grid_delete_field() {
|
||||
let mut test = GridEditorTest::new().await;
|
||||
let expected_field_count = test.field_count;
|
||||
let text_field = create_text_field();
|
||||
let scripts = vec![
|
||||
CreateField {
|
||||
field_meta: text_field.clone(),
|
||||
},
|
||||
AssertFieldCount(3),
|
||||
DeleteField { field_meta: text_field },
|
||||
AssertFieldCount(2),
|
||||
AssertFieldCount(expected_field_count),
|
||||
];
|
||||
GridEditorTest::new().await.run_scripts(scripts).await;
|
||||
test.run_scripts(scripts).await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
@ -1,15 +1,22 @@
|
||||
use bytes::Bytes;
|
||||
use flowy_collaboration::client_grid::GridBuilder;
|
||||
use flowy_collaboration::entities::revision::{RepeatedRevision, Revision};
|
||||
use flowy_error::FlowyResult;
|
||||
use flowy_grid::manager::{make_grid_view_data, GridManager};
|
||||
use flowy_grid::services::cell::*;
|
||||
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, FieldChangeset, FieldMeta, FieldType, GridBlock, GridBlockChangeset, RowMeta, RowMetaChangeset,
|
||||
BuildGridContext, CellMetaChangeset, FieldChangeset, FieldMeta, FieldType, GridBlock, GridBlockChangeset, RowMeta,
|
||||
RowMetaChangeset,
|
||||
};
|
||||
use flowy_sync::REVISION_WRITE_INTERVAL_IN_MILLIS;
|
||||
use flowy_test::helper::ViewTest;
|
||||
use flowy_test::FlowySDKTest;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use strum::{EnumCount, IntoEnumIterator};
|
||||
use tokio::time::sleep;
|
||||
|
||||
pub enum EditorScript {
|
||||
@ -71,19 +78,18 @@ pub struct GridEditorTest {
|
||||
pub field_metas: Vec<FieldMeta>,
|
||||
pub grid_blocks: Vec<GridBlock>,
|
||||
pub row_metas: Vec<Arc<RowMeta>>,
|
||||
pub field_count: usize,
|
||||
}
|
||||
|
||||
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, data).await;
|
||||
let build_context = make_template_1_grid();
|
||||
let view_data: Bytes = build_context.try_into().unwrap();
|
||||
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 fields = editor.get_field_metas(None).await.unwrap();
|
||||
let field_metas = 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();
|
||||
|
||||
@ -92,9 +98,10 @@ impl GridEditorTest {
|
||||
sdk,
|
||||
grid_id,
|
||||
editor,
|
||||
field_metas: fields,
|
||||
field_metas,
|
||||
grid_blocks,
|
||||
row_metas,
|
||||
field_count: FieldType::COUNT,
|
||||
}
|
||||
}
|
||||
|
||||
@ -111,22 +118,30 @@ impl GridEditorTest {
|
||||
let _cache = rev_manager.revision_cache().await;
|
||||
|
||||
match script {
|
||||
EditorScript::CreateField { field_meta: field } => {
|
||||
self.editor.create_field(field).await.unwrap();
|
||||
EditorScript::CreateField { field_meta } => {
|
||||
if !self.editor.contain_field(&field_meta).await {
|
||||
self.field_count += 1;
|
||||
}
|
||||
self.editor.create_field(field_meta).await.unwrap();
|
||||
self.field_metas = self.editor.get_field_metas(None).await.unwrap();
|
||||
assert_eq!(self.field_count, self.field_metas.len());
|
||||
}
|
||||
EditorScript::UpdateField { changeset: change } => {
|
||||
self.editor.update_field(change).await.unwrap();
|
||||
self.field_metas = self.editor.get_field_metas(None).await.unwrap();
|
||||
}
|
||||
EditorScript::DeleteField { field_meta: field } => {
|
||||
self.editor.delete_field(&field.id).await.unwrap();
|
||||
EditorScript::DeleteField { field_meta } => {
|
||||
if self.editor.contain_field(&field_meta).await {
|
||||
self.field_count -= 1;
|
||||
}
|
||||
|
||||
self.editor.delete_field(&field_meta.id).await.unwrap();
|
||||
self.field_metas = self.editor.get_field_metas(None).await.unwrap();
|
||||
assert_eq!(self.field_count, self.field_metas.len());
|
||||
}
|
||||
EditorScript::AssertFieldCount(count) => {
|
||||
assert_eq!(self.editor.get_field_metas(None).await.unwrap().len(), count);
|
||||
}
|
||||
|
||||
EditorScript::AssertFieldEqual {
|
||||
field_index,
|
||||
field_meta,
|
||||
@ -220,3 +235,72 @@ pub fn create_single_select_field() -> FieldMeta {
|
||||
.field_type(FieldType::SingleSelect)
|
||||
.build()
|
||||
}
|
||||
|
||||
fn make_template_1_grid() -> BuildGridContext {
|
||||
let text_field = FieldBuilder::new(RichTextTypeOptionsBuilder::default())
|
||||
.name("Name")
|
||||
.visibility(true)
|
||||
.field_type(FieldType::RichText)
|
||||
.build();
|
||||
|
||||
// Single Select
|
||||
let single_select = SingleSelectTypeOptionsBuilder::default()
|
||||
.option(SelectOption::new("Live"))
|
||||
.option(SelectOption::new("Completed"))
|
||||
.option(SelectOption::new("Planned"))
|
||||
.option(SelectOption::new("Paused"));
|
||||
let single_select_field = FieldBuilder::new(single_select)
|
||||
.name("Status")
|
||||
.visibility(true)
|
||||
.field_type(FieldType::SingleSelect)
|
||||
.build();
|
||||
|
||||
// MultiSelect
|
||||
let multi_select = MultiSelectTypeOptionsBuilder::default()
|
||||
.option(SelectOption::new("Google"))
|
||||
.option(SelectOption::new("Facebook"))
|
||||
.option(SelectOption::new("Twitter"));
|
||||
let multi_select_field = FieldBuilder::new(multi_select)
|
||||
.name("Platform")
|
||||
.visibility(true)
|
||||
.field_type(FieldType::MultiSelect)
|
||||
.build();
|
||||
|
||||
// Number
|
||||
let number = NumberTypeOptionsBuilder::default().set_format(NumberFormat::USD);
|
||||
let number_field = FieldBuilder::new(number)
|
||||
.name("Price")
|
||||
.visibility(true)
|
||||
.field_type(FieldType::Number)
|
||||
.build();
|
||||
|
||||
// Date
|
||||
let date = DateTypeOptionsBuilder::default()
|
||||
.date_format(DateFormat::US)
|
||||
.time_format(TimeFormat::TwentyFourHour);
|
||||
let date_field = FieldBuilder::new(date)
|
||||
.name("Time")
|
||||
.visibility(true)
|
||||
.field_type(FieldType::DateTime)
|
||||
.build();
|
||||
|
||||
// Checkbox
|
||||
let checkbox = CheckboxTypeOptionsBuilder::default();
|
||||
let checkbox_field = FieldBuilder::new(checkbox)
|
||||
.name("is done")
|
||||
.visibility(true)
|
||||
.field_type(FieldType::Checkbox)
|
||||
.build();
|
||||
|
||||
GridBuilder::default()
|
||||
.add_field(text_field)
|
||||
.add_field(single_select_field)
|
||||
.add_field(multi_select_field)
|
||||
.add_field(number_field)
|
||||
.add_field(date_field)
|
||||
.add_field(checkbox_field)
|
||||
.add_empty_row()
|
||||
.add_empty_row()
|
||||
.add_empty_row()
|
||||
.build()
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ flowy-user = { path = "../flowy-user" }
|
||||
flowy-net = { path = "../flowy-net" }
|
||||
flowy-folder = { path = "../flowy-folder", default-features = false }
|
||||
flowy-grid = { path = "../flowy-grid", default-features = false }
|
||||
flowy-grid-data-model = { path = "../../../shared-lib/flowy-grid-data-model" }
|
||||
flowy-database = { path = "../flowy-database" }
|
||||
flowy-block = { path = "../flowy-block", default-features = false }
|
||||
flowy-sync = { path = "../flowy-sync" }
|
||||
|
@ -4,6 +4,7 @@ use flowy_collaboration::client_document::default::initial_quill_delta_string;
|
||||
use flowy_collaboration::entities::revision::{RepeatedRevision, Revision};
|
||||
use flowy_collaboration::entities::ws_data::ClientRevisionWSData;
|
||||
use flowy_database::ConnectionPool;
|
||||
use flowy_folder::errors::FlowyResult;
|
||||
use flowy_folder::manager::{ViewDataProcessor, ViewDataProcessorMap};
|
||||
use flowy_folder::prelude::ViewDataType;
|
||||
use flowy_folder::{
|
||||
@ -11,8 +12,9 @@ use flowy_folder::{
|
||||
event_map::{FolderCouldServiceV1, WorkspaceDatabase, WorkspaceUser},
|
||||
manager::FolderManager,
|
||||
};
|
||||
use flowy_grid::manager::GridManager;
|
||||
use flowy_grid::manager::{make_grid_view_data, GridManager};
|
||||
use flowy_grid::util::make_default_grid;
|
||||
use flowy_grid_data_model::entities::BuildGridContext;
|
||||
use flowy_net::ClientServerConfiguration;
|
||||
use flowy_net::{
|
||||
http_server::folder::FolderHttpCloudService, local_server::LocalServer, ws::connection::FlowyWebSocketConnect,
|
||||
@ -23,6 +25,7 @@ use futures_core::future::BoxFuture;
|
||||
use lib_infra::future::{BoxResultFuture, FutureResult};
|
||||
use lib_ws::{WSChannel, WSMessageReceiver, WebSocketRawMessage};
|
||||
use std::collections::HashMap;
|
||||
use std::convert::TryFrom;
|
||||
use std::{convert::TryInto, sync::Arc};
|
||||
|
||||
pub struct FolderDepsResolver();
|
||||
@ -168,29 +171,39 @@ impl ViewDataProcessor for TextBlockViewDataProcessor {
|
||||
})
|
||||
}
|
||||
|
||||
fn delta_str(&self, view_id: &str) -> FutureResult<String, FlowyError> {
|
||||
fn delta_bytes(&self, view_id: &str) -> FutureResult<Bytes, FlowyError> {
|
||||
let view_id = view_id.to_string();
|
||||
let manager = self.0.clone();
|
||||
FutureResult::new(async move {
|
||||
let editor = manager.open_block(view_id).await?;
|
||||
let delta_str = editor.delta_str().await?;
|
||||
Ok(delta_str)
|
||||
let delta_bytes = Bytes::from(editor.delta_str().await?);
|
||||
Ok(delta_bytes)
|
||||
})
|
||||
}
|
||||
|
||||
fn create_default_view(&self, user_id: &str, view_id: &str) -> FutureResult<String, FlowyError> {
|
||||
fn create_default_view(&self, user_id: &str, view_id: &str) -> FutureResult<Bytes, FlowyError> {
|
||||
let user_id = user_id.to_string();
|
||||
let view_id = view_id.to_string();
|
||||
let manager = self.0.clone();
|
||||
FutureResult::new(async move {
|
||||
let view_data = initial_quill_delta_string();
|
||||
let delta_data = Bytes::from(view_data.clone());
|
||||
let repeated_revision: RepeatedRevision = Revision::initial_revision(&user_id, &view_id, delta_data).into();
|
||||
let delta_data = Bytes::from(view_data);
|
||||
let repeated_revision: RepeatedRevision =
|
||||
Revision::initial_revision(&user_id, &view_id, delta_data.clone()).into();
|
||||
let _ = manager.create_block(view_id, repeated_revision).await?;
|
||||
Ok(view_data)
|
||||
Ok(delta_data)
|
||||
})
|
||||
}
|
||||
|
||||
fn process_create_view_data(
|
||||
&self,
|
||||
_user_id: &str,
|
||||
_view_id: &str,
|
||||
data: Vec<u8>,
|
||||
) -> FutureResult<Bytes, FlowyError> {
|
||||
FutureResult::new(async move { Ok(Bytes::from(data)) })
|
||||
}
|
||||
|
||||
fn data_type(&self) -> ViewDataType {
|
||||
ViewDataType::TextBlock
|
||||
}
|
||||
@ -230,36 +243,34 @@ impl ViewDataProcessor for GridViewDataProcessor {
|
||||
})
|
||||
}
|
||||
|
||||
fn delta_str(&self, view_id: &str) -> FutureResult<String, FlowyError> {
|
||||
fn delta_bytes(&self, view_id: &str) -> FutureResult<Bytes, FlowyError> {
|
||||
let view_id = view_id.to_string();
|
||||
let grid_manager = self.0.clone();
|
||||
FutureResult::new(async move {
|
||||
let editor = grid_manager.open_grid(view_id).await?;
|
||||
let delta_str = editor.delta_str().await;
|
||||
Ok(delta_str)
|
||||
let delta_bytes = editor.delta_bytes().await;
|
||||
Ok(delta_bytes)
|
||||
})
|
||||
}
|
||||
|
||||
fn create_default_view(&self, user_id: &str, view_id: &str) -> FutureResult<String, FlowyError> {
|
||||
let info = make_default_grid(view_id);
|
||||
fn create_default_view(&self, user_id: &str, view_id: &str) -> FutureResult<Bytes, FlowyError> {
|
||||
let build_context = make_default_grid();
|
||||
let user_id = user_id.to_string();
|
||||
let view_id = view_id.to_string();
|
||||
let grid_manager = self.0.clone();
|
||||
|
||||
FutureResult::new(async move { make_grid_view_data(&user_id, &view_id, grid_manager, build_context).await })
|
||||
}
|
||||
|
||||
fn process_create_view_data(&self, user_id: &str, view_id: &str, data: Vec<u8>) -> FutureResult<Bytes, FlowyError> {
|
||||
let user_id = user_id.to_string();
|
||||
let view_id = view_id.to_string();
|
||||
let grid_manager = self.0.clone();
|
||||
|
||||
FutureResult::new(async move {
|
||||
let grid_delta_data = Bytes::from(info.grid_delta.to_delta_str());
|
||||
let repeated_revision: RepeatedRevision =
|
||||
Revision::initial_revision(&user_id, &view_id, grid_delta_data).into();
|
||||
let _ = grid_manager.create_grid(&view_id, repeated_revision).await?;
|
||||
|
||||
let block_meta_delta_data = Bytes::from(info.grid_block_meta_delta.to_delta_str());
|
||||
let repeated_revision: RepeatedRevision =
|
||||
Revision::initial_revision(&user_id, &info.block_id, block_meta_delta_data).into();
|
||||
let _ = grid_manager
|
||||
.create_grid_block_meta(&info.block_id, repeated_revision)
|
||||
.await?;
|
||||
|
||||
Ok(info.grid_delta.to_delta_str())
|
||||
let bytes = Bytes::from(data);
|
||||
let build_context = BuildGridContext::try_from(bytes)?;
|
||||
make_grid_view_data(&user_id, &view_id, grid_manager, build_context).await
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -154,7 +154,7 @@ where
|
||||
&rev_manager.object_id,
|
||||
base_rev_id,
|
||||
rev_id,
|
||||
client_delta.to_bytes(),
|
||||
client_delta.to_delta_bytes(),
|
||||
user_id,
|
||||
md5.clone(),
|
||||
);
|
||||
@ -166,7 +166,7 @@ where
|
||||
&rev_manager.object_id,
|
||||
base_rev_id,
|
||||
rev_id,
|
||||
server_delta.to_bytes(),
|
||||
server_delta.to_delta_bytes(),
|
||||
user_id,
|
||||
md5,
|
||||
);
|
||||
|
@ -26,7 +26,7 @@ pub struct ViewTest {
|
||||
|
||||
impl ViewTest {
|
||||
#[allow(dead_code)]
|
||||
pub async fn new(sdk: &FlowySDKTest, data_type: ViewDataType, data: String) -> Self {
|
||||
pub async fn new(sdk: &FlowySDKTest, data_type: ViewDataType, data: Vec<u8>) -> 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;
|
||||
@ -39,12 +39,12 @@ impl ViewTest {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn new_grid_view(sdk: &FlowySDKTest, data: String) -> Self {
|
||||
pub async fn new_grid_view(sdk: &FlowySDKTest, data: Vec<u8>) -> Self {
|
||||
Self::new(sdk, ViewDataType::Grid, data).await
|
||||
}
|
||||
|
||||
pub async fn new_text_block_view(sdk: &FlowySDKTest) -> Self {
|
||||
Self::new(sdk, ViewDataType::TextBlock, "".to_owned()).await
|
||||
Self::new(sdk, ViewDataType::TextBlock, vec![]).await
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,7 +91,7 @@ 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, data: String) -> View {
|
||||
async fn create_view(sdk: &FlowySDKTest, app_id: &str, data_type: ViewDataType, data: Vec<u8>) -> View {
|
||||
let request = CreateViewPayload {
|
||||
belong_to_id: app_id.to_string(),
|
||||
name: "View A".to_string(),
|
||||
|
Reference in New Issue
Block a user