chore: update grid test

This commit is contained in:
appflowy 2022-03-15 19:00:28 +08:00
parent 50f32521c5
commit 47081f3095
32 changed files with 746 additions and 219 deletions

View File

@ -276,7 +276,7 @@ class CreateViewPayload extends $pb.GeneratedMessage {
..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'thumbnail')
..e<ViewDataType>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dataType', $pb.PbFieldType.OE, defaultOrMaker: ViewDataType.TextBlock, valueOf: ViewDataType.valueOf, enumValues: ViewDataType.values)
..a<$core.int>(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'pluginType', $pb.PbFieldType.O3)
..aOS(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data')
..a<$core.List<$core.int>>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data', $pb.PbFieldType.OY)
..hasRequiredFields = false
;
@ -288,7 +288,7 @@ class CreateViewPayload extends $pb.GeneratedMessage {
$core.String? thumbnail,
ViewDataType? dataType,
$core.int? pluginType,
$core.String? data,
$core.List<$core.int>? data,
}) {
final _result = create();
if (belongToId != null) {
@ -393,9 +393,9 @@ class CreateViewPayload extends $pb.GeneratedMessage {
void clearPluginType() => clearField(6);
@$pb.TagNumber(7)
$core.String get data => $_getSZ(6);
$core.List<$core.int> get data => $_getN(6);
@$pb.TagNumber(7)
set data($core.String v) { $_setString(6, v); }
set data($core.List<$core.int> v) { $_setBytes(6, v); }
@$pb.TagNumber(7)
$core.bool hasData() => $_has(6);
@$pb.TagNumber(7)
@ -410,7 +410,7 @@ class CreateViewParams extends $pb.GeneratedMessage {
..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'thumbnail')
..e<ViewDataType>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dataType', $pb.PbFieldType.OE, defaultOrMaker: ViewDataType.TextBlock, valueOf: ViewDataType.valueOf, enumValues: ViewDataType.values)
..aOS(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'viewId')
..aOS(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data')
..a<$core.List<$core.int>>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data', $pb.PbFieldType.OY)
..a<$core.int>(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'pluginType', $pb.PbFieldType.O3)
..hasRequiredFields = false
;
@ -423,7 +423,7 @@ class CreateViewParams extends $pb.GeneratedMessage {
$core.String? thumbnail,
ViewDataType? dataType,
$core.String? viewId,
$core.String? data,
$core.List<$core.int>? data,
$core.int? pluginType,
}) {
final _result = create();
@ -529,9 +529,9 @@ class CreateViewParams extends $pb.GeneratedMessage {
void clearViewId() => clearField(6);
@$pb.TagNumber(7)
$core.String get data => $_getSZ(6);
$core.List<$core.int> get data => $_getN(6);
@$pb.TagNumber(7)
set data($core.String v) { $_setString(6, v); }
set data($core.List<$core.int> v) { $_setBytes(6, v); }
@$pb.TagNumber(7)
$core.bool hasData() => $_has(6);
@$pb.TagNumber(7)

View File

@ -60,7 +60,7 @@ const CreateViewPayload$json = const {
const {'1': 'thumbnail', '3': 4, '4': 1, '5': 9, '9': 0, '10': 'thumbnail'},
const {'1': 'data_type', '3': 5, '4': 1, '5': 14, '6': '.ViewDataType', '10': 'dataType'},
const {'1': 'plugin_type', '3': 6, '4': 1, '5': 5, '10': 'pluginType'},
const {'1': 'data', '3': 7, '4': 1, '5': 9, '10': 'data'},
const {'1': 'data', '3': 7, '4': 1, '5': 12, '10': 'data'},
],
'8': const [
const {'1': 'one_of_thumbnail'},
@ -68,7 +68,7 @@ const CreateViewPayload$json = const {
};
/// Descriptor for `CreateViewPayload`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List createViewPayloadDescriptor = $convert.base64Decode('ChFDcmVhdGVWaWV3UGF5bG9hZBIgCgxiZWxvbmdfdG9faWQYASABKAlSCmJlbG9uZ1RvSWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEh4KCXRodW1ibmFpbBgEIAEoCUgAUgl0aHVtYm5haWwSKgoJZGF0YV90eXBlGAUgASgOMg0uVmlld0RhdGFUeXBlUghkYXRhVHlwZRIfCgtwbHVnaW5fdHlwZRgGIAEoBVIKcGx1Z2luVHlwZRISCgRkYXRhGAcgASgJUgRkYXRhQhIKEG9uZV9vZl90aHVtYm5haWw=');
final $typed_data.Uint8List createViewPayloadDescriptor = $convert.base64Decode('ChFDcmVhdGVWaWV3UGF5bG9hZBIgCgxiZWxvbmdfdG9faWQYASABKAlSCmJlbG9uZ1RvSWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEh4KCXRodW1ibmFpbBgEIAEoCUgAUgl0aHVtYm5haWwSKgoJZGF0YV90eXBlGAUgASgOMg0uVmlld0RhdGFUeXBlUghkYXRhVHlwZRIfCgtwbHVnaW5fdHlwZRgGIAEoBVIKcGx1Z2luVHlwZRISCgRkYXRhGAcgASgMUgRkYXRhQhIKEG9uZV9vZl90aHVtYm5haWw=');
@$core.Deprecated('Use createViewParamsDescriptor instead')
const CreateViewParams$json = const {
'1': 'CreateViewParams',
@ -79,13 +79,13 @@ const CreateViewParams$json = const {
const {'1': 'thumbnail', '3': 4, '4': 1, '5': 9, '10': 'thumbnail'},
const {'1': 'data_type', '3': 5, '4': 1, '5': 14, '6': '.ViewDataType', '10': 'dataType'},
const {'1': 'view_id', '3': 6, '4': 1, '5': 9, '10': 'viewId'},
const {'1': 'data', '3': 7, '4': 1, '5': 9, '10': 'data'},
const {'1': 'data', '3': 7, '4': 1, '5': 12, '10': 'data'},
const {'1': 'plugin_type', '3': 8, '4': 1, '5': 5, '10': 'pluginType'},
],
};
/// Descriptor for `CreateViewParams`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List createViewParamsDescriptor = $convert.base64Decode('ChBDcmVhdGVWaWV3UGFyYW1zEiAKDGJlbG9uZ190b19pZBgBIAEoCVIKYmVsb25nVG9JZBISCgRuYW1lGAIgASgJUgRuYW1lEhIKBGRlc2MYAyABKAlSBGRlc2MSHAoJdGh1bWJuYWlsGAQgASgJUgl0aHVtYm5haWwSKgoJZGF0YV90eXBlGAUgASgOMg0uVmlld0RhdGFUeXBlUghkYXRhVHlwZRIXCgd2aWV3X2lkGAYgASgJUgZ2aWV3SWQSEgoEZGF0YRgHIAEoCVIEZGF0YRIfCgtwbHVnaW5fdHlwZRgIIAEoBVIKcGx1Z2luVHlwZQ==');
final $typed_data.Uint8List createViewParamsDescriptor = $convert.base64Decode('ChBDcmVhdGVWaWV3UGFyYW1zEiAKDGJlbG9uZ190b19pZBgBIAEoCVIKYmVsb25nVG9JZBISCgRuYW1lGAIgASgJUgRuYW1lEhIKBGRlc2MYAyABKAlSBGRlc2MSHAoJdGh1bWJuYWlsGAQgASgJUgl0aHVtYm5haWwSKgoJZGF0YV90eXBlGAUgASgOMg0uVmlld0RhdGFUeXBlUghkYXRhVHlwZRIXCgd2aWV3X2lkGAYgASgJUgZ2aWV3SWQSEgoEZGF0YRgHIAEoDFIEZGF0YRIfCgtwbHVnaW5fdHlwZRgIIAEoBVIKcGx1Z2luVHlwZQ==');
@$core.Deprecated('Use viewIdDescriptor instead')
const ViewId$json = const {
'1': 'ViewId',

View File

@ -1003,3 +1003,76 @@ class CellMetaChangeset extends $pb.GeneratedMessage {
void clearData() => clearField(3);
}
class BuildGridContext extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'BuildGridContext', createEmptyInstance: create)
..pc<FieldMeta>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldMetas', $pb.PbFieldType.PM, subBuilder: FieldMeta.create)
..aOM<GridBlock>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridBlock', subBuilder: GridBlock.create)
..aOM<GridBlockMeta>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'gridBlockMeta', subBuilder: GridBlockMeta.create)
..hasRequiredFields = false
;
BuildGridContext._() : super();
factory BuildGridContext({
$core.Iterable<FieldMeta>? fieldMetas,
GridBlock? gridBlock,
GridBlockMeta? gridBlockMeta,
}) {
final _result = create();
if (fieldMetas != null) {
_result.fieldMetas.addAll(fieldMetas);
}
if (gridBlock != null) {
_result.gridBlock = gridBlock;
}
if (gridBlockMeta != null) {
_result.gridBlockMeta = gridBlockMeta;
}
return _result;
}
factory BuildGridContext.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory BuildGridContext.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
BuildGridContext clone() => BuildGridContext()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
BuildGridContext copyWith(void Function(BuildGridContext) updates) => super.copyWith((message) => updates(message as BuildGridContext)) as BuildGridContext; // ignore: deprecated_member_use
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static BuildGridContext create() => BuildGridContext._();
BuildGridContext createEmptyInstance() => create();
static $pb.PbList<BuildGridContext> createRepeated() => $pb.PbList<BuildGridContext>();
@$core.pragma('dart2js:noInline')
static BuildGridContext getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<BuildGridContext>(create);
static BuildGridContext? _defaultInstance;
@$pb.TagNumber(1)
$core.List<FieldMeta> get fieldMetas => $_getList(0);
@$pb.TagNumber(2)
GridBlock get gridBlock => $_getN(1);
@$pb.TagNumber(2)
set gridBlock(GridBlock v) { setField(2, v); }
@$pb.TagNumber(2)
$core.bool hasGridBlock() => $_has(1);
@$pb.TagNumber(2)
void clearGridBlock() => clearField(2);
@$pb.TagNumber(2)
GridBlock ensureGridBlock() => $_ensure(1);
@$pb.TagNumber(3)
GridBlockMeta get gridBlockMeta => $_getN(2);
@$pb.TagNumber(3)
set gridBlockMeta(GridBlockMeta v) { setField(3, v); }
@$pb.TagNumber(3)
$core.bool hasGridBlockMeta() => $_has(2);
@$pb.TagNumber(3)
void clearGridBlockMeta() => clearField(3);
@$pb.TagNumber(3)
GridBlockMeta ensureGridBlockMeta() => $_ensure(2);
}

View File

@ -191,3 +191,15 @@ const CellMetaChangeset$json = const {
/// Descriptor for `CellMetaChangeset`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List cellMetaChangesetDescriptor = $convert.base64Decode('ChFDZWxsTWV0YUNoYW5nZXNldBIVCgZyb3dfaWQYASABKAlSBXJvd0lkEhkKCGZpZWxkX2lkGAIgASgJUgdmaWVsZElkEhQKBGRhdGEYAyABKAlIAFIEZGF0YUINCgtvbmVfb2ZfZGF0YQ==');
@$core.Deprecated('Use buildGridContextDescriptor instead')
const BuildGridContext$json = const {
'1': 'BuildGridContext',
'2': const [
const {'1': 'field_metas', '3': 1, '4': 3, '5': 11, '6': '.FieldMeta', '10': 'fieldMetas'},
const {'1': 'grid_block', '3': 2, '4': 1, '5': 11, '6': '.GridBlock', '10': 'gridBlock'},
const {'1': 'grid_block_meta', '3': 3, '4': 1, '5': 11, '6': '.GridBlockMeta', '10': 'gridBlockMeta'},
],
};
/// Descriptor for `BuildGridContext`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List buildGridContextDescriptor = $convert.base64Decode('ChBCdWlsZEdyaWRDb250ZXh0EisKC2ZpZWxkX21ldGFzGAEgAygLMgouRmllbGRNZXRhUgpmaWVsZE1ldGFzEikKCmdyaWRfYmxvY2sYAiABKAsyCi5HcmlkQmxvY2tSCWdyaWRCbG9jaxI2Cg9ncmlkX2Jsb2NrX21ldGEYAyABKAsyDi5HcmlkQmxvY2tNZXRhUg1ncmlkQmxvY2tNZXRh');

View File

@ -1147,6 +1147,7 @@ dependencies = [
"flowy-database",
"flowy-folder",
"flowy-grid",
"flowy-grid-data-model",
"flowy-net",
"flowy-sync",
"flowy-user",

View File

@ -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())
}
}

View File

@ -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;
}

View File

@ -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())
}
}

