mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
fix: serde type option data
This commit is contained in:
parent
90e7873135
commit
28948e567c
@ -215,7 +215,7 @@ class FieldMeta extends $pb.GeneratedMessage {
|
||||
..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'frozen')
|
||||
..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)
|
||||
..aOS(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOption')
|
||||
..aOS(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'typeOptionJson')
|
||||
..hasRequiredFields = false
|
||||
;
|
||||
|
||||
@ -228,7 +228,7 @@ class FieldMeta extends $pb.GeneratedMessage {
|
||||
$core.bool? frozen,
|
||||
$core.bool? visibility,
|
||||
$core.int? width,
|
||||
$core.String? typeOption,
|
||||
$core.String? typeOptionJson,
|
||||
}) {
|
||||
final _result = create();
|
||||
if (id != null) {
|
||||
@ -252,8 +252,8 @@ class FieldMeta extends $pb.GeneratedMessage {
|
||||
if (width != null) {
|
||||
_result.width = width;
|
||||
}
|
||||
if (typeOption != null) {
|
||||
_result.typeOption = typeOption;
|
||||
if (typeOptionJson != null) {
|
||||
_result.typeOptionJson = typeOptionJson;
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
@ -342,13 +342,13 @@ class FieldMeta extends $pb.GeneratedMessage {
|
||||
void clearWidth() => clearField(7);
|
||||
|
||||
@$pb.TagNumber(8)
|
||||
$core.String get typeOption => $_getSZ(7);
|
||||
$core.String get typeOptionJson => $_getSZ(7);
|
||||
@$pb.TagNumber(8)
|
||||
set typeOption($core.String v) { $_setString(7, v); }
|
||||
set typeOptionJson($core.String v) { $_setString(7, v); }
|
||||
@$pb.TagNumber(8)
|
||||
$core.bool hasTypeOption() => $_has(7);
|
||||
$core.bool hasTypeOptionJson() => $_has(7);
|
||||
@$pb.TagNumber(8)
|
||||
void clearTypeOption() => clearField(8);
|
||||
void clearTypeOptionJson() => clearField(8);
|
||||
}
|
||||
|
||||
enum FieldChangeset_OneOfName {
|
||||
|
@ -69,12 +69,12 @@ const FieldMeta$json = const {
|
||||
const {'1': 'frozen', '3': 5, '4': 1, '5': 8, '10': 'frozen'},
|
||||
const {'1': 'visibility', '3': 6, '4': 1, '5': 8, '10': 'visibility'},
|
||||
const {'1': 'width', '3': 7, '4': 1, '5': 5, '10': 'width'},
|
||||
const {'1': 'type_option', '3': 8, '4': 1, '5': 9, '10': 'typeOption'},
|
||||
const {'1': 'type_option_json', '3': 8, '4': 1, '5': 9, '10': 'typeOptionJson'},
|
||||
],
|
||||
};
|
||||
|
||||
/// Descriptor for `FieldMeta`. Decode as a `google.protobuf.DescriptorProto`.
|
||||
final $typed_data.Uint8List fieldMetaDescriptor = $convert.base64Decode('CglGaWVsZE1ldGESDgoCaWQYASABKAlSAmlkEhIKBG5hbWUYAiABKAlSBG5hbWUSEgoEZGVzYxgDIAEoCVIEZGVzYxIpCgpmaWVsZF90eXBlGAQgASgOMgouRmllbGRUeXBlUglmaWVsZFR5cGUSFgoGZnJvemVuGAUgASgIUgZmcm96ZW4SHgoKdmlzaWJpbGl0eRgGIAEoCFIKdmlzaWJpbGl0eRIUCgV3aWR0aBgHIAEoBVIFd2lkdGgSHwoLdHlwZV9vcHRpb24YCCABKAlSCnR5cGVPcHRpb24=');
|
||||
final $typed_data.Uint8List fieldMetaDescriptor = $convert.base64Decode('CglGaWVsZE1ldGESDgoCaWQYASABKAlSAmlkEhIKBG5hbWUYAiABKAlSBG5hbWUSEgoEZGVzYxgDIAEoCVIEZGVzYxIpCgpmaWVsZF90eXBlGAQgASgOMgouRmllbGRUeXBlUglmaWVsZFR5cGUSFgoGZnJvemVuGAUgASgIUgZmcm96ZW4SHgoKdmlzaWJpbGl0eRgGIAEoCFIKdmlzaWJpbGl0eRIUCgV3aWR0aBgHIAEoBVIFd2lkdGgSKAoQdHlwZV9vcHRpb25fanNvbhgIIAEoCVIOdHlwZU9wdGlvbkpzb24=');
|
||||
@$core.Deprecated('Use fieldChangesetDescriptor instead')
|
||||
const FieldChangeset$json = const {
|
||||
'1': 'FieldChangeset',
|
||||
|
@ -1,4 +1,5 @@
|
||||
use crate::manager::GridManager;
|
||||
use crate::services::field::type_option_data_from_str;
|
||||
use flowy_error::FlowyError;
|
||||
use flowy_grid_data_model::entities::{
|
||||
CellMetaChangeset, CreateEditFieldContextParams, CreateFieldPayload, CreateRowPayload, EditFieldContext, Field,
|
||||
@ -73,22 +74,20 @@ pub(crate) async fn create_field_handler(
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(data, manager), err)]
|
||||
pub(crate) async fn create_field_edit_context_handler(
|
||||
pub(crate) async fn create_edit_field_context_handler(
|
||||
data: Data<CreateEditFieldContextParams>,
|
||||
manager: AppData<Arc<GridManager>>,
|
||||
) -> DataResult<EditFieldContext, FlowyError> {
|
||||
let params: CreateEditFieldContextParams = data.into_inner();
|
||||
let editor = manager.get_grid_editor(¶ms.grid_id)?;
|
||||
let field_meta = editor.make_field_meta_from_ty(¶ms.field_type).await?;
|
||||
let type_option_data = field_meta.type_option.as_bytes().to_vec();
|
||||
let field_meta = editor.default_field_meta(¶ms.field_type).await?;
|
||||
let type_option_data = type_option_data_from_str(&field_meta.type_option_json, &field_meta.field_type);
|
||||
let field: Field = field_meta.into();
|
||||
|
||||
let edit_context = EditFieldContext {
|
||||
grid_id: params.grid_id,
|
||||
grid_field: field,
|
||||
type_option_data,
|
||||
};
|
||||
|
||||
data_result(edit_context)
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@ pub fn create(grid_manager: Arc<GridManager>) -> Module {
|
||||
.event(GridEvent::GetFields, get_fields_handler)
|
||||
.event(GridEvent::UpdateField, update_field_handler)
|
||||
.event(GridEvent::CreateField, create_field_handler)
|
||||
.event(GridEvent::CreateEditFieldContext, create_field_edit_context_handler)
|
||||
.event(GridEvent::CreateEditFieldContext, create_edit_field_context_handler)
|
||||
.event(GridEvent::CreateRow, create_row_handler)
|
||||
.event(GridEvent::GetRow, get_row_handler)
|
||||
.event(GridEvent::UpdateCell, update_cell_handler);
|
||||
|
@ -1,3 +1,29 @@
|
||||
#[macro_export]
|
||||
macro_rules! impl_into_box_type_option_builder {
|
||||
($target: ident) => {
|
||||
impl std::convert::Into<BoxTypeOptionBuilder> for $target {
|
||||
fn into(self) -> Box<dyn TypeOptionBuilder> {
|
||||
Box::new(self)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_from_json_str_and_from_bytes {
|
||||
($target: ident,$type_option: ident) => {
|
||||
impl $target {
|
||||
pub fn from_json_str(s: &str) -> $target {
|
||||
$target($type_option::from(s))
|
||||
}
|
||||
|
||||
pub fn from_bytes(bytes: Bytes) -> $target {
|
||||
let type_option = $type_option::try_from(bytes).unwrap_or($type_option::default());
|
||||
$target(type_option)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! impl_from_and_to_type_option {
|
||||
($target: ident, $field_type:expr) => {
|
||||
@ -11,7 +37,13 @@ macro_rules! impl_from_field_type_option {
|
||||
($target: ident) => {
|
||||
impl std::convert::From<&FieldMeta> for $target {
|
||||
fn from(field_meta: &FieldMeta) -> $target {
|
||||
match serde_json::from_str(&field_meta.type_option) {
|
||||
$target::from(field_meta.type_option_json.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<&str> for $target {
|
||||
fn from(type_option_str: &str) -> $target {
|
||||
match serde_json::from_str(type_option_str) {
|
||||
Ok(obj) => obj,
|
||||
Err(err) => {
|
||||
tracing::error!("{} convert from any data failed, {:?}", stringify!($target), err);
|
||||
|
@ -1,22 +1,26 @@
|
||||
use crate::services::field::type_options::*;
|
||||
use bytes::Bytes;
|
||||
use flowy_grid_data_model::entities::{FieldMeta, FieldType};
|
||||
|
||||
pub struct FieldBuilder {
|
||||
field_meta: FieldMeta,
|
||||
type_option_builder: Box<dyn TypeOptionsBuilder>,
|
||||
type_option_builder: Box<dyn TypeOptionBuilder>,
|
||||
}
|
||||
|
||||
pub type BoxTypeOptionBuilder = Box<dyn TypeOptionBuilder + 'static>;
|
||||
|
||||
impl FieldBuilder {
|
||||
pub fn new<T: TypeOptionsBuilder + 'static>(type_option_builder: T) -> Self {
|
||||
pub fn new<T: Into<BoxTypeOptionBuilder>>(type_option_builder: T) -> Self {
|
||||
let type_option_builder = type_option_builder.into();
|
||||
let field_meta = FieldMeta::new("", "", type_option_builder.field_type());
|
||||
Self {
|
||||
field_meta,
|
||||
type_option_builder: Box::new(type_option_builder),
|
||||
type_option_builder,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_field_type(field_type: &FieldType) -> Self {
|
||||
let type_option_builder = type_option_builder_from_type(field_type);
|
||||
let type_option_builder = default_type_option_builder_from_type(field_type);
|
||||
Self::new(type_option_builder)
|
||||
}
|
||||
|
||||
@ -45,39 +49,62 @@ impl FieldBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(mut self) -> FieldMeta {
|
||||
pub fn build(self) -> FieldMeta {
|
||||
debug_assert_eq!(self.field_meta.field_type, self.type_option_builder.field_type());
|
||||
let type_options = self.type_option_builder.build();
|
||||
self.field_meta.type_option = type_options;
|
||||
self.field_meta
|
||||
let mut field_meta = self.field_meta;
|
||||
let type_option_json = self.type_option_builder.build_type_option_str();
|
||||
field_meta.type_option_json = type_option_json;
|
||||
field_meta
|
||||
}
|
||||
}
|
||||
|
||||
pub trait TypeOptionsBuilder {
|
||||
pub trait TypeOptionBuilder {
|
||||
fn field_type(&self) -> FieldType;
|
||||
fn build(&self) -> String;
|
||||
fn build_type_option_str(&self) -> String;
|
||||
fn build_type_option_data(&self) -> Bytes;
|
||||
}
|
||||
|
||||
pub fn type_option_builder_from_type(field_type: &FieldType) -> Box<dyn TypeOptionsBuilder> {
|
||||
pub fn default_type_option_builder_from_type(field_type: &FieldType) -> Box<dyn TypeOptionBuilder> {
|
||||
let s: String = match field_type {
|
||||
FieldType::RichText => RichTextTypeOption::default().into(),
|
||||
FieldType::Number => NumberTypeOption::default().into(),
|
||||
FieldType::DateTime => DateTypeOption::default().into(),
|
||||
FieldType::SingleSelect => SingleSelectTypeOption::default().into(),
|
||||
FieldType::MultiSelect => MultiSelectTypeOption::default().into(),
|
||||
FieldType::Checkbox => CheckboxTypeOption::default().into(),
|
||||
};
|
||||
|
||||
type_option_builder_from_json_str(&s, field_type)
|
||||
}
|
||||
|
||||
pub fn type_option_builder_from_json_str(s: &str, field_type: &FieldType) -> Box<dyn TypeOptionBuilder> {
|
||||
match field_type {
|
||||
FieldType::RichText => Box::new(RichTextTypeOptionBuilder::default()),
|
||||
FieldType::Number => Box::new(NumberTypeOptionBuilder::default()),
|
||||
FieldType::DateTime => Box::new(DateTypeOptionBuilder::default()),
|
||||
FieldType::SingleSelect => Box::new(SingleSelectTypeOptionBuilder::default()),
|
||||
FieldType::MultiSelect => Box::new(MultiSelectTypeOptionBuilder::default()),
|
||||
FieldType::Checkbox => Box::new(CheckboxTypeOptionBuilder::default()),
|
||||
FieldType::RichText => Box::new(RichTextTypeOptionBuilder::from_json_str(s)),
|
||||
FieldType::Number => Box::new(NumberTypeOptionBuilder::from_json_str(s)),
|
||||
FieldType::DateTime => Box::new(DateTypeOptionBuilder::from_json_str(s)),
|
||||
FieldType::SingleSelect => Box::new(SingleSelectTypeOptionBuilder::from_json_str(s)),
|
||||
FieldType::MultiSelect => Box::new(MultiSelectTypeOptionBuilder::from_json_str(s)),
|
||||
FieldType::Checkbox => Box::new(CheckboxTypeOptionBuilder::from_json_str(s)),
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> TypeOptionsBuilder for Box<T>
|
||||
where
|
||||
T: TypeOptionsBuilder + ?Sized,
|
||||
{
|
||||
fn field_type(&self) -> FieldType {
|
||||
(**self).field_type()
|
||||
}
|
||||
|
||||
fn build(&self) -> String {
|
||||
(**self).build()
|
||||
pub fn type_option_builder_from_bytes(bytes: Bytes, field_type: &FieldType) -> Box<dyn TypeOptionBuilder> {
|
||||
match field_type {
|
||||
FieldType::RichText => Box::new(RichTextTypeOptionBuilder::from_bytes(bytes)),
|
||||
FieldType::Number => Box::new(NumberTypeOptionBuilder::from_bytes(bytes)),
|
||||
FieldType::DateTime => Box::new(DateTypeOptionBuilder::from_bytes(bytes)),
|
||||
FieldType::SingleSelect => Box::new(SingleSelectTypeOptionBuilder::from_bytes(bytes)),
|
||||
FieldType::MultiSelect => Box::new(MultiSelectTypeOptionBuilder::from_bytes(bytes)),
|
||||
FieldType::Checkbox => Box::new(CheckboxTypeOptionBuilder::from_bytes(bytes)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn type_option_data_from_str(s: &str, field_type: &FieldType) -> Vec<u8> {
|
||||
let builder = type_option_builder_from_json_str(s, field_type);
|
||||
builder.build_type_option_data().to_vec()
|
||||
}
|
||||
|
||||
pub fn type_option_json_str_from_bytes(bytes: Vec<u8>, field_type: &FieldType) -> String {
|
||||
let builder = type_option_builder_from_bytes(Bytes::from(bytes), field_type);
|
||||
builder.build_type_option_str()
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
use crate::impl_from_and_to_type_option;
|
||||
use crate::services::field::TypeOptionsBuilder;
|
||||
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
|
||||
use crate::services::row::CellDataSerde;
|
||||
use bytes::Bytes;
|
||||
use flowy_derive::ProtoBuf;
|
||||
use flowy_error::FlowyError;
|
||||
use flowy_grid_data_model::entities::{FieldMeta, FieldType};
|
||||
@ -8,6 +9,9 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct CheckboxTypeOptionBuilder(CheckboxTypeOption);
|
||||
impl_into_box_type_option_builder!(CheckboxTypeOptionBuilder);
|
||||
impl_from_json_str_and_from_bytes!(CheckboxTypeOptionBuilder, CheckboxTypeOption);
|
||||
|
||||
impl CheckboxTypeOptionBuilder {
|
||||
pub fn set_selected(mut self, is_selected: bool) -> Self {
|
||||
self.0.is_selected = is_selected;
|
||||
@ -15,14 +19,18 @@ impl CheckboxTypeOptionBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeOptionsBuilder for CheckboxTypeOptionBuilder {
|
||||
impl TypeOptionBuilder for CheckboxTypeOptionBuilder {
|
||||
fn field_type(&self) -> FieldType {
|
||||
self.0.field_type()
|
||||
}
|
||||
|
||||
fn build(&self) -> String {
|
||||
fn build_type_option_str(&self) -> String {
|
||||
self.0.clone().into()
|
||||
}
|
||||
|
||||
fn build_type_option_data(&self) -> Bytes {
|
||||
self.0.clone().try_into().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default, ProtoBuf)]
|
||||
|
@ -1,5 +1,6 @@
|
||||
use crate::impl_from_and_to_type_option;
|
||||
use crate::services::row::CellDataSerde;
|
||||
use bytes::Bytes;
|
||||
|
||||
use chrono::format::strftime::StrftimeItems;
|
||||
use chrono::NaiveDateTime;
|
||||
@ -8,7 +9,7 @@ use flowy_error::FlowyError;
|
||||
use flowy_grid_data_model::entities::{FieldMeta, FieldType};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::services::field::TypeOptionsBuilder;
|
||||
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
|
||||
use strum_macros::EnumIter;
|
||||
|
||||
// Date
|
||||
@ -64,6 +65,9 @@ impl CellDataSerde for DateTypeOption {
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct DateTypeOptionBuilder(DateTypeOption);
|
||||
impl_into_box_type_option_builder!(DateTypeOptionBuilder);
|
||||
impl_from_json_str_and_from_bytes!(DateTypeOptionBuilder, DateTypeOption);
|
||||
|
||||
impl DateTypeOptionBuilder {
|
||||
pub fn date_format(mut self, date_format: DateFormat) -> Self {
|
||||
self.0.date_format = date_format;
|
||||
@ -75,14 +79,18 @@ impl DateTypeOptionBuilder {
|
||||
self
|
||||
}
|
||||
}
|
||||
impl TypeOptionsBuilder for DateTypeOptionBuilder {
|
||||
impl TypeOptionBuilder for DateTypeOptionBuilder {
|
||||
fn field_type(&self) -> FieldType {
|
||||
self.0.field_type()
|
||||
}
|
||||
|
||||
fn build(&self) -> String {
|
||||
fn build_type_option_str(&self) -> String {
|
||||
self.0.clone().into()
|
||||
}
|
||||
|
||||
fn build_type_option_data(&self) -> Bytes {
|
||||
self.0.clone().try_into().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Copy, EnumIter, Serialize, Deserialize, ProtoBuf_Enum)]
|
||||
|
@ -9,7 +9,8 @@ use rust_decimal::Decimal;
|
||||
use rusty_money::iso::{Currency, CNY, EUR, USD};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::services::field::TypeOptionsBuilder;
|
||||
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
|
||||
use bytes::Bytes;
|
||||
use std::str::FromStr;
|
||||
use strum::IntoEnumIterator;
|
||||
use strum_macros::EnumIter;
|
||||
@ -20,6 +21,8 @@ lazy_static! {
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct NumberTypeOptionBuilder(NumberTypeOption);
|
||||
impl_into_box_type_option_builder!(NumberTypeOptionBuilder);
|
||||
impl_from_json_str_and_from_bytes!(NumberTypeOptionBuilder, NumberTypeOption);
|
||||
|
||||
impl NumberTypeOptionBuilder {
|
||||
pub fn name(mut self, name: &str) -> Self {
|
||||
@ -43,14 +46,18 @@ impl NumberTypeOptionBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeOptionsBuilder for NumberTypeOptionBuilder {
|
||||
impl TypeOptionBuilder for NumberTypeOptionBuilder {
|
||||
fn field_type(&self) -> FieldType {
|
||||
self.0.field_type()
|
||||
}
|
||||
|
||||
fn build(&self) -> String {
|
||||
fn build_type_option_str(&self) -> String {
|
||||
self.0.clone().into()
|
||||
}
|
||||
|
||||
fn build_type_option_data(&self) -> Bytes {
|
||||
self.0.clone().try_into().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
// Number
|
||||
|
@ -1,7 +1,8 @@
|
||||
use crate::impl_from_and_to_type_option;
|
||||
use crate::services::field::TypeOptionsBuilder;
|
||||
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
|
||||
use crate::services::row::CellDataSerde;
|
||||
use crate::services::util::*;
|
||||
use bytes::Bytes;
|
||||
use flowy_derive::ProtoBuf;
|
||||
use flowy_error::{FlowyError, FlowyResult};
|
||||
use flowy_grid_data_model::entities::{FieldMeta, FieldType};
|
||||
@ -34,6 +35,8 @@ impl CellDataSerde for SingleSelectTypeOption {
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct SingleSelectTypeOptionBuilder(SingleSelectTypeOption);
|
||||
impl_into_box_type_option_builder!(SingleSelectTypeOptionBuilder);
|
||||
impl_from_json_str_and_from_bytes!(SingleSelectTypeOptionBuilder, SingleSelectTypeOption);
|
||||
|
||||
impl SingleSelectTypeOptionBuilder {
|
||||
pub fn option(mut self, opt: SelectOption) -> Self {
|
||||
@ -41,14 +44,19 @@ impl SingleSelectTypeOptionBuilder {
|
||||
self
|
||||
}
|
||||
}
|
||||
impl TypeOptionsBuilder for SingleSelectTypeOptionBuilder {
|
||||
|
||||
impl TypeOptionBuilder for SingleSelectTypeOptionBuilder {
|
||||
fn field_type(&self) -> FieldType {
|
||||
self.0.field_type()
|
||||
}
|
||||
|
||||
fn build(&self) -> String {
|
||||
fn build_type_option_str(&self) -> String {
|
||||
self.0.clone().into()
|
||||
}
|
||||
|
||||
fn build_type_option_data(&self) -> Bytes {
|
||||
self.0.clone().try_into().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
// Multiple select
|
||||
@ -61,6 +69,7 @@ pub struct MultiSelectTypeOption {
|
||||
pub disable_color: bool,
|
||||
}
|
||||
impl_from_and_to_type_option!(MultiSelectTypeOption, FieldType::MultiSelect);
|
||||
|
||||
impl CellDataSerde for MultiSelectTypeOption {
|
||||
fn deserialize_cell_data(&self, data: String) -> String {
|
||||
data
|
||||
@ -73,6 +82,8 @@ impl CellDataSerde for MultiSelectTypeOption {
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct MultiSelectTypeOptionBuilder(MultiSelectTypeOption);
|
||||
impl_into_box_type_option_builder!(MultiSelectTypeOptionBuilder);
|
||||
impl_from_json_str_and_from_bytes!(MultiSelectTypeOptionBuilder, MultiSelectTypeOption);
|
||||
impl MultiSelectTypeOptionBuilder {
|
||||
pub fn option(mut self, opt: SelectOption) -> Self {
|
||||
self.0.options.push(opt);
|
||||
@ -80,14 +91,18 @@ impl MultiSelectTypeOptionBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeOptionsBuilder for MultiSelectTypeOptionBuilder {
|
||||
impl TypeOptionBuilder for MultiSelectTypeOptionBuilder {
|
||||
fn field_type(&self) -> FieldType {
|
||||
self.0.field_type()
|
||||
}
|
||||
|
||||
fn build(&self) -> String {
|
||||
fn build_type_option_str(&self) -> String {
|
||||
self.0.clone().into()
|
||||
}
|
||||
|
||||
fn build_type_option_data(&self) -> Bytes {
|
||||
self.0.clone().try_into().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
fn single_select_option_id_from_data(data: String) -> FlowyResult<String> {
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::impl_from_and_to_type_option;
|
||||
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
|
||||
use crate::services::row::CellDataSerde;
|
||||
|
||||
use crate::services::field::TypeOptionsBuilder;
|
||||
use bytes::Bytes;
|
||||
use flowy_derive::ProtoBuf;
|
||||
use flowy_error::FlowyError;
|
||||
use flowy_grid_data_model::entities::{FieldMeta, FieldType};
|
||||
@ -9,15 +9,21 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct RichTextTypeOptionBuilder(RichTextTypeOption);
|
||||
impl_into_box_type_option_builder!(RichTextTypeOptionBuilder);
|
||||
impl_from_json_str_and_from_bytes!(RichTextTypeOptionBuilder, RichTextTypeOption);
|
||||
|
||||
impl TypeOptionsBuilder for RichTextTypeOptionBuilder {
|
||||
impl TypeOptionBuilder for RichTextTypeOptionBuilder {
|
||||
fn field_type(&self) -> FieldType {
|
||||
self.0.field_type()
|
||||
}
|
||||
|
||||
fn build(&self) -> String {
|
||||
fn build_type_option_str(&self) -> String {
|
||||
self.0.clone().into()
|
||||
}
|
||||
|
||||
fn build_type_option_data(&self) -> Bytes {
|
||||
self.0.clone().try_into().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)]
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::dart_notification::{send_dart_notification, GridNotification};
|
||||
use crate::manager::GridUser;
|
||||
use crate::services::block_meta_editor::GridBlockMetaEditorManager;
|
||||
use crate::services::field::{type_option_builder_from_type, FieldBuilder};
|
||||
use crate::services::field::{default_type_option_builder_from_type, type_option_json_str_from_bytes, FieldBuilder};
|
||||
use crate::services::row::*;
|
||||
use bytes::Bytes;
|
||||
use flowy_error::{FlowyError, FlowyResult};
|
||||
@ -49,20 +49,35 @@ impl ClientGridEditor {
|
||||
}))
|
||||
}
|
||||
|
||||
pub async fn create_field(&self, mut params: CreateFieldParams) -> FlowyResult<()> {
|
||||
if params.type_option_data.is_empty() {
|
||||
params.type_option_data = type_option_builder_from_type(¶ms.field.field_type)
|
||||
.build()
|
||||
.as_bytes()
|
||||
.to_vec();
|
||||
}
|
||||
pub async fn create_field(&self, params: CreateFieldParams) -> FlowyResult<()> {
|
||||
let CreateFieldParams {
|
||||
field,
|
||||
type_option_data,
|
||||
start_field_id,
|
||||
..
|
||||
} = params;
|
||||
|
||||
let _ = self.modify(|grid| Ok(grid.create_field(params)?)).await?;
|
||||
let type_option_json = type_option_json_str_from_bytes(type_option_data, &field.field_type);
|
||||
|
||||
let field_meta = FieldMeta {
|
||||
id: field.id,
|
||||
name: field.name,
|
||||
desc: field.desc,
|
||||
field_type: field.field_type,
|
||||
frozen: field.frozen,
|
||||
visibility: field.visibility,
|
||||
width: field.width,
|
||||
type_option_json,
|
||||
};
|
||||
|
||||
let _ = self
|
||||
.modify(|grid| Ok(grid.create_field(field_meta, start_field_id)?))
|
||||
.await?;
|
||||
let _ = self.notify_did_update_fields().await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn make_field_meta_from_ty(&self, field_type: &FieldType) -> FlowyResult<FieldMeta> {
|
||||
pub async fn default_field_meta(&self, field_type: &FieldType) -> FlowyResult<FieldMeta> {
|
||||
let name = format!("Property {}", self.pad.read().await.fields().len());
|
||||
let field_meta = FieldBuilder::from_field_type(&field_type).name(&name).build();
|
||||
Ok(field_meta)
|
||||
|
@ -100,7 +100,7 @@ async fn grid_update_field() {
|
||||
|
||||
cloned_field.frozen = true;
|
||||
cloned_field.width = 1000;
|
||||
cloned_field.type_option = single_select_type_options.into();
|
||||
cloned_field.type_option_json = single_select_type_options.into();
|
||||
|
||||
let scripts = vec![
|
||||
CreateField {
|
||||
|
@ -268,7 +268,7 @@ pub fn create_text_field(grid_id: &str) -> (CreateFieldParams, FieldMeta) {
|
||||
let params = CreateFieldParams {
|
||||
grid_id: grid_id.to_owned(),
|
||||
field,
|
||||
type_option_data: field_meta.type_option.as_bytes().to_vec(),
|
||||
type_option_data: field_meta.type_option_json.as_bytes().to_vec(),
|
||||
start_field_id: None,
|
||||
};
|
||||
(params, cloned_field_meta)
|
||||
@ -295,7 +295,7 @@ pub fn create_single_select_field(grid_id: &str) -> (CreateFieldParams, FieldMet
|
||||
let params = CreateFieldParams {
|
||||
grid_id: grid_id.to_owned(),
|
||||
field,
|
||||
type_option_data: field_meta.type_option.as_bytes().to_vec(),
|
||||
type_option_data: field_meta.type_option_json.as_bytes().to_vec(),
|
||||
start_field_id: None,
|
||||
};
|
||||
(params, cloned_field_meta)
|
||||
|
@ -98,7 +98,7 @@ pub struct FieldMeta {
|
||||
pub width: i32,
|
||||
|
||||
#[pb(index = 8)]
|
||||
pub type_option: String,
|
||||
pub type_option_json: String,
|
||||
}
|
||||
|
||||
impl FieldMeta {
|
||||
@ -111,7 +111,7 @@ impl FieldMeta {
|
||||
frozen: false,
|
||||
visibility: true,
|
||||
width: DEFAULT_FIELD_WIDTH,
|
||||
type_option: Default::default(),
|
||||
type_option_json: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -727,7 +727,7 @@ pub struct FieldMeta {
|
||||
pub frozen: bool,
|
||||
pub visibility: bool,
|
||||
pub width: i32,
|
||||
pub type_option: ::std::string::String,
|
||||
pub type_option_json: ::std::string::String,
|
||||
// special fields
|
||||
pub unknown_fields: ::protobuf::UnknownFields,
|
||||
pub cached_size: ::protobuf::CachedSize,
|
||||
@ -882,30 +882,30 @@ impl FieldMeta {
|
||||
self.width = v;
|
||||
}
|
||||
|
||||
// string type_option = 8;
|
||||
// string type_option_json = 8;
|
||||
|
||||
|
||||
pub fn get_type_option(&self) -> &str {
|
||||
&self.type_option
|
||||
pub fn get_type_option_json(&self) -> &str {
|
||||
&self.type_option_json
|
||||
}
|
||||
pub fn clear_type_option(&mut self) {
|
||||
self.type_option.clear();
|
||||
pub fn clear_type_option_json(&mut self) {
|
||||
self.type_option_json.clear();
|
||||
}
|
||||
|
||||
// Param is passed by value, moved
|
||||
pub fn set_type_option(&mut self, v: ::std::string::String) {
|
||||
self.type_option = v;
|
||||
pub fn set_type_option_json(&mut self, v: ::std::string::String) {
|
||||
self.type_option_json = v;
|
||||
}
|
||||
|
||||
// Mutable pointer to the field.
|
||||
// If field is not initialized, it is initialized with default value first.
|
||||
pub fn mut_type_option(&mut self) -> &mut ::std::string::String {
|
||||
&mut self.type_option
|
||||
pub fn mut_type_option_json(&mut self) -> &mut ::std::string::String {
|
||||
&mut self.type_option_json
|
||||
}
|
||||
|
||||
// Take field
|
||||
pub fn take_type_option(&mut self) -> ::std::string::String {
|
||||
::std::mem::replace(&mut self.type_option, ::std::string::String::new())
|
||||
pub fn take_type_option_json(&mut self) -> ::std::string::String {
|
||||
::std::mem::replace(&mut self.type_option_json, ::std::string::String::new())
|
||||
}
|
||||
}
|
||||
|
||||
@ -952,7 +952,7 @@ impl ::protobuf::Message for FieldMeta {
|
||||
self.width = tmp;
|
||||
},
|
||||
8 => {
|
||||
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.type_option)?;
|
||||
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.type_option_json)?;
|
||||
},
|
||||
_ => {
|
||||
::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
|
||||
@ -987,8 +987,8 @@ impl ::protobuf::Message for FieldMeta {
|
||||
if self.width != 0 {
|
||||
my_size += ::protobuf::rt::value_size(7, self.width, ::protobuf::wire_format::WireTypeVarint);
|
||||
}
|
||||
if !self.type_option.is_empty() {
|
||||
my_size += ::protobuf::rt::string_size(8, &self.type_option);
|
||||
if !self.type_option_json.is_empty() {
|
||||
my_size += ::protobuf::rt::string_size(8, &self.type_option_json);
|
||||
}
|
||||
my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
|
||||
self.cached_size.set(my_size);
|
||||
@ -1017,8 +1017,8 @@ impl ::protobuf::Message for FieldMeta {
|
||||
if self.width != 0 {
|
||||
os.write_int32(7, self.width)?;
|
||||
}
|
||||
if !self.type_option.is_empty() {
|
||||
os.write_string(8, &self.type_option)?;
|
||||
if !self.type_option_json.is_empty() {
|
||||
os.write_string(8, &self.type_option_json)?;
|
||||
}
|
||||
os.write_unknown_fields(self.get_unknown_fields())?;
|
||||
::std::result::Result::Ok(())
|
||||
@ -1094,9 +1094,9 @@ impl ::protobuf::Message for FieldMeta {
|
||||
|m: &mut FieldMeta| { &mut m.width },
|
||||
));
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
|
||||
"type_option",
|
||||
|m: &FieldMeta| { &m.type_option },
|
||||
|m: &mut FieldMeta| { &mut m.type_option },
|
||||
"type_option_json",
|
||||
|m: &FieldMeta| { &m.type_option_json },
|
||||
|m: &mut FieldMeta| { &mut m.type_option_json },
|
||||
));
|
||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<FieldMeta>(
|
||||
"FieldMeta",
|
||||
@ -1121,7 +1121,7 @@ impl ::protobuf::Clear for FieldMeta {
|
||||
self.frozen = false;
|
||||
self.visibility = false;
|
||||
self.width = 0;
|
||||
self.type_option.clear();
|
||||
self.type_option_json.clear();
|
||||
self.unknown_fields.clear();
|
||||
}
|
||||
}
|
||||
@ -3507,50 +3507,50 @@ static file_descriptor_proto_data: &'static [u8] = b"\
|
||||
ockId\x12&\n\x0fstart_row_index\x18\x02\x20\x01(\x05R\rstartRowIndex\x12\
|
||||
\x1b\n\trow_count\x18\x03\x20\x01(\x05R\x08rowCount\"V\n\x12GridBlockMet\
|
||||
aSerde\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12%\n\trow_\
|
||||
metas\x18\x02\x20\x03(\x0b2\x08.RowMetaR\x08rowMetas\"\xdd\x01\n\tFieldM\
|
||||
metas\x18\x02\x20\x03(\x0b2\x08.RowMetaR\x08rowMetas\"\xe6\x01\n\tFieldM\
|
||||
eta\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\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.FieldTypeR\tfieldType\x12\x16\n\
|
||||
\x06frozen\x18\x05\x20\x01(\x08R\x06frozen\x12\x1e\n\nvisibility\x18\x06\
|
||||
\x20\x01(\x08R\nvisibility\x12\x14\n\x05width\x18\x07\x20\x01(\x05R\x05w\
|
||||
idth\x12\x1f\n\x0btype_option\x18\x08\x20\x01(\tR\ntypeOption\"\x96\x03\
|
||||
\n\x0eFieldChangeset\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldI\
|
||||
d\x12\x17\n\x07grid_id\x18\x02\x20\x01(\tR\x06gridId\x12\x14\n\x04name\
|
||||
\x18\x03\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x04\x20\x01(\tH\
|
||||
\x01R\x04desc\x12+\n\nfield_type\x18\x05\x20\x01(\x0e2\n.FieldTypeH\x02R\
|
||||
\tfieldType\x12\x18\n\x06frozen\x18\x06\x20\x01(\x08H\x03R\x06frozen\x12\
|
||||
\x20\n\nvisibility\x18\x07\x20\x01(\x08H\x04R\nvisibility\x12\x16\n\x05w\
|
||||
idth\x18\x08\x20\x01(\x05H\x05R\x05width\x12#\n\x0ctype_options\x18\t\
|
||||
\x20\x01(\tH\x06R\x0btypeOptionsB\r\n\x0bone_of_nameB\r\n\x0bone_of_desc\
|
||||
B\x13\n\x11one_of_field_typeB\x0f\n\rone_of_frozenB\x13\n\x11one_of_visi\
|
||||
bilityB\x0e\n\x0cone_of_widthB\x15\n\x13one_of_type_options\"8\n\x07AnyD\
|
||||
ata\x12\x17\n\x07type_id\x18\x01\x20\x01(\tR\x06typeId\x12\x14\n\x05valu\
|
||||
e\x18\x02\x20\x01(\x0cR\x05value\"\xff\x01\n\x07RowMeta\x12\x0e\n\x02id\
|
||||
\x18\x01\x20\x01(\tR\x02id\x12\x19\n\x08block_id\x18\x02\x20\x01(\tR\x07\
|
||||
blockId\x12D\n\x10cell_by_field_id\x18\x03\x20\x03(\x0b2\x1b.RowMeta.Cel\
|
||||
lByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x04\x20\x01(\x05\
|
||||
R\x06height\x12\x1e\n\nvisibility\x18\x05\x20\x01(\x08R\nvisibility\x1aK\
|
||||
\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\
|
||||
\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\x028\x01\"\
|
||||
\xa7\x02\n\x10RowMetaChangeset\x12\x15\n\x06row_id\x18\x01\x20\x01(\tR\
|
||||
\x05rowId\x12\x18\n\x06height\x18\x02\x20\x01(\x05H\0R\x06height\x12\x20\
|
||||
\n\nvisibility\x18\x03\x20\x01(\x08H\x01R\nvisibility\x12M\n\x10cell_by_\
|
||||
field_id\x18\x04\x20\x03(\x0b2$.RowMetaChangeset.CellByFieldIdEntryR\rce\
|
||||
llByFieldId\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\
|
||||
\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05\
|
||||
value:\x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one_of_visibility\"9\n\
|
||||
\x08CellMeta\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fieldId\x12\
|
||||
\x12\n\x04data\x18\x02\x20\x01(\tR\x04data\"\x83\x01\n\x11CellMetaChange\
|
||||
set\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x15\n\x06row_\
|
||||
id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\x20\x01(\t\
|
||||
R\x07fieldId\x12\x14\n\x04data\x18\x04\x20\x01(\tH\0R\x04dataB\r\n\x0bon\
|
||||
e_of_data\"\xad\x01\n\x10BuildGridContext\x12+\n\x0bfield_metas\x18\x01\
|
||||
\x20\x03(\x0b2\n.FieldMetaR\nfieldMetas\x12/\n\x0bblock_metas\x18\x02\
|
||||
\x20\x01(\x0b2\x0e.GridBlockMetaR\nblockMetas\x12;\n\x0fblock_meta_data\
|
||||
\x18\x03\x20\x01(\x0b2\x13.GridBlockMetaSerdeR\rblockMetaData*d\n\tField\
|
||||
Type\x12\x0c\n\x08RichText\x10\0\x12\n\n\x06Number\x10\x01\x12\x0c\n\x08\
|
||||
DateTime\x10\x02\x12\x10\n\x0cSingleSelect\x10\x03\x12\x0f\n\x0bMultiSel\
|
||||
ect\x10\x04\x12\x0c\n\x08Checkbox\x10\x05b\x06proto3\
|
||||
idth\x12(\n\x10type_option_json\x18\x08\x20\x01(\tR\x0etypeOptionJson\"\
|
||||
\x96\x03\n\x0eFieldChangeset\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\
|
||||
\x07fieldId\x12\x17\n\x07grid_id\x18\x02\x20\x01(\tR\x06gridId\x12\x14\n\
|
||||
\x04name\x18\x03\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x04\x20\
|
||||
\x01(\tH\x01R\x04desc\x12+\n\nfield_type\x18\x05\x20\x01(\x0e2\n.FieldTy\
|
||||
peH\x02R\tfieldType\x12\x18\n\x06frozen\x18\x06\x20\x01(\x08H\x03R\x06fr\
|
||||
ozen\x12\x20\n\nvisibility\x18\x07\x20\x01(\x08H\x04R\nvisibility\x12\
|
||||
\x16\n\x05width\x18\x08\x20\x01(\x05H\x05R\x05width\x12#\n\x0ctype_optio\
|
||||
ns\x18\t\x20\x01(\tH\x06R\x0btypeOptionsB\r\n\x0bone_of_nameB\r\n\x0bone\
|
||||
_of_descB\x13\n\x11one_of_field_typeB\x0f\n\rone_of_frozenB\x13\n\x11one\
|
||||
_of_visibilityB\x0e\n\x0cone_of_widthB\x15\n\x13one_of_type_options\"8\n\
|
||||
\x07AnyData\x12\x17\n\x07type_id\x18\x01\x20\x01(\tR\x06typeId\x12\x14\n\
|
||||
\x05value\x18\x02\x20\x01(\x0cR\x05value\"\xff\x01\n\x07RowMeta\x12\x0e\
|
||||
\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x19\n\x08block_id\x18\x02\x20\x01\
|
||||
(\tR\x07blockId\x12D\n\x10cell_by_field_id\x18\x03\x20\x03(\x0b2\x1b.Row\
|
||||
Meta.CellByFieldIdEntryR\rcellByFieldId\x12\x16\n\x06height\x18\x04\x20\
|
||||
\x01(\x05R\x06height\x12\x1e\n\nvisibility\x18\x05\x20\x01(\x08R\nvisibi\
|
||||
lity\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\
|
||||
\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.CellMetaR\x05value:\
|
||||
\x028\x01\"\xa7\x02\n\x10RowMetaChangeset\x12\x15\n\x06row_id\x18\x01\
|
||||
\x20\x01(\tR\x05rowId\x12\x18\n\x06height\x18\x02\x20\x01(\x05H\0R\x06he\
|
||||
ight\x12\x20\n\nvisibility\x18\x03\x20\x01(\x08H\x01R\nvisibility\x12M\n\
|
||||
\x10cell_by_field_id\x18\x04\x20\x03(\x0b2$.RowMetaChangeset.CellByField\
|
||||
IdEntryR\rcellByFieldId\x1aK\n\x12CellByFieldIdEntry\x12\x10\n\x03key\
|
||||
\x18\x01\x20\x01(\tR\x03key\x12\x1f\n\x05value\x18\x02\x20\x01(\x0b2\t.C\
|
||||
ellMetaR\x05value:\x028\x01B\x0f\n\rone_of_heightB\x13\n\x11one_of_visib\
|
||||
ility\"9\n\x08CellMeta\x12\x19\n\x08field_id\x18\x01\x20\x01(\tR\x07fiel\
|
||||
dId\x12\x12\n\x04data\x18\x02\x20\x01(\tR\x04data\"\x83\x01\n\x11CellMet\
|
||||
aChangeset\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x15\n\
|
||||
\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_id\x18\x03\
|
||||
\x20\x01(\tR\x07fieldId\x12\x14\n\x04data\x18\x04\x20\x01(\tH\0R\x04data\
|
||||
B\r\n\x0bone_of_data\"\xad\x01\n\x10BuildGridContext\x12+\n\x0bfield_met\
|
||||
as\x18\x01\x20\x03(\x0b2\n.FieldMetaR\nfieldMetas\x12/\n\x0bblock_metas\
|
||||
\x18\x02\x20\x01(\x0b2\x0e.GridBlockMetaR\nblockMetas\x12;\n\x0fblock_me\
|
||||
ta_data\x18\x03\x20\x01(\x0b2\x13.GridBlockMetaSerdeR\rblockMetaData*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;
|
||||
|
@ -22,7 +22,7 @@ message FieldMeta {
|
||||
bool frozen = 5;
|
||||
bool visibility = 6;
|
||||
int32 width = 7;
|
||||
string type_option = 8;
|
||||
string type_option_json = 8;
|
||||
}
|
||||
message FieldChangeset {
|
||||
string field_id = 1;
|
||||
|
@ -36,49 +36,31 @@ impl GridMetaPad {
|
||||
Self::from_delta(grid_delta)
|
||||
}
|
||||
|
||||
pub fn create_field(&mut self, params: CreateFieldParams) -> CollaborateResult<Option<GridChangeset>> {
|
||||
pub fn create_field(
|
||||
&mut self,
|
||||
new_field_meta: FieldMeta,
|
||||
start_field_id: Option<String>,
|
||||
) -> CollaborateResult<Option<GridChangeset>> {
|
||||
self.modify_grid(|grid| {
|
||||
let CreateFieldParams {
|
||||
field,
|
||||
type_option_data,
|
||||
start_field_id,
|
||||
..
|
||||
} = params;
|
||||
|
||||
// Check if the field exists or not
|
||||
if grid
|
||||
.fields
|
||||
.iter()
|
||||
.find(|field_meta| field_meta.id == field.id)
|
||||
.find(|field_meta| field_meta.id == new_field_meta.id)
|
||||
.is_some()
|
||||
{
|
||||
tracing::warn!("Duplicate grid field");
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
// Parse type option
|
||||
let type_option =
|
||||
String::from_utf8(type_option_data).map_err(|e| CollaborateError::internal().context(e))?;
|
||||
|
||||
let field_meta = FieldMeta {
|
||||
id: field.id,
|
||||
name: field.name,
|
||||
desc: field.desc,
|
||||
field_type: field.field_type,
|
||||
frozen: field.frozen,
|
||||
visibility: field.visibility,
|
||||
width: field.width,
|
||||
type_option,
|
||||
};
|
||||
|
||||
let insert_index = match start_field_id {
|
||||
None => None,
|
||||
Some(start_field_id) => grid.fields.iter().position(|field| field.id == start_field_id),
|
||||
};
|
||||
|
||||
match insert_index {
|
||||
None => grid.fields.push(field_meta),
|
||||
Some(index) => grid.fields.insert(index, field_meta),
|
||||
None => grid.fields.push(new_field_meta),
|
||||
Some(index) => grid.fields.insert(index, new_field_meta),
|
||||
}
|
||||
Ok(Some(()))
|
||||
})
|
||||
@ -167,7 +149,7 @@ impl GridMetaPad {
|
||||
}
|
||||
|
||||
if let Some(type_options) = changeset.type_options {
|
||||
field.type_option = type_options;
|
||||
field.type_option_json = type_options;
|
||||
is_changed = Some(())
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user