mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
refactor: cell with origin data
This commit is contained in:
parent
f21ca6c52a
commit
f617a04900
@ -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<DateCalEvent, DateCalState> {
|
||||
@ -15,9 +17,10 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
|
||||
DateCalBloc({required this.cellContext}) : super(DateCalState.initial(cellContext)) {
|
||||
on<DateCalEvent>(
|
||||
(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<DateCalEvent, DateCalState> {
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _loadDateTypeOption(Emitter<DateCalState> 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<DateTypeOption> 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,
|
||||
);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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 {
|
||||
|
@ -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',
|
||||
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
@ -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<T: Into<CellDataChangeset>>(
|
||||
|
@ -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::<i64>() {
|
||||
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<T: Into<CellDataChangeset>>(
|
||||
|
@ -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::<f64>() {
|
||||
return v.to_string();
|
||||
return DecodedCellData::from_content(v.to_string());
|
||||
}
|
||||
|
||||
if let Ok(v) = cell_data.parse::<i64>() {
|
||||
return v.to_string();
|
||||
return DecodedCellData::from_content(v.to_string());
|
||||
}
|
||||
|
||||
return String::new();
|
||||
DecodedCellData::default()
|
||||
}
|
||||
NumberFormat::Percent => cell_data.parse::<f64>().map_or(String::new(), |v| v.to_string()),
|
||||
_ => self.money_from_str(&cell_data),
|
||||
}
|
||||
NumberFormat::Percent => {
|
||||
let content = cell_data.parse::<f64>().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()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<T: Into<CellDataChangeset>>(
|
||||
@ -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::<Vec<String>>()
|
||||
.join(SELECTION_IDS_SEPARATOR)
|
||||
.join(SELECTION_IDS_SEPARATOR);
|
||||
DecodedCellData::from_content(content)
|
||||
} else {
|
||||
String::new()
|
||||
DecodedCellData::default()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<T: Into<CellDataChangeset>>(
|
||||
&self,
|
||||
changeset: T,
|
||||
@ -106,22 +108,31 @@ pub fn apply_cell_data_changeset<T: Into<CellDataChangeset>>(
|
||||
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<String, FlowyError> {
|
||||
// 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<String> {
|
||||
#[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<DecodedCellData> {
|
||||
let s = match field_type {
|
||||
FieldType::RichText => field_meta
|
||||
.get_type_option_entry::<RichTextTypeOption>(field_type)?
|
||||
@ -142,6 +153,9 @@ pub fn decode_cell_data(data: String, field_meta: &FieldMeta, field_type: &Field
|
||||
.get_type_option_entry::<CheckboxTypeOption>(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)
|
||||
}
|
||||
|
@ -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<Cell> {
|
||||
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<RowMeta>]) -> Vec<RowOrder> {
|
||||
|
@ -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 }];
|
||||
|
@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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>(
|
||||
"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;
|
||||
|
@ -94,6 +94,7 @@ message GridBlock {
|
||||
message Cell {
|
||||
string field_id = 1;
|
||||
string content = 2;
|
||||
string data = 3;
|
||||
}
|
||||
message RepeatedCell {
|
||||
repeated Cell items = 1;
|
||||
|
Loading…
Reference in New Issue
Block a user