chore: add grid unit test

This commit is contained in:
appflowy 2022-03-12 22:52:24 +08:00
parent 1e6d82c0ec
commit baa70f2ee6
18 changed files with 252 additions and 169 deletions

View file

@ -215,7 +215,7 @@ class Field extends $pb.GeneratedMessage {
..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'frozen') ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'frozen')
..aOB(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') ..aOB(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility')
..a<$core.int>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'width', $pb.PbFieldType.O3) ..a<$core.int>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'width', $pb.PbFieldType.O3)
..aOM<AnyData>(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptions', subBuilder: AnyData.create) ..aOS(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptions')
..hasRequiredFields = false ..hasRequiredFields = false
; ;
@ -228,7 +228,7 @@ class Field extends $pb.GeneratedMessage {
$core.bool? frozen, $core.bool? frozen,
$core.bool? visibility, $core.bool? visibility,
$core.int? width, $core.int? width,
AnyData? typeOptions, $core.String? typeOptions,
}) { }) {
final _result = create(); final _result = create();
if (id != null) { if (id != null) {
@ -342,15 +342,13 @@ class Field extends $pb.GeneratedMessage {
void clearWidth() => clearField(7); void clearWidth() => clearField(7);
@$pb.TagNumber(8) @$pb.TagNumber(8)
AnyData get typeOptions => $_getN(7); $core.String get typeOptions => $_getSZ(7);
@$pb.TagNumber(8) @$pb.TagNumber(8)
set typeOptions(AnyData v) { setField(8, v); } set typeOptions($core.String v) { $_setString(7, v); }
@$pb.TagNumber(8) @$pb.TagNumber(8)
$core.bool hasTypeOptions() => $_has(7); $core.bool hasTypeOptions() => $_has(7);
@$pb.TagNumber(8) @$pb.TagNumber(8)
void clearTypeOptions() => clearField(8); void clearTypeOptions() => clearField(8);
@$pb.TagNumber(8)
AnyData ensureTypeOptions() => $_ensure(7);
} }
enum FieldChangeset_OneOfName { enum FieldChangeset_OneOfName {
@ -432,7 +430,7 @@ class FieldChangeset extends $pb.GeneratedMessage {
..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'frozen') ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'frozen')
..aOB(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility') ..aOB(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'visibility')
..a<$core.int>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'width', $pb.PbFieldType.O3) ..a<$core.int>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'width', $pb.PbFieldType.O3)
..aOM<AnyData>(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptions', subBuilder: AnyData.create) ..aOS(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptions')
..hasRequiredFields = false ..hasRequiredFields = false
; ;
@ -445,7 +443,7 @@ class FieldChangeset extends $pb.GeneratedMessage {
$core.bool? frozen, $core.bool? frozen,
$core.bool? visibility, $core.bool? visibility,
$core.int? width, $core.int? width,
AnyData? typeOptions, $core.String? typeOptions,
}) { }) {
final _result = create(); final _result = create();
if (fieldId != null) { if (fieldId != null) {
@ -580,15 +578,13 @@ class FieldChangeset extends $pb.GeneratedMessage {
void clearWidth() => clearField(7); void clearWidth() => clearField(7);
@$pb.TagNumber(8) @$pb.TagNumber(8)
AnyData get typeOptions => $_getN(7); $core.String get typeOptions => $_getSZ(7);
@$pb.TagNumber(8) @$pb.TagNumber(8)
set typeOptions(AnyData v) { setField(8, v); } set typeOptions($core.String v) { $_setString(7, v); }
@$pb.TagNumber(8) @$pb.TagNumber(8)
$core.bool hasTypeOptions() => $_has(7); $core.bool hasTypeOptions() => $_has(7);
@$pb.TagNumber(8) @$pb.TagNumber(8)
void clearTypeOptions() => clearField(8); void clearTypeOptions() => clearField(8);
@$pb.TagNumber(8)
AnyData ensureTypeOptions() => $_ensure(7);
} }
class RepeatedField extends $pb.GeneratedMessage { class RepeatedField extends $pb.GeneratedMessage {

View file

@ -69,12 +69,12 @@ const Field$json = const {
const {'1': 'frozen', '3': 5, '4': 1, '5': 8, '10': 'frozen'}, const {'1': 'frozen', '3': 5, '4': 1, '5': 8, '10': 'frozen'},
const {'1': 'visibility', '3': 6, '4': 1, '5': 8, '10': 'visibility'}, const {'1': 'visibility', '3': 6, '4': 1, '5': 8, '10': 'visibility'},
const {'1': 'width', '3': 7, '4': 1, '5': 5, '10': 'width'}, const {'1': 'width', '3': 7, '4': 1, '5': 5, '10': 'width'},
const {'1': 'type_options', '3': 8, '4': 1, '5': 11, '6': '.AnyData', '10': 'typeOptions'}, const {'1': 'type_options', '3': 8, '4': 1, '5': 9, '10': 'typeOptions'},
], ],
}; };
/// Descriptor for `Field`. Decode as a `google.protobuf.DescriptorProto`. /// Descriptor for `Field`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List fieldDescriptor = $convert.base64Decode('CgVGaWVsZBIOCgJpZBgBIAEoCVICaWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEikKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVSCWZpZWxkVHlwZRIWCgZmcm96ZW4YBSABKAhSBmZyb3plbhIeCgp2aXNpYmlsaXR5GAYgASgIUgp2aXNpYmlsaXR5EhQKBXdpZHRoGAcgASgFUgV3aWR0aBIrCgx0eXBlX29wdGlvbnMYCCABKAsyCC5BbnlEYXRhUgt0eXBlT3B0aW9ucw=='); final $typed_data.Uint8List fieldDescriptor = $convert.base64Decode('CgVGaWVsZBIOCgJpZBgBIAEoCVICaWQSEgoEbmFtZRgCIAEoCVIEbmFtZRISCgRkZXNjGAMgASgJUgRkZXNjEikKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVSCWZpZWxkVHlwZRIWCgZmcm96ZW4YBSABKAhSBmZyb3plbhIeCgp2aXNpYmlsaXR5GAYgASgIUgp2aXNpYmlsaXR5EhQKBXdpZHRoGAcgASgFUgV3aWR0aBIhCgx0eXBlX29wdGlvbnMYCCABKAlSC3R5cGVPcHRpb25z');
@$core.Deprecated('Use fieldChangesetDescriptor instead') @$core.Deprecated('Use fieldChangesetDescriptor instead')
const FieldChangeset$json = const { const FieldChangeset$json = const {
'1': 'FieldChangeset', '1': 'FieldChangeset',
@ -86,7 +86,7 @@ const FieldChangeset$json = const {
const {'1': 'frozen', '3': 5, '4': 1, '5': 8, '9': 3, '10': 'frozen'}, const {'1': 'frozen', '3': 5, '4': 1, '5': 8, '9': 3, '10': 'frozen'},
const {'1': 'visibility', '3': 6, '4': 1, '5': 8, '9': 4, '10': 'visibility'}, const {'1': 'visibility', '3': 6, '4': 1, '5': 8, '9': 4, '10': 'visibility'},
const {'1': 'width', '3': 7, '4': 1, '5': 5, '9': 5, '10': 'width'}, const {'1': 'width', '3': 7, '4': 1, '5': 5, '9': 5, '10': 'width'},
const {'1': 'type_options', '3': 8, '4': 1, '5': 11, '6': '.AnyData', '9': 6, '10': 'typeOptions'}, const {'1': 'type_options', '3': 8, '4': 1, '5': 9, '9': 6, '10': 'typeOptions'},
], ],
'8': const [ '8': const [
const {'1': 'one_of_name'}, const {'1': 'one_of_name'},
@ -100,7 +100,7 @@ const FieldChangeset$json = const {
}; };
/// Descriptor for `FieldChangeset`. Decode as a `google.protobuf.DescriptorProto`. /// Descriptor for `FieldChangeset`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List fieldChangesetDescriptor = $convert.base64Decode('Cg5GaWVsZENoYW5nZXNldBIZCghmaWVsZF9pZBgBIAEoCVIHZmllbGRJZBIUCgRuYW1lGAIgASgJSABSBG5hbWUSFAoEZGVzYxgDIAEoCUgBUgRkZXNjEisKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVIAlIJZmllbGRUeXBlEhgKBmZyb3plbhgFIAEoCEgDUgZmcm96ZW4SIAoKdmlzaWJpbGl0eRgGIAEoCEgEUgp2aXNpYmlsaXR5EhYKBXdpZHRoGAcgASgFSAVSBXdpZHRoEi0KDHR5cGVfb3B0aW9ucxgIIAEoCzIILkFueURhdGFIBlILdHlwZU9wdGlvbnNCDQoLb25lX29mX25hbWVCDQoLb25lX29mX2Rlc2NCEwoRb25lX29mX2ZpZWxkX3R5cGVCDwoNb25lX29mX2Zyb3plbkITChFvbmVfb2ZfdmlzaWJpbGl0eUIOCgxvbmVfb2Zfd2lkdGhCFQoTb25lX29mX3R5cGVfb3B0aW9ucw=='); final $typed_data.Uint8List fieldChangesetDescriptor = $convert.base64Decode('Cg5GaWVsZENoYW5nZXNldBIZCghmaWVsZF9pZBgBIAEoCVIHZmllbGRJZBIUCgRuYW1lGAIgASgJSABSBG5hbWUSFAoEZGVzYxgDIAEoCUgBUgRkZXNjEisKCmZpZWxkX3R5cGUYBCABKA4yCi5GaWVsZFR5cGVIAlIJZmllbGRUeXBlEhgKBmZyb3plbhgFIAEoCEgDUgZmcm96ZW4SIAoKdmlzaWJpbGl0eRgGIAEoCEgEUgp2aXNpYmlsaXR5EhYKBXdpZHRoGAcgASgFSAVSBXdpZHRoEiMKDHR5cGVfb3B0aW9ucxgIIAEoCUgGUgt0eXBlT3B0aW9uc0INCgtvbmVfb2ZfbmFtZUINCgtvbmVfb2ZfZGVzY0ITChFvbmVfb2ZfZmllbGRfdHlwZUIPCg1vbmVfb2ZfZnJvemVuQhMKEW9uZV9vZl92aXNpYmlsaXR5Qg4KDG9uZV9vZl93aWR0aEIVChNvbmVfb2ZfdHlwZV9vcHRpb25z');
@$core.Deprecated('Use repeatedFieldDescriptor instead') @$core.Deprecated('Use repeatedFieldDescriptor instead')
const RepeatedField$json = const { const RepeatedField$json = const {
'1': 'RepeatedField', '1': 'RepeatedField',

View file

@ -1073,6 +1073,8 @@ dependencies = [
"rayon", "rayon",
"rust_decimal", "rust_decimal",
"rusty-money", "rusty-money",
"serde",
"serde_json",
"strum", "strum",
"strum_macros", "strum_macros",
"tokio", "tokio",

View file

@ -12,7 +12,7 @@ pub mod errors {
pub use flowy_error::{internal_error, ErrorCode, FlowyError}; pub use flowy_error::{internal_error, ErrorCode, FlowyError};
} }
pub const DOCUMENT_SYNC_INTERVAL_IN_MILLIS: u64 = 1000; pub const TEXT_BLOCK_SYNC_INTERVAL_IN_MILLIS: u64 = 1000;
use crate::errors::FlowyError; use crate::errors::FlowyError;
use flowy_collaboration::entities::text_block_info::{ use flowy_collaboration::entities::text_block_info::{

View file

@ -1,4 +1,4 @@
use crate::{queue::EditorCommand, DOCUMENT_SYNC_INTERVAL_IN_MILLIS}; use crate::{queue::EditorCommand, TEXT_BLOCK_SYNC_INTERVAL_IN_MILLIS};
use bytes::Bytes; use bytes::Bytes;
use flowy_collaboration::{ use flowy_collaboration::{
entities::{ entities::{
@ -36,7 +36,7 @@ pub(crate) async fn make_block_ws_manager(
RichTextConflictController::new(&user_id, resolver, Arc::new(ws_data_provider.clone()), rev_manager); RichTextConflictController::new(&user_id, resolver, Arc::new(ws_data_provider.clone()), rev_manager);
let ws_data_stream = Arc::new(TextBlockRevisionWSDataStream::new(conflict_controller)); let ws_data_stream = Arc::new(TextBlockRevisionWSDataStream::new(conflict_controller));
let ws_data_sink = Arc::new(TextBlockWSDataSink(ws_data_provider)); let ws_data_sink = Arc::new(TextBlockWSDataSink(ws_data_provider));
let ping_duration = Duration::from_millis(DOCUMENT_SYNC_INTERVAL_IN_MILLIS); let ping_duration = Duration::from_millis(TEXT_BLOCK_SYNC_INTERVAL_IN_MILLIS);
let ws_manager = Arc::new(RevisionWebSocketManager::new( let ws_manager = Arc::new(RevisionWebSocketManager::new(
"Block", "Block",
&doc_id, &doc_id,

View file

@ -1,5 +1,5 @@
use flowy_block::editor::ClientTextBlockEditor; use flowy_block::editor::ClientTextBlockEditor;
use flowy_block::DOCUMENT_SYNC_INTERVAL_IN_MILLIS; use flowy_block::TEXT_BLOCK_SYNC_INTERVAL_IN_MILLIS;
use flowy_sync::disk::RevisionState; use flowy_sync::disk::RevisionState;
use flowy_test::{helper::ViewTest, FlowySDKTest}; use flowy_test::{helper::ViewTest, FlowySDKTest};
use lib_ot::{core::Interval, rich_text::RichTextDelta}; use lib_ot::{core::Interval, rich_text::RichTextDelta};
@ -80,6 +80,6 @@ impl TextBlockEditorTest {
assert_eq!(expected_delta, delta); assert_eq!(expected_delta, delta);
} }
} }
sleep(Duration::from_millis(DOCUMENT_SYNC_INTERVAL_IN_MILLIS)).await; sleep(Duration::from_millis(TEXT_BLOCK_SYNC_INTERVAL_IN_MILLIS)).await;
} }
} }

View file

@ -33,6 +33,8 @@ dashmap = "4.0"
tokio = {version = "1", features = ["sync"]} tokio = {version = "1", features = ["sync"]}
rayon = "1.5" rayon = "1.5"
parking_lot = "0.11" parking_lot = "0.11"
serde = { version = "1.0", features = ["derive"] }
serde_json = {version = "1.0"}
[dev-dependencies] [dev-dependencies]
flowy-test = { path = "../flowy-test" } flowy-test = { path = "../flowy-test" }

View file

@ -35,7 +35,7 @@ pub(crate) async fn get_fields_handler(
) -> DataResult<RepeatedField, FlowyError> { ) -> DataResult<RepeatedField, FlowyError> {
let payload: QueryFieldPayload = data.into_inner(); let payload: QueryFieldPayload = data.into_inner();
let editor = manager.get_grid_editor(&payload.grid_id)?; let editor = manager.get_grid_editor(&payload.grid_id)?;
let repeated_field = editor.get_fields(payload.field_orders).await?; let repeated_field = editor.get_fields(Some(payload.field_orders)).await?;
data_result(repeated_field) data_result(repeated_field)
} }

View file

@ -11,7 +11,7 @@ macro_rules! impl_from_field_type_option {
($target: ident) => { ($target: ident) => {
impl std::convert::From<&Field> for $target { impl std::convert::From<&Field> for $target {
fn from(field: &Field) -> $target { fn from(field: &Field) -> $target {
match $target::try_from(Bytes::from(field.type_options.value.clone())) { match serde_json::from_str(&field.type_options) {
Ok(obj) => obj, Ok(obj) => obj,
Err(err) => { Err(err) => {
tracing::error!("{} convert from any data failed, {:?}", stringify!($target), err); tracing::error!("{} convert from any data failed, {:?}", stringify!($target), err);
@ -32,19 +32,13 @@ macro_rules! impl_to_field_type_option {
} }
} }
impl std::convert::From<$target> for AnyData { impl std::convert::From<$target> for String {
fn from(field_description: $target) -> Self { fn from(field_description: $target) -> Self {
let field_type = field_description.field_type(); match serde_json::to_string(&field_description) {
match field_description.try_into() { Ok(s) => s,
Ok(bytes) => {
let bytes: Bytes = bytes;
AnyData::from_bytes(field_type, bytes)
}
Err(e) => { Err(e) => {
tracing::error!("Field type data convert to AnyData fail, error: {:?}", e); tracing::error!("Field type data convert to AnyData fail, error: {:?}", e);
// it's impossible to fail when unwrapping the default field type data serde_json::to_string(&$target::default()).unwrap()
let default_bytes: Bytes = $target::default().try_into().unwrap();
AnyData::from_bytes(field_type, default_bytes)
} }
} }
} }

View file

@ -59,7 +59,7 @@ impl FieldBuilder {
pub trait TypeOptionsBuilder { pub trait TypeOptionsBuilder {
fn field_type(&self) -> FieldType; fn field_type(&self) -> FieldType;
fn build(&self) -> AnyData; fn build(&self) -> String;
} }
// Text // Text
@ -76,7 +76,7 @@ impl TypeOptionsBuilder for RichTextTypeOptionsBuilder {
self.0.field_type() self.0.field_type()
} }
fn build(&self) -> AnyData { fn build(&self) -> String {
self.0.clone().into() self.0.clone().into()
} }
} }
@ -115,7 +115,7 @@ impl TypeOptionsBuilder for NumberTypeOptionsBuilder {
self.0.field_type() self.0.field_type()
} }
fn build(&self) -> AnyData { fn build(&self) -> String {
self.0.clone().into() self.0.clone().into()
} }
} }
@ -142,7 +142,7 @@ impl TypeOptionsBuilder for DateTypeOptionsBuilder {
self.0.field_type() self.0.field_type()
} }
fn build(&self) -> AnyData { fn build(&self) -> String {
self.0.clone().into() self.0.clone().into()
} }
} }
@ -165,7 +165,7 @@ impl TypeOptionsBuilder for SingleSelectTypeOptionsBuilder {
self.0.field_type() self.0.field_type()
} }
fn build(&self) -> AnyData { fn build(&self) -> String {
self.0.clone().into() self.0.clone().into()
} }
} }
@ -189,7 +189,7 @@ impl TypeOptionsBuilder for MultiSelectTypeOptionsBuilder {
self.0.field_type() self.0.field_type()
} }
fn build(&self) -> AnyData { fn build(&self) -> String {
self.0.clone().into() self.0.clone().into()
} }
} }
@ -211,7 +211,7 @@ impl TypeOptionsBuilder for CheckboxTypeOptionsBuilder {
self.0.field_type() self.0.field_type()
} }
fn build(&self) -> AnyData { fn build(&self) -> String {
self.0.clone().into() self.0.clone().into()
} }
} }

View file

@ -13,10 +13,11 @@ use rusty_money::{
iso::{Currency, CNY, EUR, USD}, iso::{Currency, CNY, EUR, USD},
Money, Money,
}; };
use serde::{Deserialize, Serialize};
use std::str::FromStr; use std::str::FromStr;
use strum_macros::EnumIter; use strum_macros::EnumIter;
#[derive(Debug, Clone, ProtoBuf, Default)] #[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)]
pub struct RichTextDescription { pub struct RichTextDescription {
#[pb(index = 1)] #[pb(index = 1)]
pub format: String, pub format: String,
@ -34,7 +35,7 @@ impl StringifyCellData for RichTextDescription {
} }
// Checkbox // Checkbox
#[derive(Debug, Clone, ProtoBuf, Default)] #[derive(Debug, Clone, Serialize, Deserialize, Default, ProtoBuf)]
pub struct CheckboxDescription { pub struct CheckboxDescription {
#[pb(index = 1)] #[pb(index = 1)]
pub is_selected: bool, pub is_selected: bool,
@ -56,7 +57,7 @@ impl StringifyCellData for CheckboxDescription {
} }
// Date // Date
#[derive(Clone, Debug, ProtoBuf, Default)] #[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)]
pub struct DateDescription { pub struct DateDescription {
#[pb(index = 1)] #[pb(index = 1)]
pub date_format: DateFormat, pub date_format: DateFormat,
@ -115,7 +116,7 @@ impl StringifyCellData for DateDescription {
} }
} }
#[derive(Clone, Debug, Copy, ProtoBuf_Enum)] #[derive(Clone, Debug, Copy, Serialize, Deserialize, ProtoBuf_Enum)]
pub enum DateFormat { pub enum DateFormat {
Local = 0, Local = 0,
US = 1, US = 1,
@ -158,7 +159,7 @@ impl DateFormat {
} }
} }
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, ProtoBuf_Enum)] #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize, Deserialize, ProtoBuf_Enum)]
pub enum TimeFormat { pub enum TimeFormat {
TwelveHour = 0, TwelveHour = 0,
TwentyFourHour = 1, TwentyFourHour = 1,
@ -198,7 +199,7 @@ impl std::default::Default for TimeFormat {
} }
// Single select // Single select
#[derive(Clone, Debug, ProtoBuf, Default)] #[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)]
pub struct SingleSelectDescription { pub struct SingleSelectDescription {
#[pb(index = 1)] #[pb(index = 1)]
pub options: Vec<SelectOption>, pub options: Vec<SelectOption>,
@ -219,7 +220,7 @@ impl StringifyCellData for SingleSelectDescription {
} }
// Multiple select // Multiple select
#[derive(Clone, Debug, ProtoBuf, Default)] #[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)]
pub struct MultiSelectDescription { pub struct MultiSelectDescription {
#[pb(index = 1)] #[pb(index = 1)]
pub options: Vec<SelectOption>, pub options: Vec<SelectOption>,
@ -238,7 +239,7 @@ impl StringifyCellData for MultiSelectDescription {
} }
} }
#[derive(Clone, Debug, ProtoBuf, Default)] #[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)]
pub struct SelectOption { pub struct SelectOption {
#[pb(index = 1)] #[pb(index = 1)]
pub id: String, pub id: String,
@ -261,7 +262,7 @@ impl SelectOption {
} }
// Number // Number
#[derive(Clone, Debug, ProtoBuf)] #[derive(Clone, Debug, Serialize, Deserialize, ProtoBuf)]
pub struct NumberDescription { pub struct NumberDescription {
#[pb(index = 1)] #[pb(index = 1)]
pub money: MoneySymbol, pub money: MoneySymbol,
@ -342,7 +343,7 @@ impl StringifyCellData for NumberDescription {
} }
} }
#[derive(Clone, Copy, Debug, EnumIter, ProtoBuf_Enum)] #[derive(Clone, Copy, Debug, EnumIter, Serialize, Deserialize, ProtoBuf_Enum)]
pub enum MoneySymbol { pub enum MoneySymbol {
CNY = 0, CNY = 0,
EUR = 1, EUR = 1,

View file

@ -9,7 +9,7 @@ use flowy_collaboration::entities::revision::Revision;
use flowy_collaboration::util::make_delta_from_revisions; use flowy_collaboration::util::make_delta_from_revisions;
use flowy_error::{FlowyError, FlowyResult}; use flowy_error::{FlowyError, FlowyResult};
use flowy_grid_data_model::entities::{ use flowy_grid_data_model::entities::{
Field, Grid, GridBlock, RepeatedField, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder, Field, FieldChangeset, Grid, GridBlock, RepeatedField, RepeatedFieldOrder, RepeatedRow, RepeatedRowOrder,
}; };
use flowy_sync::disk::SQLiteGridBlockMetaRevisionPersistence; use flowy_sync::disk::SQLiteGridBlockMetaRevisionPersistence;
use flowy_sync::{ use flowy_sync::{
@ -60,6 +60,11 @@ impl ClientGridEditor {
Ok(()) Ok(())
} }
pub async fn update_field(&self, change: FieldChangeset) -> FlowyResult<()> {
let _ = self.modify(|grid| Ok(grid.update_field(change)?)).await?;
Ok(())
}
pub async fn delete_field(&self, field_id: &str) -> FlowyResult<()> { pub async fn delete_field(&self, field_id: &str) -> FlowyResult<()> {
let _ = self.modify(|grid| Ok(grid.delete_field(field_id)?)).await?; let _ = self.modify(|grid| Ok(grid.delete_field(field_id)?)).await?;
Ok(()) Ok(())
@ -81,7 +86,7 @@ impl ClientGridEditor {
todo!() todo!()
} }
pub async fn get_fields(&self, field_orders: RepeatedFieldOrder) -> FlowyResult<RepeatedField> { pub async fn get_fields(&self, field_orders: Option<RepeatedFieldOrder>) -> FlowyResult<RepeatedField> {
let fields = self.grid_meta_pad.read().await.get_fields(field_orders)?; let fields = self.grid_meta_pad.read().await.get_fields(field_orders)?;
Ok(fields) Ok(fields)
} }

View file

@ -1,14 +1,98 @@
use crate::grid::script::EditorScript::*; use crate::grid::script::EditorScript::*;
use crate::grid::script::*; use crate::grid::script::*;
use flowy_grid::services::field::{SelectOption, SingleSelectDescription};
use flowy_grid_data_model::entities::FieldChangeset;
#[tokio::test] #[tokio::test]
async fn grid_creat_field_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 text_field = create_text_field();
let single_select_field = create_single_select_field();
let scripts = vec![
AssertFieldCount(2),
CreateField {
field: text_field.clone(),
},
AssertFieldEqual {
field_index: 2,
field: text_field,
},
AssertFieldCount(3),
CreateField {
field: single_select_field.clone(),
},
AssertFieldEqual {
field_index: 3,
field: single_select_field,
},
AssertFieldCount(4),
];
GridEditorTest::new().await.run_scripts(scripts).await;
}
#[tokio::test]
async fn grid_update_field_with_empty_change() {
let single_select_field = create_single_select_field();
let change = FieldChangeset {
field_id: single_select_field.id.clone(),
name: None,
desc: None,
field_type: None,
frozen: None,
visibility: None,
width: None,
type_options: None,
};
let scripts = vec![ let scripts = vec![
CreateField { CreateField {
field: create_text_field(), field: single_select_field.clone(),
}, },
UpdateField { change },
AssertFieldEqual {
field_index: 2,
field: single_select_field,
},
];
GridEditorTest::new().await.run_scripts(scripts).await;
}
#[tokio::test]
async fn grid_update_field() {
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 change = FieldChangeset {
field_id: single_select_field.id.clone(),
name: None,
desc: None,
field_type: None,
frozen: Some(true),
visibility: None,
width: Some(1000),
type_options: Some(single_select_type_options.clone().into()),
};
cloned_field.frozen = true;
cloned_field.width = 1000;
cloned_field.type_options = single_select_type_options.into();
let scripts = vec![
CreateField { CreateField {
field: create_single_select_field(), field: single_select_field.clone(),
},
UpdateField { change },
AssertFieldEqual {
field_index: 2,
field: cloned_field,
}, },
AssertGridMetaPad, AssertGridMetaPad,
]; ];

View file

@ -1,15 +1,21 @@
use flowy_grid::services::field::*; use flowy_grid::services::field::*;
use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder}; use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder};
use flowy_grid_data_model::entities::{AnyData, Field, FieldType}; use flowy_grid_data_model::entities::{AnyData, Field, FieldChangeset, FieldType};
use flowy_sync::REVISION_WRITE_INTERVAL_IN_MILLIS;
use flowy_test::event_builder::FolderEventBuilder; use flowy_test::event_builder::FolderEventBuilder;
use flowy_test::helper::ViewTest; use flowy_test::helper::ViewTest;
use flowy_test::FlowySDKTest; use flowy_test::FlowySDKTest;
use std::sync::Arc; use std::sync::Arc;
use std::time::Duration;
use tokio::time::sleep;
pub enum EditorScript { pub enum EditorScript {
CreateField { field: Field }, CreateField { field: Field },
CreateRow, UpdateField { change: FieldChangeset },
AssertFieldCount(usize),
AssertFieldEqual { field_index: usize, field: Field },
AssertGridMetaPad, AssertGridMetaPad,
CreateRow,
} }
pub struct GridEditorTest { pub struct GridEditorTest {
@ -44,12 +50,24 @@ impl GridEditorTest {
EditorScript::CreateField { field } => { EditorScript::CreateField { field } => {
self.editor.create_field(field).await.unwrap(); self.editor.create_field(field).await.unwrap();
} }
EditorScript::CreateRow => {} EditorScript::UpdateField { change } => {
self.editor.update_field(change).await.unwrap();
}
EditorScript::AssertFieldCount(count) => {
assert_eq!(self.editor.get_fields(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::AssertGridMetaPad => { EditorScript::AssertGridMetaPad => {
sleep(Duration::from_millis(2 * REVISION_WRITE_INTERVAL_IN_MILLIS)).await;
let mut grid_rev_manager = grid_manager.make_grid_rev_manager(&self.grid_id, pool.clone()).unwrap(); let mut grid_rev_manager = grid_manager.make_grid_rev_manager(&self.grid_id, pool.clone()).unwrap();
let grid_pad = grid_rev_manager.load::<GridPadBuilder>(None).await.unwrap(); let grid_pad = grid_rev_manager.load::<GridPadBuilder>(None).await.unwrap();
println!("{}", grid_pad.delta_str()); println!("{}", grid_pad.delta_str());
} }
EditorScript::CreateRow => {}
} }
} }
} }

View file

@ -51,25 +51,30 @@ impl GridMetaPad {
}) })
} }
pub fn get_fields(&self, field_orders: RepeatedFieldOrder) -> CollaborateResult<RepeatedField> { pub fn get_fields(&self, field_orders: Option<RepeatedFieldOrder>) -> CollaborateResult<RepeatedField> {
let field_by_field_id = self match field_orders {
.grid_meta None => Ok(self.grid_meta.fields.clone().into()),
.fields Some(field_orders) => {
.iter() let field_by_field_id = self
.map(|field| (&field.id, field)) .grid_meta
.collect::<HashMap<&String, &Field>>(); .fields
.iter()
.map(|field| (&field.id, field))
.collect::<HashMap<&String, &Field>>();
let fields = field_orders let fields = field_orders
.iter() .iter()
.flat_map(|field_order| match field_by_field_id.get(&field_order.field_id) { .flat_map(|field_order| match field_by_field_id.get(&field_order.field_id) {
None => { None => {
tracing::error!("Can't find the field with id: {}", field_order.field_id); tracing::error!("Can't find the field with id: {}", field_order.field_id);
None None
} }
Some(field) => Some((*field).clone()), Some(field) => Some((*field).clone()),
}) })
.collect::<Vec<Field>>(); .collect::<Vec<Field>>();
Ok(fields.into()) Ok(fields.into())
}
}
} }
pub fn update_field(&mut self, change: FieldChangeset) -> CollaborateResult<Option<GridChange>> { pub fn update_field(&mut self, change: FieldChangeset) -> CollaborateResult<Option<GridChange>> {

View file

@ -54,7 +54,7 @@ pub struct GridBlockMeta {
pub rows: Vec<RowMeta>, pub rows: Vec<RowMeta>,
} }
#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)] #[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf, PartialEq, Eq)]
pub struct Field { pub struct Field {
#[pb(index = 1)] #[pb(index = 1)]
pub id: String, pub id: String,
@ -78,7 +78,7 @@ pub struct Field {
pub width: i32, pub width: i32,
#[pb(index = 8)] #[pb(index = 8)]
pub type_options: AnyData, pub type_options: String,
} }
impl Field { impl Field {
@ -120,7 +120,7 @@ pub struct FieldChangeset {
pub width: Option<i32>, pub width: Option<i32>,
#[pb(index = 8, one_of)] #[pb(index = 8, one_of)]
pub type_options: Option<AnyData>, pub type_options: Option<String>,
} }
#[derive(Debug, Default, ProtoBuf)] #[derive(Debug, Default, ProtoBuf)]

View file

@ -727,7 +727,7 @@ pub struct Field {
pub frozen: bool, pub frozen: bool,
pub visibility: bool, pub visibility: bool,
pub width: i32, pub width: i32,
pub type_options: ::protobuf::SingularPtrField<AnyData>, pub type_options: ::std::string::String,
// special fields // special fields
pub unknown_fields: ::protobuf::UnknownFields, pub unknown_fields: ::protobuf::UnknownFields,
pub cached_size: ::protobuf::CachedSize, pub cached_size: ::protobuf::CachedSize,
@ -882,47 +882,35 @@ impl Field {
self.width = v; self.width = v;
} }
// .AnyData type_options = 8; // string type_options = 8;
pub fn get_type_options(&self) -> &AnyData { pub fn get_type_options(&self) -> &str {
self.type_options.as_ref().unwrap_or_else(|| <AnyData as ::protobuf::Message>::default_instance()) &self.type_options
} }
pub fn clear_type_options(&mut self) { pub fn clear_type_options(&mut self) {
self.type_options.clear(); self.type_options.clear();
} }
pub fn has_type_options(&self) -> bool {
self.type_options.is_some()
}
// Param is passed by value, moved // Param is passed by value, moved
pub fn set_type_options(&mut self, v: AnyData) { pub fn set_type_options(&mut self, v: ::std::string::String) {
self.type_options = ::protobuf::SingularPtrField::some(v); self.type_options = v;
} }
// Mutable pointer to the field. // Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first. // If field is not initialized, it is initialized with default value first.
pub fn mut_type_options(&mut self) -> &mut AnyData { pub fn mut_type_options(&mut self) -> &mut ::std::string::String {
if self.type_options.is_none() { &mut self.type_options
self.type_options.set_default();
}
self.type_options.as_mut().unwrap()
} }
// Take field // Take field
pub fn take_type_options(&mut self) -> AnyData { pub fn take_type_options(&mut self) -> ::std::string::String {
self.type_options.take().unwrap_or_else(|| AnyData::new()) ::std::mem::replace(&mut self.type_options, ::std::string::String::new())
} }
} }
impl ::protobuf::Message for Field { impl ::protobuf::Message for Field {
fn is_initialized(&self) -> bool { fn is_initialized(&self) -> bool {
for v in &self.type_options {
if !v.is_initialized() {
return false;
}
};
true true
} }
@ -964,7 +952,7 @@ impl ::protobuf::Message for Field {
self.width = tmp; self.width = tmp;
}, },
8 => { 8 => {
::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.type_options)?; ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.type_options)?;
}, },
_ => { _ => {
::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
@ -999,9 +987,8 @@ impl ::protobuf::Message for Field {
if self.width != 0 { if self.width != 0 {
my_size += ::protobuf::rt::value_size(7, self.width, ::protobuf::wire_format::WireTypeVarint); my_size += ::protobuf::rt::value_size(7, self.width, ::protobuf::wire_format::WireTypeVarint);
} }
if let Some(ref v) = self.type_options.as_ref() { if !self.type_options.is_empty() {
let len = v.compute_size(); my_size += ::protobuf::rt::string_size(8, &self.type_options);
my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
} }
my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
self.cached_size.set(my_size); self.cached_size.set(my_size);
@ -1030,10 +1017,8 @@ impl ::protobuf::Message for Field {
if self.width != 0 { if self.width != 0 {
os.write_int32(7, self.width)?; os.write_int32(7, self.width)?;
} }
if let Some(ref v) = self.type_options.as_ref() { if !self.type_options.is_empty() {
os.write_tag(8, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_string(8, &self.type_options)?;
os.write_raw_varint32(v.get_cached_size())?;
v.write_to_with_cached_sizes(os)?;
} }
os.write_unknown_fields(self.get_unknown_fields())?; os.write_unknown_fields(self.get_unknown_fields())?;
::std::result::Result::Ok(()) ::std::result::Result::Ok(())
@ -1108,7 +1093,7 @@ impl ::protobuf::Message for Field {
|m: &Field| { &m.width }, |m: &Field| { &m.width },
|m: &mut Field| { &mut m.width }, |m: &mut Field| { &mut m.width },
)); ));
fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<AnyData>>( fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
"type_options", "type_options",
|m: &Field| { &m.type_options }, |m: &Field| { &m.type_options },
|m: &mut Field| { &mut m.type_options }, |m: &mut Field| { &mut m.type_options },
@ -1208,7 +1193,7 @@ pub enum FieldChangeset_oneof_one_of_width {
#[derive(Clone,PartialEq,Debug)] #[derive(Clone,PartialEq,Debug)]
pub enum FieldChangeset_oneof_one_of_type_options { pub enum FieldChangeset_oneof_one_of_type_options {
type_options(AnyData), type_options(::std::string::String),
} }
impl FieldChangeset { impl FieldChangeset {
@ -1440,13 +1425,13 @@ impl FieldChangeset {
self.one_of_width = ::std::option::Option::Some(FieldChangeset_oneof_one_of_width::width(v)) self.one_of_width = ::std::option::Option::Some(FieldChangeset_oneof_one_of_width::width(v))
} }
// .AnyData type_options = 8; // string type_options = 8;
pub fn get_type_options(&self) -> &AnyData { pub fn get_type_options(&self) -> &str {
match self.one_of_type_options { match self.one_of_type_options {
::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(ref v)) => v, ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(ref v)) => v,
_ => <AnyData as ::protobuf::Message>::default_instance(), _ => "",
} }
} }
pub fn clear_type_options(&mut self) { pub fn clear_type_options(&mut self) {
@ -1461,15 +1446,15 @@ impl FieldChangeset {
} }
// Param is passed by value, moved // Param is passed by value, moved
pub fn set_type_options(&mut self, v: AnyData) { pub fn set_type_options(&mut self, v: ::std::string::String) {
self.one_of_type_options = ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(v)) self.one_of_type_options = ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(v))
} }
// Mutable pointer to the field. // Mutable pointer to the field.
pub fn mut_type_options(&mut self) -> &mut AnyData { pub fn mut_type_options(&mut self) -> &mut ::std::string::String {
if let ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(_)) = self.one_of_type_options { if let ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(_)) = self.one_of_type_options {
} else { } else {
self.one_of_type_options = ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(AnyData::new())); self.one_of_type_options = ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(::std::string::String::new()));
} }
match self.one_of_type_options { match self.one_of_type_options {
::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(ref mut v)) => v, ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(ref mut v)) => v,
@ -1478,25 +1463,20 @@ impl FieldChangeset {
} }
// Take field // Take field
pub fn take_type_options(&mut self) -> AnyData { pub fn take_type_options(&mut self) -> ::std::string::String {
if self.has_type_options() { if self.has_type_options() {
match self.one_of_type_options.take() { match self.one_of_type_options.take() {
::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(v)) => v, ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(v)) => v,
_ => panic!(), _ => panic!(),
} }
} else { } else {
AnyData::new() ::std::string::String::new()
} }
} }
} }
impl ::protobuf::Message for FieldChangeset { impl ::protobuf::Message for FieldChangeset {
fn is_initialized(&self) -> bool { fn is_initialized(&self) -> bool {
if let Some(FieldChangeset_oneof_one_of_type_options::type_options(ref v)) = self.one_of_type_options {
if !v.is_initialized() {
return false;
}
}
true true
} }
@ -1547,7 +1527,7 @@ impl ::protobuf::Message for FieldChangeset {
if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
} }
self.one_of_type_options = ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(is.read_message()?)); self.one_of_type_options = ::std::option::Option::Some(FieldChangeset_oneof_one_of_type_options::type_options(is.read_string()?));
}, },
_ => { _ => {
::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
@ -1609,8 +1589,7 @@ impl ::protobuf::Message for FieldChangeset {
if let ::std::option::Option::Some(ref v) = self.one_of_type_options { if let ::std::option::Option::Some(ref v) = self.one_of_type_options {
match v { match v {
&FieldChangeset_oneof_one_of_type_options::type_options(ref v) => { &FieldChangeset_oneof_one_of_type_options::type_options(ref v) => {
let len = v.compute_size(); my_size += ::protobuf::rt::string_size(8, &v);
my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
}, },
}; };
} }
@ -1668,9 +1647,7 @@ impl ::protobuf::Message for FieldChangeset {
if let ::std::option::Option::Some(ref v) = self.one_of_type_options { if let ::std::option::Option::Some(ref v) = self.one_of_type_options {
match v { match v {
&FieldChangeset_oneof_one_of_type_options::type_options(ref v) => { &FieldChangeset_oneof_one_of_type_options::type_options(ref v) => {
os.write_tag(8, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_string(8, v)?;
os.write_raw_varint32(v.get_cached_size())?;
v.write_to_with_cached_sizes(os)?;
}, },
}; };
} }
@ -1747,7 +1724,7 @@ impl ::protobuf::Message for FieldChangeset {
FieldChangeset::has_width, FieldChangeset::has_width,
FieldChangeset::get_width, FieldChangeset::get_width,
)); ));
fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, AnyData>( fields.push(::protobuf::reflect::accessor::make_singular_string_accessor::<_>(
"type_options", "type_options",
FieldChangeset::has_type_options, FieldChangeset::has_type_options,
FieldChangeset::get_type_options, FieldChangeset::get_type_options,
@ -3183,46 +3160,45 @@ static file_descriptor_proto_data: &'static [u8] = b"\
ndex\x18\x02\x20\x01(\x05R\rstartRowIndex\x12\x1b\n\trow_count\x18\x03\ ndex\x18\x02\x20\x01(\x05R\rstartRowIndex\x12\x1b\n\trow_count\x18\x03\
\x20\x01(\x05R\x08rowCount\"H\n\rGridBlockMeta\x12\x19\n\x08block_id\x18\ \x20\x01(\x05R\x08rowCount\"H\n\rGridBlockMeta\x12\x19\n\x08block_id\x18\
\x01\x20\x01(\tR\x07blockId\x12\x1c\n\x04rows\x18\x02\x20\x03(\x0b2\x08.\ \x01\x20\x01(\tR\x07blockId\x12\x1c\n\x04rows\x18\x02\x20\x03(\x0b2\x08.\
RowMetaR\x04rows\"\xe5\x01\n\x05Field\x12\x0e\n\x02id\x18\x01\x20\x01(\t\ RowMetaR\x04rows\"\xdb\x01\n\x05Field\x12\x0e\n\x02id\x18\x01\x20\x01(\t\
R\x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\ R\x02id\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\
\x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_type\x18\x04\x20\x01(\x0e2\n.\ \x18\x03\x20\x01(\tR\x04desc\x12)\n\nfield_type\x18\x04\x20\x01(\x0e2\n.\
FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\x08R\x06froze\ FieldTypeR\tfieldType\x12\x16\n\x06frozen\x18\x05\x20\x01(\x08R\x06froze\
n\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\x12\x14\n\x05w\ n\x12\x1e\n\nvisibility\x18\x06\x20\x01(\x08R\nvisibility\x12\x14\n\x05w\
idth\x18\x07\x20\x01(\x05R\x05width\x12+\n\x0ctype_options\x18\x08\x20\ idth\x18\x07\x20\x01(\x05R\x05width\x12!\n\x0ctype_options\x18\x08\x20\
\x01(\x0b2\x08.AnyDataR\x0btypeOptions\"\x87\x03\n\x0eFieldChangeset\x12\ \x01(\tR\x0btypeOptions\"\xfd\x02\n\x0eFieldChangeset\x12\x19\n\x08field\
\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\x14\n\x04name\x18\ _id\x18\x01\x20\x01(\tR\x07fieldId\x12\x14\n\x04name\x18\x02\x20\x01(\tH\
\x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\x01(\tH\x01R\ \0R\x04name\x12\x14\n\x04desc\x18\x03\x20\x01(\tH\x01R\x04desc\x12+\n\nf\
\x04desc\x12+\n\nfield_type\x18\x04\x20\x01(\x0e2\n.FieldTypeH\x02R\tfie\ ield_type\x18\x04\x20\x01(\x0e2\n.FieldTypeH\x02R\tfieldType\x12\x18\n\
ldType\x12\x18\n\x06frozen\x18\x05\x20\x01(\x08H\x03R\x06frozen\x12\x20\ \x06frozen\x18\x05\x20\x01(\x08H\x03R\x06frozen\x12\x20\n\nvisibility\
\n\nvisibility\x18\x06\x20\x01(\x08H\x04R\nvisibility\x12\x16\n\x05width\ \x18\x06\x20\x01(\x08H\x04R\nvisibility\x12\x16\n\x05width\x18\x07\x20\
\x18\x07\x20\x01(\x05H\x05R\x05width\x12-\n\x0ctype_options\x18\x08\x20\ \x01(\x05H\x05R\x05width\x12#\n\x0ctype_options\x18\x08\x20\x01(\tH\x06R\
\x01(\x0b2\x08.AnyDataH\x06R\x0btypeOptionsB\r\n\x0bone_of_nameB\r\n\x0b\ \x0btypeOptionsB\r\n\x0bone_of_nameB\r\n\x0bone_of_descB\x13\n\x11one_of\
one_of_descB\x13\n\x11one_of_field_typeB\x0f\n\rone_of_frozenB\x13\n\x11\ _field_typeB\x0f\n\rone_of_frozenB\x13\n\x11one_of_visibilityB\x0e\n\x0c\
one_of_visibilityB\x0e\n\x0cone_of_widthB\x15\n\x13one_of_type_options\"\ one_of_widthB\x15\n\x13one_of_type_options\"-\n\rRepeatedField\x12\x1c\n\
-\n\rRepeatedField\x12\x1c\n\x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\ \x05items\x18\x01\x20\x03(\x0b2\x06.FieldR\x05items\"8\n\x07AnyData\x12\
\x05items\"8\n\x07AnyData\x12\x17\n\x07type_id\x18\x01\x20\x01(\tR\x06ty\ \x17\n\x07type_id\x18\x01\x20\x01(\tR\x06typeId\x12\x14\n\x05value\x18\
peId\x12\x14\n\x05value\x18\x02\x20\x01(\x0cR\x05value\"\xff\x01\n\x07Ro\ \x02\x20\x01(\x0cR\x05value\"\xff\x01\n\x07RowMeta\x12\x0e\n\x02id\x18\
wMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x19\n\x08block_id\ \x01\x20\x01(\tR\x02id\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07bloc\
\x18\x02\x20\x01(\tR\x07blockId\x12D\n\x10cell_by_field_id\x18\x03\x20\ kId\x12D\n\x10cell_by_field_id\x18\x03\x20\x03(\x0b2\x1b.RowMeta.CellByF\
\x03(\x0b2\x1b.RowMeta.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06h\ ieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x04\x20\x01(\x05R\
eight\x18\x04\x20\x01(\x05R\x06height\x12\x1e\n\nvisibility\x18\x05\x20\ \x06height\x12\x1e\n\nvisibility\x18\x05\x20\x01(\x08R\nvisibility\x1aK\
\x01(\x08R\nvisibility\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\ \n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\
\x01\x20\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellM\ \x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\x028\x01\"\
etaR\x05value:\x028\x01\"\xa7\x02\n\x10RowMetaChangeset\x12\x15\n\x06row\ \xa7\x02\n\x10RowMetaChangeset\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\
_id\x18\x01\x20\x01(\tR\x05rowId\x12\x18\n\x06height\x18\x02\x20\x01(\ \x05rowId\x12\x18\n\x06height\x18\x02\x20\x01(\x05H\0R\x06height\x12\x20\
\x05H\0R\x06height\x12\x20\n\nvisibility\x18\x03\x20\x01(\x08H\x01R\nvis\ \n\nvisibility\x18\x03\x20\x01(\x08H\x01R\nvisibility\x12M\n\x10cell_by_\
ibility\x12M\n\x10cell_by_field_id\x18\x04\x20\x03(\x0b2$.RowMetaChanges\ field_id\x18\x04\x20\x03(\x0b2$.RowMetaChangeset.CellByFieldIdEntryR\rce\
et.CellByFieldIdEntryR\rcellByFieldId\x1aK\n\x12CellByFieldIdEntry\x12\ llByFieldId\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\
\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\ \x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05\
\x01(\x0b2\t.CellMetaR\x05value:\x028\x01B\x0f\n\rone_of_heightB\x13\n\ value:\x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one_of_visibility\"\x82\
\x11one_of_visibility\"\x82\x01\n\x08CellMeta\x12\x0e\n\x02id\x18\x01\ \x01\n\x08CellMeta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x15\n\
\x20\x01(\tR\x02id\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\ \x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\
\x19\n\x08field_id\x18\x03\x20\x01(\tR\x07fieldId\x12\x1c\n\x04data\x18\ \x20\x01(\tR\x07fieldId\x12\x1c\n\x04data\x18\x04\x20\x01(\x0b2\x08.AnyD\
\x04\x20\x01(\x0b2\x08.AnyDataR\x04data\x12\x16\n\x06height\x18\x05\x20\ ataR\x04data\x12\x16\n\x06height\x18\x05\x20\x01(\x05R\x06height*d\n\tFi\
\x01(\x05R\x06height*d\n\tFieldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\ eldType\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Number\x10\x01\x12\x0c\n\
\x06Number\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0cSingleSele\ \x08DateTime\x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\x12\x0f\n\x0bMult\
ct\x10\x03\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\ iSelect\x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06proto3\
\x05b\x06proto3\
"; ";
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

View file

@ -22,7 +22,7 @@ message Field {
bool frozen = 5; bool frozen = 5;
bool visibility = 6; bool visibility = 6;
int32 width = 7; int32 width = 7;
AnyData type_options = 8; string type_options = 8;
} }
message FieldChangeset { message FieldChangeset {
string field_id = 1; string field_id = 1;
@ -32,7 +32,7 @@ message FieldChangeset {
oneof one_of_frozen { bool frozen = 5; }; oneof one_of_frozen { bool frozen = 5; };
oneof one_of_visibility { bool visibility = 6; }; oneof one_of_visibility { bool visibility = 6; };
oneof one_of_width { int32 width = 7; }; oneof one_of_width { int32 width = 7; };
oneof one_of_type_options { AnyData type_options = 8; }; oneof one_of_type_options { string type_options = 8; };
} }
message RepeatedField { message RepeatedField {
repeated Field items = 1; repeated Field items = 1;