diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/date_cal_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/date_cal_bloc.dart index 2214ddb875..f3ce3d5faa 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/date_cal_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/date_cal_bloc.dart @@ -1,3 +1,4 @@ +import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Cell, Field; import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -6,6 +7,7 @@ import 'package:table_calendar/table_calendar.dart'; import 'dart:async'; import 'cell_service.dart'; import 'package:dartz/dartz.dart'; +import 'package:fixnum/fixnum.dart' as $fixnum; part 'date_cal_bloc.freezed.dart'; class DateCalBloc extends Bloc { @@ -15,9 +17,10 @@ class DateCalBloc extends Bloc { DateCalBloc({required this.cellContext}) : super(DateCalState.initial(cellContext)) { on( (event, emit) async { - event.map( - initial: (_Initial value) { + await event.map( + initial: (_Initial value) async { _startListening(); + await _loadDateTypeOption(emit); }, selectDay: (_SelectDay value) { if (!isSameDay(state.selectedDay, value.day)) { @@ -60,6 +63,30 @@ class DateCalBloc extends Bloc { ); } + Future _loadDateTypeOption(Emitter emit) async { + final result = await cellContext.getTypeOptionData(); + result.fold( + (data) { + final typeOptionData = DateTypeOption.fromBuffer(data); + + DateTime? selectedDay; + final cellData = cellContext.getCellData()?.data; + + if (cellData != null) { + final timestamp = $fixnum.Int64.parseInt(cellData).toInt(); + selectedDay = DateTime.fromMillisecondsSinceEpoch(timestamp * 1000); + } + + emit(state.copyWith( + typeOptinoData: some(typeOptionData), + includeTime: typeOptionData.includeTime, + selectedDay: selectedDay, + )); + }, + (err) => Log.error(err), + ); + } + void _updateCellData(DateTime day) { final data = day.millisecondsSinceEpoch ~/ 1000; cellContext.saveCellData(data.toString()); @@ -83,6 +110,7 @@ class DateCalState with _$DateCalState { required Option typeOptinoData, required CalendarFormat format, required DateTime focusedDay, + required bool includeTime, DateTime? selectedDay, }) = _DateCalState; @@ -91,5 +119,6 @@ class DateCalState with _$DateCalState { typeOptinoData: none(), format: CalendarFormat.month, focusedDay: DateTime.now(), + includeTime: false, ); } diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart index 7ee2863ef0..ef198d5c3a 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart @@ -119,6 +119,7 @@ class FieldService { required FieldType fieldType, }) { final payload = EditFieldPayload.create() + ..gridId = gridId ..fieldId = fieldId ..fieldType = fieldType; return GridEventGetFieldTypeOption(payload).send().then((result) { diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart index f88989a841..968044a972 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pb.dart @@ -1350,6 +1350,7 @@ class Cell extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Cell', createEmptyInstance: create) ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fieldId') ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'content') + ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data') ..hasRequiredFields = false ; @@ -1357,6 +1358,7 @@ class Cell extends $pb.GeneratedMessage { factory Cell({ $core.String? fieldId, $core.String? content, + $core.String? data, }) { final _result = create(); if (fieldId != null) { @@ -1365,6 +1367,9 @@ class Cell extends $pb.GeneratedMessage { if (content != null) { _result.content = content; } + if (data != null) { + _result.data = data; + } return _result; } factory Cell.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); @@ -1405,6 +1410,15 @@ class Cell extends $pb.GeneratedMessage { $core.bool hasContent() => $_has(1); @$pb.TagNumber(2) void clearContent() => clearField(2); + + @$pb.TagNumber(3) + $core.String get data => $_getSZ(2); + @$pb.TagNumber(3) + set data($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasData() => $_has(2); + @$pb.TagNumber(3) + void clearData() => clearField(3); } class RepeatedCell extends $pb.GeneratedMessage { diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart index d59dd68b25..29dcde046c 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid-data-model/grid.pbjson.dart @@ -291,11 +291,12 @@ const Cell$json = const { '2': const [ const {'1': 'field_id', '3': 1, '4': 1, '5': 9, '10': 'fieldId'}, const {'1': 'content', '3': 2, '4': 1, '5': 9, '10': 'content'}, + const {'1': 'data', '3': 3, '4': 1, '5': 9, '10': 'data'}, ], }; /// Descriptor for `Cell`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List cellDescriptor = $convert.base64Decode('CgRDZWxsEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElkEhgKB2NvbnRlbnQYAiABKAlSB2NvbnRlbnQ='); +final $typed_data.Uint8List cellDescriptor = $convert.base64Decode('CgRDZWxsEhkKCGZpZWxkX2lkGAEgASgJUgdmaWVsZElkEhgKB2NvbnRlbnQYAiABKAlSB2NvbnRlbnQSEgoEZGF0YRgDIAEoCVIEZGF0YQ=='); @$core.Deprecated('Use repeatedCellDescriptor instead') const RepeatedCell$json = const { '1': 'RepeatedCell', diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 43bed6b053..fd7b838b82 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -245,7 +245,7 @@ pub(crate) async fn get_cell_handler( let params: CellIdentifier = data.into_inner().try_into()?; let editor = manager.get_grid_editor(¶ms.grid_id)?; match editor.get_cell(¶ms).await { - None => data_result(Cell::new(¶ms.field_id, "".to_owned())), + None => data_result(Cell::empty(¶ms.field_id)), Some(cell) => data_result(cell), } } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs index 994e82829a..ff1f2d3d78 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs @@ -1,6 +1,6 @@ use crate::impl_type_option; use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; -use crate::services::row::{CellDataChangeset, CellDataOperation, TypeOptionCellData}; +use crate::services::row::{CellDataChangeset, CellDataOperation, DecodedCellData, TypeOptionCellData}; use bytes::Bytes; use flowy_derive::ProtoBuf; use flowy_error::FlowyError; @@ -44,18 +44,18 @@ const YES: &str = "Yes"; const NO: &str = "No"; impl CellDataOperation for CheckboxTypeOption { - fn decode_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { + fn decode_cell_data(&self, data: String, field_meta: &FieldMeta) -> DecodedCellData { if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) { if !type_option_cell_data.is_checkbox() { - return String::new(); + return DecodedCellData::default(); } let cell_data = type_option_cell_data.data; if cell_data == YES || cell_data == NO { - return cell_data; + return DecodedCellData::from_content(cell_data); } } - String::new() + DecodedCellData::default() } fn apply_changeset>( diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs index 81e77f2645..42912b932f 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs @@ -1,8 +1,8 @@ use crate::impl_type_option; -use crate::services::row::{CellDataChangeset, CellDataOperation, TypeOptionCellData}; +use crate::services::row::{CellDataChangeset, CellDataOperation, DecodedCellData, TypeOptionCellData}; use bytes::Bytes; use chrono::format::strftime::StrftimeItems; -use chrono::NaiveDateTime; +use chrono::{NaiveDateTime, ParseResult}; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{ @@ -53,24 +53,25 @@ impl DateTypeOption { } impl CellDataOperation for DateTypeOption { - fn decode_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { + fn decode_cell_data(&self, data: String, field_meta: &FieldMeta) -> DecodedCellData { if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) { if !type_option_cell_data.is_date() { - return String::new(); + return DecodedCellData::default(); } let cell_data = type_option_cell_data.data; if let Ok(timestamp) = cell_data.parse::() { let native = NaiveDateTime::from_timestamp(timestamp, 0); - return self.today_from_native(native); + return DecodedCellData::new(format!("{}", timestamp), self.today_from_native(native)); } - if NaiveDateTime::parse_from_str(&cell_data, &self.fmt_str()).is_ok() { - return cell_data; - } + return match NaiveDateTime::parse_from_str(&cell_data, &self.fmt_str()) { + Ok(date_time) => DecodedCellData::new(format!("{}", date_time.timestamp()), cell_data), + Err(_) => DecodedCellData::default(), + }; } - String::new() + DecodedCellData::default() } fn apply_changeset>( diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs index 2d03a0ab33..36c05410da 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs @@ -1,6 +1,6 @@ use crate::impl_type_option; use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; -use crate::services::row::{CellDataChangeset, CellDataOperation, TypeOptionCellData}; +use crate::services::row::{CellDataChangeset, CellDataOperation, DecodedCellData, TypeOptionCellData}; use bytes::Bytes; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::FlowyError; @@ -77,30 +77,36 @@ pub struct NumberTypeOption { impl_type_option!(NumberTypeOption, FieldType::Number); impl CellDataOperation for NumberTypeOption { - fn decode_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { + fn decode_cell_data(&self, data: String, field_meta: &FieldMeta) -> DecodedCellData { if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) { if type_option_cell_data.is_date() { - return String::new(); + return DecodedCellData::default(); } let cell_data = type_option_cell_data.data; - match self.format { + return match self.format { NumberFormat::Number => { if let Ok(v) = cell_data.parse::() { - return v.to_string(); + return DecodedCellData::from_content(v.to_string()); } if let Ok(v) = cell_data.parse::() { - return v.to_string(); + return DecodedCellData::from_content(v.to_string()); } - return String::new(); + DecodedCellData::default() } - NumberFormat::Percent => cell_data.parse::().map_or(String::new(), |v| v.to_string()), - _ => self.money_from_str(&cell_data), - } + NumberFormat::Percent => { + let content = cell_data.parse::().map_or(String::new(), |v| v.to_string()); + DecodedCellData::from_content(content) + } + _ => { + let content = self.money_from_str(&cell_data); + DecodedCellData::from_content(content) + } + }; } else { - String::new() + DecodedCellData::default() } } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs index ecaf2344b8..7b049a7385 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs @@ -1,7 +1,7 @@ use crate::impl_type_option; use crate::services::entities::{CellIdentifier, CellIdentifierPayload}; use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; -use crate::services::row::{CellDataChangeset, CellDataOperation, TypeOptionCellData}; +use crate::services::row::{CellDataChangeset, CellDataOperation, DecodedCellData, TypeOptionCellData}; use bytes::Bytes; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::{ErrorCode, FlowyError, FlowyResult}; @@ -95,22 +95,21 @@ impl SelectOptionOperation for SingleSelectTypeOption { } impl CellDataOperation for SingleSelectTypeOption { - fn decode_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { + fn decode_cell_data(&self, data: String, _field_meta: &FieldMeta) -> DecodedCellData { if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) { if !type_option_cell_data.is_single_select() { - return String::new(); + return DecodedCellData::default(); } - match select_option_ids(type_option_cell_data.data).first() { - None => String::new(), - Some(option_id) => match self.options.iter().find(|option| &option.id == option_id) { - None => String::new(), - Some(option) => option.name.clone(), - }, + if let Some(option_id) = select_option_ids(type_option_cell_data.data).first() { + return match self.options.iter().find(|option| &option.id == option_id) { + None => DecodedCellData::default(), + Some(option) => DecodedCellData::from_content(option.name.clone()), + }; } - } else { - String::new() } + + DecodedCellData::default() } fn apply_changeset>( @@ -194,20 +193,22 @@ impl SelectOptionOperation for MultiSelectTypeOption { } impl CellDataOperation for MultiSelectTypeOption { - fn decode_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String { + fn decode_cell_data(&self, data: String, _field_meta: &FieldMeta) -> DecodedCellData { if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) { if !type_option_cell_data.is_multi_select() { - return String::new(); + return DecodedCellData::default(); } let option_ids = select_option_ids(type_option_cell_data.data); - self.options + let content = self + .options .iter() .filter(|option| option_ids.contains(&option.id)) .map(|option| option.name.clone()) .collect::>() - .join(SELECTION_IDS_SEPARATOR) + .join(SELECTION_IDS_SEPARATOR); + DecodedCellData::from_content(content) } else { - String::new() + DecodedCellData::default() } } diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs index 08e61a57e9..d605a719bf 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs @@ -1,6 +1,8 @@ use crate::impl_type_option; use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; -use crate::services::row::{decode_cell_data, CellDataChangeset, CellDataOperation, TypeOptionCellData}; +use crate::services::row::{ + decode_cell_data, CellDataChangeset, CellDataOperation, DecodedCellData, TypeOptionCellData, +}; use bytes::Bytes; use flowy_derive::ProtoBuf; use flowy_error::FlowyError; @@ -33,19 +35,20 @@ pub struct RichTextTypeOption { impl_type_option!(RichTextTypeOption, FieldType::RichText); impl CellDataOperation for RichTextTypeOption { - fn decode_cell_data(&self, data: String, field_meta: &FieldMeta) -> String { + fn decode_cell_data(&self, data: String, field_meta: &FieldMeta) -> DecodedCellData { if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) { if type_option_cell_data.is_date() || type_option_cell_data.is_single_select() || type_option_cell_data.is_multi_select() || type_option_cell_data.is_number() { - decode_cell_data(data, field_meta, &type_option_cell_data.field_type).unwrap_or_else(|| "".to_owned()) + decode_cell_data(data, field_meta, &type_option_cell_data.field_type) + .unwrap_or_else(|| DecodedCellData::default()) } else { - type_option_cell_data.data + DecodedCellData::from_content(type_option_cell_data.data) } } else { - String::new() + DecodedCellData::default() } } diff --git a/frontend/rust-lib/flowy-grid/src/services/row/cell_data_operation.rs b/frontend/rust-lib/flowy-grid/src/services/row/cell_data_operation.rs index 9d92de574e..99ff127b32 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/cell_data_operation.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/cell_data_operation.rs @@ -1,12 +1,14 @@ use crate::services::field::*; +use std::borrow::Cow; use std::fmt::Formatter; +use std::sync::Arc; use flowy_error::FlowyError; use flowy_grid_data_model::entities::{CellMeta, FieldMeta, FieldType}; use serde::{Deserialize, Serialize}; pub trait CellDataOperation { - fn decode_cell_data(&self, data: String, field_meta: &FieldMeta) -> String; + fn decode_cell_data(&self, data: String, field_meta: &FieldMeta) -> DecodedCellData; fn apply_changeset>( &self, changeset: T, @@ -106,22 +108,31 @@ pub fn apply_cell_data_changeset>( FieldType::Checkbox => CheckboxTypeOption::from(field_meta).apply_changeset(changeset, cell_meta), } } -// -// #[tracing::instrument(level = "trace", skip(field_meta, data), fields(content), err)] -// pub fn decode_cell_data(data: String, field_meta: &FieldMeta, field_type: &FieldType) -> Result { -// let s = match field_meta.field_type { -// FieldType::RichText => RichTextTypeOption::from(field_meta).decode_cell_data(data, field_meta), -// FieldType::Number => NumberTypeOption::from(field_meta).decode_cell_data(data, field_meta), -// FieldType::DateTime => DateTypeOption::from(field_meta).decode_cell_data(data, field_meta), -// FieldType::SingleSelect => SingleSelectTypeOption::from(field_meta).decode_cell_data(data, field_meta), -// FieldType::MultiSelect => MultiSelectTypeOption::from(field_meta).decode_cell_data(data, field_meta), -// FieldType::Checkbox => CheckboxTypeOption::from(field_meta).decode_cell_data(data, field_meta), -// }; -// tracing::Span::current().record("content", &format!("{:?}: {}", field_meta.field_type, s).as_str()); -// Ok(s) -// } -pub fn decode_cell_data(data: String, field_meta: &FieldMeta, field_type: &FieldType) -> Option { +#[derive(Default)] +pub struct DecodedCellData { + raw: String, + content: String, +} + +impl DecodedCellData { + pub fn from_content(content: String) -> Self { + Self { + raw: content.clone(), + content, + } + } + + pub fn new(raw: String, content: String) -> Self { + Self { raw, content } + } + + pub fn split(self) -> (String, String) { + (self.raw, self.content) + } +} + +pub fn decode_cell_data(data: String, field_meta: &FieldMeta, field_type: &FieldType) -> Option { let s = match field_type { FieldType::RichText => field_meta .get_type_option_entry::(field_type)? @@ -142,6 +153,9 @@ pub fn decode_cell_data(data: String, field_meta: &FieldMeta, field_type: &Field .get_type_option_entry::(field_type)? .decode_cell_data(data, field_meta), }; - tracing::Span::current().record("content", &format!("{:?}: {}", field_meta.field_type, s).as_str()); + tracing::Span::current().record( + "content", + &format!("{:?}: {}", field_meta.field_type, s.content).as_str(), + ); Some(s) } diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs index b4cb0476ef..543e743a51 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs @@ -31,15 +31,15 @@ pub fn make_cell_by_field_id( cell_meta: CellMeta, ) -> Option<(String, Cell)> { let field_meta = field_map.get(&field_id)?; - let content = decode_cell_data(cell_meta.data, field_meta, &field_meta.field_type)?; - let cell = Cell::new(&field_id, content); + let (raw, content) = decode_cell_data(cell_meta.data.clone(), field_meta, &field_meta.field_type)?.split(); + let cell = Cell::new(&field_id, content, raw); Some((field_id, cell)) } pub fn make_cell(field_id: &str, field_meta: &FieldMeta, row_meta: &RowMeta) -> Option { let cell_meta = row_meta.cells.get(field_id)?.clone(); - let content = decode_cell_data(cell_meta.data, field_meta, &field_meta.field_type)?; - Some(Cell::new(field_id, content)) + let (raw, content) = decode_cell_data(cell_meta.data.clone(), field_meta, &field_meta.field_type)?.split(); + Some(Cell::new(field_id, content, raw)) } pub(crate) fn make_row_orders_from_row_metas(row_metas: &[Arc]) -> Vec { diff --git a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs index 3c66f2355e..9ac18aed7f 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -287,7 +287,10 @@ async fn grid_row_add_date_cell_test() { let date_field = date_field.unwrap(); let cell_data = context.cell_by_field_id.get(&date_field.id).unwrap().clone(); assert_eq!( - decode_cell_data(cell_data.data.clone(), &date_field, &date_field.field_type).unwrap(), + decode_cell_data(cell_data.data.clone(), &date_field, &date_field.field_type) + .unwrap() + .split() + .1, "2022/03/16", ); let scripts = vec![CreateRow { context }]; diff --git a/shared-lib/flowy-grid-data-model/src/entities/grid.rs b/shared-lib/flowy-grid-data-model/src/entities/grid.rs index 2a287c941a..09f6f8f40c 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -461,13 +461,25 @@ pub struct Cell { #[pb(index = 2)] pub content: String, + + #[pb(index = 3)] + pub data: String, } impl Cell { - pub fn new(field_id: &str, content: String) -> Self { + pub fn new(field_id: &str, content: String, data: String) -> Self { Self { field_id: field_id.to_owned(), content, + data, + } + } + + pub fn empty(field_id: &str) -> Self { + Self { + field_id: field_id.to_owned(), + content: "".to_string(), + data: "".to_string(), } } } diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs b/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs index 072c4a4e49..5d3d3df43a 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs @@ -4692,6 +4692,7 @@ pub struct Cell { // message fields pub field_id: ::std::string::String, pub content: ::std::string::String, + pub data: ::std::string::String, // special fields pub unknown_fields: ::protobuf::UnknownFields, pub cached_size: ::protobuf::CachedSize, @@ -4759,6 +4760,32 @@ impl Cell { pub fn take_content(&mut self) -> ::std::string::String { ::std::mem::replace(&mut self.content, ::std::string::String::new()) } + + // string data = 3; + + + pub fn get_data(&self) -> &str { + &self.data + } + pub fn clear_data(&mut self) { + self.data.clear(); + } + + // Param is passed by value, moved + pub fn set_data(&mut self, v: ::std::string::String) { + 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 { + &mut self.data + } + + // Take field + pub fn take_data(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.data, ::std::string::String::new()) + } } impl ::protobuf::Message for Cell { @@ -4776,6 +4803,9 @@ impl ::protobuf::Message for Cell { 2 => { ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.content)?; }, + 3 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.data)?; + }, _ => { ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; }, @@ -4794,6 +4824,9 @@ impl ::protobuf::Message for Cell { if !self.content.is_empty() { my_size += ::protobuf::rt::string_size(2, &self.content); } + if !self.data.is_empty() { + my_size += ::protobuf::rt::string_size(3, &self.data); + } my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); self.cached_size.set(my_size); my_size @@ -4806,6 +4839,9 @@ impl ::protobuf::Message for Cell { if !self.content.is_empty() { os.write_string(2, &self.content)?; } + if !self.data.is_empty() { + os.write_string(3, &self.data)?; + } os.write_unknown_fields(self.get_unknown_fields())?; ::std::result::Result::Ok(()) } @@ -4854,6 +4890,11 @@ impl ::protobuf::Message for Cell { |m: &Cell| { &m.content }, |m: &mut Cell| { &mut m.content }, )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "data", + |m: &Cell| { &m.data }, + |m: &mut Cell| { &mut m.data }, + )); ::protobuf::reflect::MessageDescriptor::new_pb_name::( "Cell", fields, @@ -4872,6 +4913,7 @@ impl ::protobuf::Clear for Cell { fn clear(&mut self) { self.field_id.clear(); self.content.clear(); + self.data.clear(); self.unknown_fields.clear(); } } @@ -8001,46 +8043,46 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x03\x20\x03(\x0b2\t.RowOrderR\x0bdeletedRows\x123\n\x0cupdated_rows\x18\ \x04\x20\x03(\x0b2\x10.UpdatedRowOrderR\x0bupdatedRows\"E\n\tGridBlock\ \x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12(\n\nrow_orders\x18\x02\ - \x20\x03(\x0b2\t.RowOrderR\trowOrders\";\n\x04Cell\x12\x19\n\x08field_id\ + \x20\x03(\x0b2\t.RowOrderR\trowOrders\"O\n\x04Cell\x12\x19\n\x08field_id\ \x18\x01\x20\x01(\tR\x07fieldId\x12\x18\n\x07content\x18\x02\x20\x01(\tR\ - \x07content\"+\n\x0cRepeatedCell\x12\x1b\n\x05items\x18\x01\x20\x03(\x0b\ - 2\x05.CellR\x05items\"'\n\x11CreateGridPayload\x12\x12\n\x04name\x18\x01\ - \x20\x01(\tR\x04name\"\x1e\n\x06GridId\x12\x14\n\x05value\x18\x01\x20\ - \x01(\tR\x05value\"#\n\x0bGridBlockId\x12\x14\n\x05value\x18\x01\x20\x01\ - (\tR\x05value\"f\n\x10CreateRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\ - \x01(\tR\x06gridId\x12\"\n\x0cstart_row_id\x18\x02\x20\x01(\tH\0R\nstart\ - RowIdB\x15\n\x13one_of_start_row_id\"\xb6\x01\n\x12InsertFieldPayload\ - \x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x1c\n\x05field\ - \x18\x02\x20\x01(\x0b2\x06.FieldR\x05field\x12(\n\x10type_option_data\ - \x18\x03\x20\x01(\x0cR\x0etypeOptionData\x12&\n\x0estart_field_id\x18\ - \x04\x20\x01(\tH\0R\x0cstartFieldIdB\x17\n\x15one_of_start_field_id\"d\n\ - \x11QueryFieldPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\ - \x126\n\x0cfield_orders\x18\x02\x20\x01(\x0b2\x13.RepeatedFieldOrderR\ - \x0bfieldOrders\"e\n\x16QueryGridBlocksPayload\x12\x17\n\x07grid_id\x18\ - \x01\x20\x01(\tR\x06gridId\x122\n\x0cblock_orders\x18\x02\x20\x03(\x0b2\ - \x0f.GridBlockOrderR\x0bblockOrders\"\xa8\x03\n\x15FieldChangesetPayload\ - \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\0\ - R\x04name\x12\x14\n\x04desc\x18\x04\x20\x01(\tH\x01R\x04desc\x12+\n\nfie\ - ld_type\x18\x05\x20\x01(\x0e2\n.FieldTypeH\x02R\tfieldType\x12\x18\n\x06\ - frozen\x18\x06\x20\x01(\x08H\x03R\x06frozen\x12\x20\n\nvisibility\x18\ - \x07\x20\x01(\x08H\x04R\nvisibility\x12\x16\n\x05width\x18\x08\x20\x01(\ - \x05H\x05R\x05width\x12*\n\x10type_option_data\x18\t\x20\x01(\x0cH\x06R\ - \x0etypeOptionDataB\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\x19\n\x17one_of_type_option_data\"\x9c\x01\n\x0fMoveIt\ - emPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\x17\n\ - \x07item_id\x18\x02\x20\x01(\tR\x06itemId\x12\x1d\n\nfrom_index\x18\x03\ - \x20\x01(\x05R\tfromIndex\x12\x19\n\x08to_index\x18\x04\x20\x01(\x05R\ - \x07toIndex\x12\x1d\n\x02ty\x18\x05\x20\x01(\x0e2\r.MoveItemTypeR\x02ty\ - \"\x7f\n\rCellChangeset\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06grid\ - Id\x12\x15\n\x06row_id\x18\x02\x20\x01(\tR\x05rowId\x12\x19\n\x08field_i\ - d\x18\x03\x20\x01(\tR\x07fieldId\x12\x14\n\x04data\x18\x04\x20\x01(\tH\0\ - R\x04dataB\r\n\x0bone_of_data**\n\x0cMoveItemType\x12\r\n\tMoveField\x10\ - \0\x12\x0b\n\x07MoveRow\x10\x01*d\n\tFieldType\x12\x0c\n\x08RichText\x10\ - \0\x12\n\n\x06Number\x10\x01\x12\x0c\n\x08DateTime\x10\x02\x12\x10\n\x0c\ - SingleSelect\x10\x03\x12\x0f\n\x0bMultiSelect\x10\x04\x12\x0c\n\x08Check\ - box\x10\x05b\x06proto3\ + \x07content\x12\x12\n\x04data\x18\x03\x20\x01(\tR\x04data\"+\n\x0cRepeat\ + edCell\x12\x1b\n\x05items\x18\x01\x20\x03(\x0b2\x05.CellR\x05items\"'\n\ + \x11CreateGridPayload\x12\x12\n\x04name\x18\x01\x20\x01(\tR\x04name\"\ + \x1e\n\x06GridId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"#\n\ + \x0bGridBlockId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05value\"f\n\x10\ + CreateRowPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x12\ + \"\n\x0cstart_row_id\x18\x02\x20\x01(\tH\0R\nstartRowIdB\x15\n\x13one_of\ + _start_row_id\"\xb6\x01\n\x12InsertFieldPayload\x12\x17\n\x07grid_id\x18\ + \x01\x20\x01(\tR\x06gridId\x12\x1c\n\x05field\x18\x02\x20\x01(\x0b2\x06.\ + FieldR\x05field\x12(\n\x10type_option_data\x18\x03\x20\x01(\x0cR\x0etype\ + OptionData\x12&\n\x0estart_field_id\x18\x04\x20\x01(\tH\0R\x0cstartField\ + IdB\x17\n\x15one_of_start_field_id\"d\n\x11QueryFieldPayload\x12\x17\n\ + \x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x126\n\x0cfield_orders\x18\x02\ + \x20\x01(\x0b2\x13.RepeatedFieldOrderR\x0bfieldOrders\"e\n\x16QueryGridB\ + locksPayload\x12\x17\n\x07grid_id\x18\x01\x20\x01(\tR\x06gridId\x122\n\ + \x0cblock_orders\x18\x02\x20\x03(\x0b2\x0f.GridBlockOrderR\x0bblockOrder\ + s\"\xa8\x03\n\x15FieldChangesetPayload\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\ + .FieldTypeH\x02R\tfieldType\x12\x18\n\x06frozen\x18\x06\x20\x01(\x08H\ + \x03R\x06frozen\x12\x20\n\nvisibility\x18\x07\x20\x01(\x08H\x04R\nvisibi\ + lity\x12\x16\n\x05width\x18\x08\x20\x01(\x05H\x05R\x05width\x12*\n\x10ty\ + pe_option_data\x18\t\x20\x01(\x0cH\x06R\x0etypeOptionDataB\r\n\x0bone_of\ + _nameB\r\n\x0bone_of_descB\x13\n\x11one_of_field_typeB\x0f\n\rone_of_fro\ + zenB\x13\n\x11one_of_visibilityB\x0e\n\x0cone_of_widthB\x19\n\x17one_of_\ + type_option_data\"\x9c\x01\n\x0fMoveItemPayload\x12\x17\n\x07grid_id\x18\ + \x01\x20\x01(\tR\x06gridId\x12\x17\n\x07item_id\x18\x02\x20\x01(\tR\x06i\ + temId\x12\x1d\n\nfrom_index\x18\x03\x20\x01(\x05R\tfromIndex\x12\x19\n\ + \x08to_index\x18\x04\x20\x01(\x05R\x07toIndex\x12\x1d\n\x02ty\x18\x05\ + \x20\x01(\x0e2\r.MoveItemTypeR\x02ty\"\x7f\n\rCellChangeset\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\x07field\ + Id\x12\x14\n\x04data\x18\x04\x20\x01(\tH\0R\x04dataB\r\n\x0bone_of_data*\ + *\n\x0cMoveItemType\x12\r\n\tMoveField\x10\0\x12\x0b\n\x07MoveRow\x10\ + \x01*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; diff --git a/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto index 3fb7740fe7..77c6943c04 100644 --- a/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto +++ b/shared-lib/flowy-grid-data-model/src/protobuf/proto/grid.proto @@ -94,6 +94,7 @@ message GridBlock { message Cell { string field_id = 1; string content = 2; + string data = 3; } message RepeatedCell { repeated Cell items = 1;