View File

@ -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 {

View File

@ -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(&params.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, &params.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, &params.view_id, params.data.clone())
.await?;
let _ = self
.create_view(&params.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,
};

View File

@ -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)
}

View File

@ -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())
}
}

View File

@ -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())
}
}

View File

@ -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()
}

View File

@ -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]

View File

@ -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()
}

View File

@ -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" }

View File

@ -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
})
}

View File

@ -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,
);

View File

@ -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(),

View File

@ -6,6 +6,7 @@ use crate::{
},
errors::CollaborateError,
};
use bytes::Bytes;
use lib_ot::{
core::*,
rich_text::{RichTextAttribute, RichTextDelta},
@ -62,8 +63,8 @@ impl ClientDocument {
self.delta.to_delta_str()
}
pub fn to_bytes(&self) -> Vec<u8> {
self.delta.clone().to_bytes().to_vec()
pub fn to_bytes(&self) -> Bytes {
self.delta.to_delta_bytes()
}
pub fn to_plain_string(&self) -> String {

View File

@ -268,7 +268,7 @@ impl FolderPad {
}
pub fn md5(&self) -> String {
md5(&self.delta.to_bytes())
md5(&self.delta.to_delta_bytes())
}
pub fn to_json(&self) -> CollaborateResult<String> {

View File

@ -144,7 +144,7 @@ impl GridBlockMetaPad {
}
pub fn md5(&self) -> String {
md5(&self.delta.to_bytes())
md5(&self.delta.to_delta_bytes())
}
pub fn delta_str(&self) -> String {
@ -165,7 +165,7 @@ pub fn make_block_meta_delta(block_meta: &GridBlockMeta) -> GridBlockMetaDelta {
pub fn make_block_meta_revisions(user_id: &str, block_meta: &GridBlockMeta) -> RepeatedRevision {
let delta = make_block_meta_delta(block_meta);
let bytes = delta.to_bytes();
let bytes = delta.to_delta_bytes();
let revision = Revision::initial_revision(user_id, &block_meta.block_id, bytes);
revision.into()
}

View File

@ -1,66 +1,37 @@
use crate::client_grid::{make_block_meta_delta, make_grid_delta, GridBlockMetaDelta, GridMetaDelta};
use crate::errors::{CollaborateError, CollaborateResult};
use flowy_grid_data_model::entities::{FieldMeta, GridBlock, GridBlockMeta, GridMeta, RowMeta};
use flowy_grid_data_model::entities::{BuildGridContext, FieldMeta, GridBlock, GridBlockMeta, GridMeta, RowMeta};
pub struct GridBuilder {
grid_id: String,
fields: Vec<FieldMeta>,
grid_block: GridBlock,
grid_block_meta: GridBlockMeta,
build_context: BuildGridContext,
}
impl std::default::Default for GridBuilder {
fn default() -> Self {
Self {
build_context: Default::default(),
}
}
}
impl GridBuilder {
pub fn new(grid_id: &str) -> Self {
let grid_block = GridBlock::new();
let grid_block_meta = GridBlockMeta {
block_id: grid_block.id.clone(),
rows: vec![],
};
Self {
grid_id: grid_id.to_owned(),
fields: vec![],
grid_block,
grid_block_meta,
}
}
pub fn add_field(mut self, field: FieldMeta) -> Self {
self.fields.push(field);
self.build_context.field_metas.push(field);
self
}
pub fn add_empty_row(mut self) -> Self {
let row = RowMeta::new(&self.grid_block.id);
self.grid_block_meta.rows.push(row);
self.grid_block.row_count += 1;
let row = RowMeta::new(&self.build_context.grid_block.id);
self.build_context.grid_block_meta.rows.push(row);
self.build_context.grid_block.row_count += 1;
self
}
pub fn build(self) -> CollaborateResult<BuildGridInfo> {
let block_id = self.grid_block.id.clone();
let grid_meta = GridMeta {
grid_id: self.grid_id,
fields: self.fields,
blocks: vec![self.grid_block],
};
// let _ = check_rows(&self.fields, &self.rows)?;
let grid_delta = make_grid_delta(&grid_meta);
let grid_block_meta_delta = make_block_meta_delta(&self.grid_block_meta);
Ok(BuildGridInfo {
grid_delta,
block_id,
grid_block_meta_delta,
})
pub fn build(self) -> BuildGridContext {
self.build_context
}
}
pub struct BuildGridInfo {
pub grid_delta: GridMetaDelta,
pub block_id: String,
pub grid_block_meta_delta: GridBlockMetaDelta,
}
#[allow(dead_code)]
fn check_rows(fields: &[FieldMeta], rows: &[RowMeta]) -> CollaborateResult<()> {
let field_ids = fields.iter().map(|field| &field.id).collect::<Vec<&String>>();
@ -76,28 +47,31 @@ fn check_rows(fields: &[FieldMeta], rows: &[RowMeta]) -> CollaborateResult<()> {
#[cfg(test)]
mod tests {
use crate::client_grid::GridBuilder;
use crate::client_grid::{make_block_meta_delta, make_grid_delta, GridBuilder};
use flowy_grid_data_model::entities::{FieldMeta, FieldType, GridBlockMeta, GridMeta};
#[test]
fn create_default_grid_test() {
let info = GridBuilder::new("1")
let grid_id = "1".to_owned();
let build_context = GridBuilder::default()
.add_field(FieldMeta::new("Name", "", FieldType::RichText))
.add_field(FieldMeta::new("Tags", "", FieldType::SingleSelect))
.add_empty_row()
.add_empty_row()
.add_empty_row()
.build()
.unwrap();
.build();
let grid_meta: GridMeta = serde_json::from_str(&info.grid_delta.to_str().unwrap()).unwrap();
assert_eq!(grid_meta.fields.len(), 2);
assert_eq!(grid_meta.blocks.len(), 1);
let grid_meta = GridMeta {
grid_id: grid_id.clone(),
fields: build_context.field_metas,
blocks: vec![build_context.grid_block],
};
let grid_block_meta: GridBlockMeta =
serde_json::from_str(&info.grid_block_meta_delta.to_str().unwrap()).unwrap();
assert_eq!(grid_block_meta.rows.len(), 3);
let grid_meta_delta = make_grid_delta(&grid_meta);
let _: GridMeta = serde_json::from_str(&grid_meta_delta.to_str().unwrap()).unwrap();
assert_eq!(grid_meta.blocks[0].id, grid_block_meta.block_id);
let grid_block_meta_delta = make_block_meta_delta(&build_context.grid_block_meta);
let _: GridBlockMeta = serde_json::from_str(&grid_block_meta_delta.to_str().unwrap()).unwrap();
}
}

View File

@ -1,6 +1,7 @@
use crate::entities::revision::{md5, RepeatedRevision, Revision};
use crate::errors::{internal_error, CollaborateError, CollaborateResult};
use crate::util::{cal_diff, make_delta_from_revisions};
use bytes::Bytes;
use flowy_grid_data_model::entities::{
FieldChangeset, FieldMeta, FieldOrder, GridBlock, GridBlockChangeset, GridMeta, RepeatedFieldOrder,
};
@ -56,6 +57,14 @@ impl GridMetaPad {
})
}
pub fn contain_field(&self, field_id: &str) -> bool {
self.grid_meta
.fields
.iter()
.find(|field| &field.id == field_id)
.is_some()
}
pub fn get_field_orders(&self) -> Vec<FieldOrder> {
self.grid_meta
.fields
@ -180,13 +189,17 @@ impl GridMetaPad {
}
pub fn md5(&self) -> String {
md5(&self.delta.to_bytes())
md5(&self.delta.to_delta_bytes())
}
pub fn delta_str(&self) -> String {
self.delta.to_delta_str()
}
pub fn delta_bytes(&self) -> Bytes {
self.delta.to_delta_bytes()
}
pub fn fields(&self) -> &[FieldMeta] {
&self.grid_meta.fields
}
@ -258,7 +271,7 @@ pub fn make_grid_delta(grid_meta: &GridMeta) -> GridMetaDelta {
pub fn make_grid_revisions(user_id: &str, grid_meta: &GridMeta) -> RepeatedRevision {
let delta = make_grid_delta(grid_meta);
let bytes = delta.to_bytes();
let bytes = delta.to_delta_bytes();
let revision = Revision::initial_revision(user_id, &grid_meta.grid_id, bytes);
revision.into()
}

View File

@ -127,7 +127,7 @@ pub struct CreateViewPayload {
pub plugin_type: i32,
#[pb(index = 7)]
pub data: String,
pub data: Vec<u8>,
}
#[derive(Default, ProtoBuf, Debug, Clone)]
@ -151,7 +151,7 @@ pub struct CreateViewParams {
pub view_id: String,
#[pb(index = 7)]
pub data: String,
pub data: Vec<u8>,
#[pb(index = 8)]
pub plugin_type: i32,

View File

@ -794,7 +794,7 @@ pub struct CreateViewPayload {
pub desc: ::std::string::String,
pub data_type: ViewDataType,
pub plugin_type: i32,
pub data: ::std::string::String,
pub data: ::std::vec::Vec<u8>,
// message oneof groups
pub one_of_thumbnail: ::std::option::Option<CreateViewPayload_oneof_one_of_thumbnail>,
// special fields
@ -975,10 +975,10 @@ impl CreateViewPayload {
self.plugin_type = v;
}
// string data = 7;
// bytes data = 7;
pub fn get_data(&self) -> &str {
pub fn get_data(&self) -> &[u8] {
&self.data
}
pub fn clear_data(&mut self) {
@ -986,19 +986,19 @@ impl CreateViewPayload {
}
// Param is passed by value, moved
pub fn set_data(&mut self, v: ::std::string::String) {
pub fn set_data(&mut self, v: ::std::vec::Vec<u8>) {
self.data = v;
}
// Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first.
pub fn mut_data(&mut self) -> &mut ::std::string::String {
pub fn mut_data(&mut self) -> &mut ::std::vec::Vec<u8> {
&mut self.data
}
// Take field
pub fn take_data(&mut self) -> ::std::string::String {
::std::mem::replace(&mut self.data, ::std::string::String::new())
pub fn take_data(&mut self) -> ::std::vec::Vec<u8> {
::std::mem::replace(&mut self.data, ::std::vec::Vec::new())
}
}
@ -1037,7 +1037,7 @@ impl ::protobuf::Message for CreateViewPayload {
self.plugin_type = tmp;
},
7 => {
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.data)?;
::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.data)?;
},
_ => {
::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
@ -1067,7 +1067,7 @@ impl ::protobuf::Message for CreateViewPayload {
my_size += ::protobuf::rt::value_size(6, self.plugin_type, ::protobuf::wire_format::WireTypeVarint);
}
if !self.data.is_empty() {
my_size += ::protobuf::rt::string_size(7, &self.data);
my_size += ::protobuf::rt::bytes_size(7, &self.data);
}
if let ::std::option::Option::Some(ref v) = self.one_of_thumbnail {
match v {
@ -1098,7 +1098,7 @@ impl ::protobuf::Message for CreateViewPayload {
os.write_int32(6, self.plugin_type)?;
}
if !self.data.is_empty() {
os.write_string(7, &self.data)?;
os.write_bytes(7, &self.data)?;
}
if let ::std::option::Option::Some(ref v) = self.one_of_thumbnail {
match v {
@ -1175,7 +1175,7 @@ impl ::protobuf::Message for CreateViewPayload {
|m: &CreateViewPayload| { &m.plugin_type },
|m: &mut CreateViewPayload| { &mut m.plugin_type },
));
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
"data",
|m: &CreateViewPayload| { &m.data },
|m: &mut CreateViewPayload| { &mut m.data },
@ -1228,7 +1228,7 @@ pub struct CreateViewParams {
pub thumbnail: ::std::string::String,
pub data_type: ViewDataType,
pub view_id: ::std::string::String,
pub data: ::std::string::String,
pub data: ::std::vec::Vec<u8>,
pub plugin_type: i32,
// special fields
pub unknown_fields: ::protobuf::UnknownFields,
@ -1391,10 +1391,10 @@ impl CreateViewParams {
::std::mem::replace(&mut self.view_id, ::std::string::String::new())
}
// string data = 7;
// bytes data = 7;
pub fn get_data(&self) -> &str {
pub fn get_data(&self) -> &[u8] {
&self.data
}
pub fn clear_data(&mut self) {
@ -1402,19 +1402,19 @@ impl CreateViewParams {
}
// Param is passed by value, moved
pub fn set_data(&mut self, v: ::std::string::String) {
pub fn set_data(&mut self, v: ::std::vec::Vec<u8>) {
self.data = v;
}
// Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first.
pub fn mut_data(&mut self) -> &mut ::std::string::String {
pub fn mut_data(&mut self) -> &mut ::std::vec::Vec<u8> {
&mut self.data
}
// Take field
pub fn take_data(&mut self) -> ::std::string::String {
::std::mem::replace(&mut self.data, ::std::string::String::new())
pub fn take_data(&mut self) -> ::std::vec::Vec<u8> {
::std::mem::replace(&mut self.data, ::std::vec::Vec::new())
}
// int32 plugin_type = 8;
@ -1461,7 +1461,7 @@ impl ::protobuf::Message for CreateViewParams {
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.view_id)?;
},
7 => {
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.data)?;
::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.data)?;
},
8 => {
if wire_type != ::protobuf::wire_format::WireTypeVarint {
@ -1501,7 +1501,7 @@ impl ::protobuf::Message for CreateViewParams {
my_size += ::protobuf::rt::string_size(6, &self.view_id);
}
if !self.data.is_empty() {
my_size += ::protobuf::rt::string_size(7, &self.data);
my_size += ::protobuf::rt::bytes_size(7, &self.data);
}
if self.plugin_type != 0 {
my_size += ::protobuf::rt::value_size(8, self.plugin_type, ::protobuf::wire_format::WireTypeVarint);
@ -1531,7 +1531,7 @@ impl ::protobuf::Message for CreateViewParams {
os.write_string(6, &self.view_id)?;
}
if !self.data.is_empty() {
os.write_string(7, &self.data)?;
os.write_bytes(7, &self.data)?;
}
if self.plugin_type != 0 {
os.write_int32(8, self.plugin_type)?;
@ -1604,7 +1604,7 @@ impl ::protobuf::Message for CreateViewParams {
|m: &CreateViewParams| { &m.view_id },
|m: &mut CreateViewParams| { &mut m.view_id },
));
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
"data",
|m: &CreateViewParams| { &m.data },
|m: &mut CreateViewParams| { &mut m.data },
@ -2844,22 +2844,22 @@ static file_descriptor_proto_data: &'static [u8] = b"\
\x18\x03\x20\x01(\tR\x04desc\x12\x1e\n\tthumbnail\x18\x04\x20\x01(\tH\0R\
\tthumbnail\x12*\n\tdata_type\x18\x05\x20\x01(\x0e2\r.ViewDataTypeR\x08d\
ataType\x12\x1f\n\x0bplugin_type\x18\x06\x20\x01(\x05R\npluginType\x12\
\x12\n\x04data\x18\x07\x20\x01(\tR\x04dataB\x12\n\x10one_of_thumbnail\"\
\xf4\x01\n\x10CreateViewParams\x12\x20\n\x0cbelong_to_id\x18\x01\x20\x01\
(\tR\nbelongToId\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\
\x04desc\x18\x03\x20\x01(\tR\x04desc\x12\x1c\n\tthumbnail\x18\x04\x20\
\x01(\tR\tthumbnail\x12*\n\tdata_type\x18\x05\x20\x01(\x0e2\r.ViewDataTy\
peR\x08dataType\x12\x17\n\x07view_id\x18\x06\x20\x01(\tR\x06viewId\x12\
\x12\n\x04data\x18\x07\x20\x01(\tR\x04data\x12\x1f\n\x0bplugin_type\x18\
\x08\x20\x01(\x05R\npluginType\"\x1e\n\x06ViewId\x12\x14\n\x05value\x18\
\x01\x20\x01(\tR\x05value\"&\n\x0eRepeatedViewId\x12\x14\n\x05items\x18\
\x01\x20\x03(\tR\x05items\"\xaa\x01\n\x11UpdateViewPayload\x12\x17\n\x07\
view_id\x18\x01\x20\x01(\tR\x06viewId\x12\x14\n\x04name\x18\x02\x20\x01(\
\tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\x01(\tH\x01R\x04desc\x12\
\x1e\n\tthumbnail\x18\x04\x20\x01(\tH\x02R\tthumbnailB\r\n\x0bone_of_nam\
eB\r\n\x0bone_of_descB\x12\n\x10one_of_thumbnail\"\xa9\x01\n\x10UpdateVi\
ewParams\x12\x17\n\x07view_id\x18\x01\x20\x01(\tR\x06viewId\x12\x14\n\
\x04name\x18\x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\
\x12\n\x04data\x18\x07\x20\x01(\x0cR\x04dataB\x12\n\x10one_of_thumbnail\
\"\xf4\x01\n\x10CreateViewParams\x12\x20\n\x0cbelong_to_id\x18\x01\x20\
\x01(\tR\nbelongToId\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\
\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\x12\x1c\n\tthumbnail\x18\x04\
\x20\x01(\tR\tthumbnail\x12*\n\tdata_type\x18\x05\x20\x01(\x0e2\r.ViewDa\
taTypeR\x08dataType\x12\x17\n\x07view_id\x18\x06\x20\x01(\tR\x06viewId\
\x12\x12\n\x04data\x18\x07\x20\x01(\x0cR\x04data\x12\x1f\n\x0bplugin_typ\
e\x18\x08\x20\x01(\x05R\npluginType\"\x1e\n\x06ViewId\x12\x14\n\x05value\
\x18\x01\x20\x01(\tR\x05value\"&\n\x0eRepeatedViewId\x12\x14\n\x05items\
\x18\x01\x20\x03(\tR\x05items\"\xaa\x01\n\x11UpdateViewPayload\x12\x17\n\
\x07view_id\x18\x01\x20\x01(\tR\x06viewId\x12\x14\n\x04name\x18\x02\x20\
\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\x01(\tH\x01R\x04desc\
\x12\x1e\n\tthumbnail\x18\x04\x20\x01(\tH\x02R\tthumbnailB\r\n\x0bone_of\
_nameB\r\n\x0bone_of_descB\x12\n\x10one_of_thumbnail\"\xa9\x01\n\x10Upda\
teViewParams\x12\x17\n\x07view_id\x18\x01\x20\x01(\tR\x06viewId\x12\x14\
\n\x04name\x18\x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\
\x01(\tH\x01R\x04desc\x12\x1e\n\tthumbnail\x18\x04\x20\x01(\tH\x02R\tthu\
mbnailB\r\n\x0bone_of_nameB\r\n\x0bone_of_descB\x12\n\x10one_of_thumbnai\
l*'\n\x0cViewDataType\x12\r\n\tTextBlock\x10\0\x12\x08\n\x04Grid\x10\x01\

View File

@ -24,7 +24,7 @@ message CreateViewPayload {
oneof one_of_thumbnail { string thumbnail = 4; };
ViewDataType data_type = 5;
int32 plugin_type = 6;
string data = 7;
bytes data = 7;
}
message CreateViewParams {
string belong_to_id = 1;
@ -33,7 +33,7 @@ message CreateViewParams {
string thumbnail = 4;
ViewDataType data_type = 5;
string view_id = 6;
string data = 7;
bytes data = 7;
int32 plugin_type = 8;
}
message ViewId {

View File

@ -1,7 +1,8 @@
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use strum_macros::{Display, EnumIter, EnumString};
use strum::{EnumCount, IntoEnumIterator};
use strum_macros::{Display, EnumCount as EnumCountMacro, EnumIter, EnumString};
pub const DEFAULT_ROW_HEIGHT: i32 = 36;
pub const DEFAULT_FIELD_WIDTH: i32 = 150;
@ -139,7 +140,9 @@ pub struct FieldChangeset {
pub type_options: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum, EnumString, EnumIter, Display, Serialize, Deserialize)]
#[derive(
Debug, Clone, PartialEq, Eq, ProtoBuf_Enum, EnumCountMacro, EnumString, EnumIter, Display, Serialize, Deserialize,
)]
pub enum FieldType {
RichText = 0,
Number = 1,
@ -312,3 +315,31 @@ impl std::convert::From<CellMetaChangeset> for RowMetaChangeset {
}
}
}
#[derive(Clone, ProtoBuf)]
pub struct BuildGridContext {
#[pb(index = 1)]
pub field_metas: Vec<FieldMeta>,
#[pb(index = 2)]
pub grid_block: GridBlock,
#[pb(index = 3)]
pub grid_block_meta: GridBlockMeta,
}
impl std::default::Default for BuildGridContext {
fn default() -> Self {
let grid_block = GridBlock::new();
let grid_block_meta = GridBlockMeta {
block_id: grid_block.id.clone(),
rows: vec![],
};
Self {
field_metas: vec![],
grid_block,
grid_block_meta,
}
}
}

View File

@ -3073,6 +3073,286 @@ impl ::protobuf::reflect::ProtobufValue for CellMetaChangeset {
}
}
#[derive(PartialEq,Clone,Default)]
pub struct BuildGridContext {
// message fields
pub field_metas: ::protobuf::RepeatedField<FieldMeta>,
pub grid_block: ::protobuf::SingularPtrField<GridBlock>,
pub grid_block_meta: ::protobuf::SingularPtrField<GridBlockMeta>,
// special fields
pub unknown_fields: ::protobuf::UnknownFields,
pub cached_size: ::protobuf::CachedSize,
}
impl<'a> ::std::default::Default for &'a BuildGridContext {
fn default() -> &'a BuildGridContext {
<BuildGridContext as ::protobuf::Message>::default_instance()
}
}
impl BuildGridContext {
pub fn new() -> BuildGridContext {
::std::default::Default::default()
}
// repeated .FieldMeta field_metas = 1;
pub fn get_field_metas(&self) -> &[FieldMeta] {
&self.field_metas
}
pub fn clear_field_metas(&mut self) {
self.field_metas.clear();
}
// Param is passed by value, moved
pub fn set_field_metas(&mut self, v: ::protobuf::RepeatedField<FieldMeta>) {
self.field_metas = v;
}
// Mutable pointer to the field.
pub fn mut_field_metas(&mut self) -> &mut ::protobuf::RepeatedField<FieldMeta> {
&mut self.field_metas
}
// Take field
pub fn take_field_metas(&mut self) -> ::protobuf::RepeatedField<FieldMeta> {
::std::mem::replace(&mut self.field_metas, ::protobuf::RepeatedField::new())
}
// .GridBlock grid_block = 2;
pub fn get_grid_block(&self) -> &GridBlock {
self.grid_block.as_ref().unwrap_or_else(|| <GridBlock as ::protobuf::Message>::default_instance())
}
pub fn clear_grid_block(&mut self) {
self.grid_block.clear();
}
pub fn has_grid_block(&self) -> bool {
self.grid_block.is_some()
}
// Param is passed by value, moved
pub fn set_grid_block(&mut self, v: GridBlock) {
self.grid_block = ::protobuf::SingularPtrField::some(v);
}
// Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first.
pub fn mut_grid_block(&mut self) -> &mut GridBlock {
if self.grid_block.is_none() {
self.grid_block.set_default();
}
self.grid_block.as_mut().unwrap()
}
// Take field
pub fn take_grid_block(&mut self) -> GridBlock {
self.grid_block.take().unwrap_or_else(|| GridBlock::new())
}
// .GridBlockMeta grid_block_meta = 3;
pub fn get_grid_block_meta(&self) -> &GridBlockMeta {
self.grid_block_meta.as_ref().unwrap_or_else(|| <GridBlockMeta as ::protobuf::Message>::default_instance())
}
pub fn clear_grid_block_meta(&mut self) {
self.grid_block_meta.clear();
}
pub fn has_grid_block_meta(&self) -> bool {
self.grid_block_meta.is_some()
}
// Param is passed by value, moved
pub fn set_grid_block_meta(&mut self, v: GridBlockMeta) {
self.grid_block_meta = ::protobuf::SingularPtrField::some(v);
}
// Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first.
pub fn mut_grid_block_meta(&mut self) -> &mut GridBlockMeta {
if self.grid_block_meta.is_none() {
self.grid_block_meta.set_default();
}
self.grid_block_meta.as_mut().unwrap()
}
// Take field
pub fn take_grid_block_meta(&mut self) -> GridBlockMeta {
self.grid_block_meta.take().unwrap_or_else(|| GridBlockMeta::new())
}
}
impl ::protobuf::Message for BuildGridContext {
fn is_initialized(&self) -> bool {
for v in &self.field_metas {
if !v.is_initialized() {
return false;
}
};
for v in &self.grid_block {
if !v.is_initialized() {
return false;
}
};
for v in &self.grid_block_meta {
if !v.is_initialized() {
return false;
}
};
true
}
fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
while !is.eof()? {
let (field_number, wire_type) = is.read_tag_unpack()?;
match field_number {
1 => {
::protobuf::rt::read_repeated_message_into(wire_type, is, &mut self.field_metas)?;
},
2 => {
::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.grid_block)?;
},
3 => {
::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.grid_block_meta)?;
},
_ => {
::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
},
};
}
::std::result::Result::Ok(())
}
// Compute sizes of nested messages
#[allow(unused_variables)]
fn compute_size(&self) -> u32 {
let mut my_size = 0;
for value in &self.field_metas {
let len = value.compute_size();
my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
};
if let Some(ref v) = self.grid_block.as_ref() {
let len = v.compute_size();
my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
}
if let Some(ref v) = self.grid_block_meta.as_ref() {
let len = v.compute_size();
my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
}
my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
self.cached_size.set(my_size);
my_size
}
fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
for v in &self.field_metas {
os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?;
os.write_raw_varint32(v.get_cached_size())?;
v.write_to_with_cached_sizes(os)?;
};
if let Some(ref v) = self.grid_block.as_ref() {
os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?;
os.write_raw_varint32(v.get_cached_size())?;
v.write_to_with_cached_sizes(os)?;
}
if let Some(ref v) = self.grid_block_meta.as_ref() {
os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?;
os.write_raw_varint32(v.get_cached_size())?;
v.write_to_with_cached_sizes(os)?;
}
os.write_unknown_fields(self.get_unknown_fields())?;
::std::result::Result::Ok(())
}
fn get_cached_size(&self) -> u32 {
self.cached_size.get()
}
fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
&self.unknown_fields
}
fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
&mut self.unknown_fields
}
fn as_any(&self) -> &dyn (::std::any::Any) {
self as &dyn (::std::any::Any)
}
fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
self as &mut dyn (::std::any::Any)
}
fn into_any(self: ::std::boxed::Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
self
}
fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
Self::descriptor_static()
}
fn new() -> BuildGridContext {
BuildGridContext::new()
}
fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT;
descriptor.get(|| {
let mut fields = ::std::vec::Vec::new();
fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<FieldMeta>>(
"field_metas",
|m: &BuildGridContext| { &m.field_metas },
|m: &mut BuildGridContext| { &mut m.field_metas },
));
fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<GridBlock>>(
"grid_block",
|m: &BuildGridContext| { &m.grid_block },
|m: &mut BuildGridContext| { &mut m.grid_block },
));
fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<GridBlockMeta>>(
"grid_block_meta",
|m: &BuildGridContext| { &m.grid_block_meta },
|m: &mut BuildGridContext| { &mut m.grid_block_meta },
));
::protobuf::reflect::MessageDescriptor::new_pb_name::<BuildGridContext>(
"BuildGridContext",
fields,
file_descriptor_proto()
)
})
}
fn default_instance() -> &'static BuildGridContext {
static instance: ::protobuf::rt::LazyV2<BuildGridContext> = ::protobuf::rt::LazyV2::INIT;
instance.get(BuildGridContext::new)
}
}
impl ::protobuf::Clear for BuildGridContext {
fn clear(&mut self) {
self.field_metas.clear();
self.grid_block.clear();
self.grid_block_meta.clear();
self.unknown_fields.clear();
}
}
impl ::std::fmt::Debug for BuildGridContext {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
::protobuf::text_format::fmt(self, f)
}
}
impl ::protobuf::reflect::ProtobufValue for BuildGridContext {
fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
::protobuf::reflect::ReflectValueRef::Message(self)
}
}
#[derive(Clone,PartialEq,Eq,Debug,Hash)]
pub enum FieldType {
RichText = 0,
@ -3178,10 +3458,13 @@ static file_descriptor_proto_data: &'static [u8] = b"\
ata\x18\x02\x20\x01(\tR\x04data\"j\n\x11CellMetaChangeset\x12\x15\n\x06r\
ow_id\x18\x01\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x02\x20\x01\
(\tR\x07fieldId\x12\x14\n\x04data\x18\x03\x20\x01(\tH\0R\x04dataB\r\n\
\x0bone_of_data*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Nu\
mber\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingleSelect\x10\
\x03\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06\
proto3\
\x0bone_of_data\"\xa2\x01\n\x10BuildGridContext\x12+\n\x0bfield_metas\
\x18\x01\x20\x03(\x0b2\n.FieldMetaR\nfieldMetas\x12)\n\ngrid_block\x18\
\x02\x20\x01(\x0b2\n.GridBlockR\tgridBlock\x126\n\x0fgrid_block_meta\x18\
\x03\x20\x01(\x0b2\x0e.GridBlockMetaR\rgridBlockMeta*d\n\tFieldType\x12\
\x0c\n\x08RichText\x10\0\x12\n\n\x06Number\x10\x01\x12\x0c\n\x08DateTime\
\x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\x12\x0f\n\x0bMultiSelect\x10\
\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06proto3\
";
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

View File

@ -60,6 +60,11 @@ message CellMetaChangeset {
string field_id = 2;
oneof one_of_data { string data = 3; };
}
message BuildGridContext {
repeated FieldMeta field_metas = 1;
GridBlock grid_block = 2;
GridBlockMeta grid_block_meta = 3;
}
enum FieldType {
RichText = 0;
Number = 1;

View File

@ -529,7 +529,7 @@ where
self.apply("")
}
pub fn to_bytes(&self) -> Bytes {
pub fn to_delta_bytes(&self) -> Bytes {
let json = self.to_delta_str();
Bytes::from(json.into_bytes())
}