mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: add date type option test
This commit is contained in:
parent
a178546acd
commit
4f9470b076
@ -23,50 +23,61 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
|
||||
}) : super(DateCalState.initial(dateTypeOption, selectedDay)) {
|
||||
on<DateCalEvent>(
|
||||
(event, emit) async {
|
||||
await event.map(
|
||||
initial: (_Initial value) async {
|
||||
_startListening();
|
||||
// await _loadDateTypeOption(emit);
|
||||
await event.when(
|
||||
initial: () async => _startListening(),
|
||||
selectDay: (date) {
|
||||
_updateDateData(emit, date: date);
|
||||
},
|
||||
selectDay: (_SelectDay value) {
|
||||
if (state.dateData != null) {
|
||||
if (!isSameDay(state.dateData!.date, value.day)) {
|
||||
final newDateData = state.dateData!.copyWith(date: value.day);
|
||||
emit(state.copyWith(dateData: newDateData));
|
||||
}
|
||||
} else {
|
||||
emit(state.copyWith(dateData: DateCellPersistenceData(date: value.day)));
|
||||
}
|
||||
setCalFormat: (format) {
|
||||
emit(state.copyWith(format: format));
|
||||
},
|
||||
setCalFormat: (_CalendarFormat value) {
|
||||
emit(state.copyWith(format: value.format));
|
||||
setFocusedDay: (focusedDay) {
|
||||
emit(state.copyWith(focusedDay: focusedDay));
|
||||
},
|
||||
setFocusedDay: (_FocusedDay value) {
|
||||
emit(state.copyWith(focusedDay: value.day));
|
||||
didReceiveCellUpdate: (value) {},
|
||||
setIncludeTime: (includeTime) async {
|
||||
await _updateTypeOption(emit, includeTime: includeTime);
|
||||
},
|
||||
didReceiveCellUpdate: (_DidReceiveCellUpdate value) {},
|
||||
setIncludeTime: (_IncludeTime value) async {
|
||||
await _updateTypeOption(emit, includeTime: value.includeTime);
|
||||
setDateFormat: (dateFormat) async {
|
||||
await _updateTypeOption(emit, dateFormat: dateFormat);
|
||||
},
|
||||
setDateFormat: (_DateFormat value) async {
|
||||
await _updateTypeOption(emit, dateFormat: value.dateFormat);
|
||||
setTimeFormat: (timeFormat) async {
|
||||
await _updateTypeOption(emit, timeFormat: timeFormat);
|
||||
},
|
||||
setTimeFormat: (_TimeFormat value) async {
|
||||
await _updateTypeOption(emit, timeFormat: value.timeFormat);
|
||||
},
|
||||
setTime: (_Time value) {
|
||||
if (state.dateData != null) {
|
||||
final newDateData = state.dateData!.copyWith(time: value.time);
|
||||
emit(state.copyWith(dateData: newDateData));
|
||||
} else {
|
||||
emit(state.copyWith(dateData: DateCellPersistenceData(date: DateTime.now(), time: value.time)));
|
||||
}
|
||||
setTime: (time) {
|
||||
_updateDateData(emit, time: time);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _updateDateData(Emitter<DateCalState> emit, {DateTime? date, String? time}) {
|
||||
state.dateData.fold(
|
||||
() {
|
||||
var newDateData = DateCellPersistenceData(date: date ?? DateTime.now());
|
||||
if (time != null) {
|
||||
newDateData = newDateData.copyWith(time: time);
|
||||
}
|
||||
emit(state.copyWith(dateData: Some(newDateData)));
|
||||
},
|
||||
(dateData) {
|
||||
var newDateData = dateData;
|
||||
if (date != null && !isSameDay(newDateData.date, date)) {
|
||||
newDateData = newDateData.copyWith(date: date);
|
||||
}
|
||||
|
||||
if (newDateData.time != time) {
|
||||
newDateData = newDateData.copyWith(time: time);
|
||||
}
|
||||
|
||||
if (newDateData != dateData) {
|
||||
emit(state.copyWith(dateData: Some(newDateData)));
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
if (_onCellChangedFn != null) {
|
||||
@ -142,16 +153,16 @@ class DateCalState with _$DateCalState {
|
||||
required DateTime focusedDay,
|
||||
required String time,
|
||||
required Option<FlowyError> inputTimeError,
|
||||
DateCellPersistenceData? dateData,
|
||||
required Option<DateCellPersistenceData> dateData,
|
||||
}) = _DateCalState;
|
||||
|
||||
factory DateCalState.initial(
|
||||
DateTypeOption dateTypeOption,
|
||||
DateTime? selectedDay,
|
||||
) {
|
||||
DateCellPersistenceData? dateData;
|
||||
Option<DateCellPersistenceData> dateData = none();
|
||||
if (selectedDay != null) {
|
||||
dateData = DateCellPersistenceData(date: selectedDay);
|
||||
dateData = Some(DateCellPersistenceData(date: selectedDay));
|
||||
}
|
||||
|
||||
return DateCalState(
|
||||
|
@ -12,21 +12,11 @@ class DateCellBloc extends Bloc<DateCellEvent, DateCellState> {
|
||||
DateCellBloc({required this.cellContext}) : super(DateCellState.initial(cellContext)) {
|
||||
on<DateCellEvent>(
|
||||
(event, emit) async {
|
||||
event.map(
|
||||
initial: (_InitialCell value) {
|
||||
_startListening();
|
||||
},
|
||||
selectDay: (_SelectDay value) {
|
||||
cellContext.saveCellData(value.data);
|
||||
},
|
||||
didReceiveCellUpdate: (_DidReceiveCellUpdate value) {
|
||||
emit(state.copyWith(
|
||||
content: value.cell.content,
|
||||
));
|
||||
},
|
||||
didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) {
|
||||
emit(state.copyWith(field: value.field));
|
||||
},
|
||||
event.when(
|
||||
initial: () => _startListening(),
|
||||
selectDate: (DateCellPersistenceData value) => cellContext.saveCellData(value),
|
||||
didReceiveCellUpdate: (Cell value) => emit(state.copyWith(content: value.content)),
|
||||
didReceiveFieldUpdate: (Field value) => emit(state.copyWith(field: value)),
|
||||
);
|
||||
},
|
||||
);
|
||||
@ -56,7 +46,7 @@ class DateCellBloc extends Bloc<DateCellEvent, DateCellState> {
|
||||
@freezed
|
||||
class DateCellEvent with _$DateCellEvent {
|
||||
const factory DateCellEvent.initial() = _InitialCell;
|
||||
const factory DateCellEvent.selectDay(DateCellPersistenceData data) = _SelectDay;
|
||||
const factory DateCellEvent.selectDate(DateCellPersistenceData data) = _SelectDay;
|
||||
const factory DateCellEvent.didReceiveCellUpdate(Cell cell) = _DidReceiveCellUpdate;
|
||||
const factory DateCellEvent.didReceiveFieldUpdate(Field field) = _DidReceiveFieldUpdate;
|
||||
}
|
||||
|
@ -112,9 +112,10 @@ class _CellCalendarWidget extends StatelessWidget {
|
||||
)..add(const DateCalEvent.initial()),
|
||||
child: BlocConsumer<DateCalBloc, DateCalState>(
|
||||
listener: (context, state) {
|
||||
if (state.dateData != null) {
|
||||
onSelected(state.dateData!);
|
||||
}
|
||||
state.dateData.fold(
|
||||
() => null,
|
||||
(dateData) => onSelected(dateData),
|
||||
);
|
||||
},
|
||||
listenWhen: (p, c) => p.dateData != c.dateData,
|
||||
builder: (context, state) {
|
||||
@ -127,7 +128,13 @@ class _CellCalendarWidget extends StatelessWidget {
|
||||
|
||||
if (state.dateTypeOption.includeTime) {
|
||||
children.addAll([
|
||||
const _TimeTextField(),
|
||||
_TimeTextField(
|
||||
time: "",
|
||||
errorText: state.inputTimeError.fold(() => "", (error) => error.toString()),
|
||||
onEditingComplete: (text) {
|
||||
context.read<DateCalBloc>().add(DateCalEvent.setTime(text));
|
||||
},
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
@ -190,11 +197,10 @@ class _CellCalendarWidget extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
selectedDayPredicate: (day) {
|
||||
if (state.dateData != null) {
|
||||
return isSameDay(state.dateData!.date, day);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return state.dateData.fold(
|
||||
() => false,
|
||||
(dateData) => isSameDay(dateData.date, day),
|
||||
);
|
||||
},
|
||||
onDaySelected: (selectedDay, focusedDay) {
|
||||
context.read<DateCalBloc>().add(DateCalEvent.selectDay(selectedDay));
|
||||
@ -241,8 +247,36 @@ class _IncludeTimeButton extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class _TimeTextField extends StatelessWidget {
|
||||
const _TimeTextField({Key? key}) : super(key: key);
|
||||
class _TimeTextField extends StatefulWidget {
|
||||
final String errorText;
|
||||
final String time;
|
||||
final void Function(String) onEditingComplete;
|
||||
const _TimeTextField({
|
||||
Key? key,
|
||||
required this.time,
|
||||
required this.errorText,
|
||||
required this.onEditingComplete,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<_TimeTextField> createState() => _TimeTextFieldState();
|
||||
}
|
||||
|
||||
class _TimeTextFieldState extends State<_TimeTextField> {
|
||||
late final FocusNode _focusNode;
|
||||
late final TextEditingController _controller;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_focusNode = FocusNode();
|
||||
_controller = TextEditingController(text: widget.time);
|
||||
_focusNode.addListener(() {
|
||||
if (mounted) {
|
||||
widget.onEditingComplete(_controller.text);
|
||||
}
|
||||
});
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -251,15 +285,25 @@ class _TimeTextField extends StatelessWidget {
|
||||
padding: kMargin,
|
||||
child: RoundedInputField(
|
||||
height: 40,
|
||||
focusNode: _focusNode,
|
||||
controller: _controller,
|
||||
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
|
||||
normalBorderColor: theme.shader4,
|
||||
errorBorderColor: theme.red,
|
||||
cursorColor: theme.main1,
|
||||
errorText: context.read<DateCalBloc>().state.inputTimeError.fold(() => "", (error) => error.toString()),
|
||||
onEditingComplete: (value) => context.read<DateCalBloc>().add(DateCalEvent.setTime(value)),
|
||||
errorText: widget.errorText,
|
||||
onEditingComplete: (value) {
|
||||
widget.onEditingComplete(value);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_focusNode.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
class _DateTypeOptionButton extends StatelessWidget {
|
||||
|
@ -78,7 +78,7 @@ class _DateCellState extends State<DateCell> {
|
||||
calendar.show(
|
||||
context,
|
||||
cellContext: bloc.cellContext.clone(),
|
||||
onSelected: (day) => bloc.add(DateCellEvent.selectDay(day)),
|
||||
onSelected: (data) => bloc.add(DateCellEvent.selectDate(data)),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,20 +1,18 @@
|
||||
use crate::impl_type_option;
|
||||
use crate::services::entities::{CellIdentifier, CellIdentifierPayload};
|
||||
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
|
||||
use crate::services::row::{CellContentChangeset, CellDataOperation, DecodedCellData, TypeOptionCellData};
|
||||
use bytes::Bytes;
|
||||
use chrono::format::strftime::StrftimeItems;
|
||||
use chrono::{Datelike, NaiveDateTime};
|
||||
use chrono::NaiveDateTime;
|
||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||
use flowy_error::{ErrorCode, FlowyError};
|
||||
use flowy_error::{ErrorCode, FlowyError, FlowyResult};
|
||||
use flowy_grid_data_model::entities::{
|
||||
CellChangeset, CellMeta, FieldMeta, FieldType, TypeOptionDataDeserializer, TypeOptionDataEntry,
|
||||
};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::ops::Add;
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::services::entities::{CellIdentifier, CellIdentifierPayload};
|
||||
use crate::services::field::type_options::util::get_cell_data;
|
||||
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
|
||||
use strum_macros::EnumIter;
|
||||
|
||||
// Date
|
||||
@ -33,18 +31,45 @@ impl_type_option!(DateTypeOption, FieldType::DateTime);
|
||||
|
||||
impl DateTypeOption {
|
||||
#[allow(dead_code)]
|
||||
fn today_from_timestamp(&self, timestamp: i64) -> String {
|
||||
fn today_desc_from_timestamp(&self, timestamp: i64) -> String {
|
||||
let native = chrono::NaiveDateTime::from_timestamp(timestamp, 0);
|
||||
self.today_from_native(native)
|
||||
self.today_desc_from_native(native)
|
||||
}
|
||||
|
||||
fn today_from_native(&self, naive: chrono::NaiveDateTime) -> String {
|
||||
let utc: chrono::DateTime<chrono::Utc> = chrono::DateTime::from_utc(naive, chrono::Utc);
|
||||
let local: chrono::DateTime<chrono::Local> = chrono::DateTime::from(utc);
|
||||
let output = format!("{}", local.format_with_items(StrftimeItems::new(&self.fmt_str())));
|
||||
fn today_desc_from_str(&self, s: String) -> String {
|
||||
match NaiveDateTime::parse_from_str(&s, &self.fmt_str()) {
|
||||
Ok(native) => self.today_desc_from_native(native),
|
||||
Err(_) => "".to_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
fn today_desc_from_native(&self, native: chrono::NaiveDateTime) -> String {
|
||||
let utc = self.utc_date_time_from_native(native);
|
||||
// let china_timezone = FixedOffset::east(8 * 3600);
|
||||
// let a = utc.with_timezone(&china_timezone);
|
||||
let output = format!("{}", utc.format_with_items(StrftimeItems::new(&self.fmt_str())));
|
||||
output
|
||||
}
|
||||
|
||||
fn timestamp_from_str(&self, s: &str) -> FlowyResult<i64> {
|
||||
match NaiveDateTime::parse_from_str(s, &self.fmt_str()) {
|
||||
Ok(native) => {
|
||||
let utc = self.utc_date_time_from_native(native);
|
||||
Ok(utc.timestamp())
|
||||
}
|
||||
Err(_) => Err(ErrorCode::InvalidData.into()),
|
||||
}
|
||||
}
|
||||
|
||||
fn utc_date_time_from_timestamp(&self, timestamp: i64) -> chrono::DateTime<chrono::Utc> {
|
||||
let native = NaiveDateTime::from_timestamp(timestamp, 0);
|
||||
self.utc_date_time_from_native(native)
|
||||
}
|
||||
|
||||
fn utc_date_time_from_native(&self, naive: chrono::NaiveDateTime) -> chrono::DateTime<chrono::Utc> {
|
||||
chrono::DateTime::<chrono::Utc>::from_utc(naive, chrono::Utc)
|
||||
}
|
||||
|
||||
fn fmt_str(&self) -> String {
|
||||
if self.include_time {
|
||||
format!("{} {}", self.date_format.format_str(), self.time_format.format_str())
|
||||
@ -63,14 +88,11 @@ impl CellDataOperation for DateTypeOption {
|
||||
|
||||
let cell_data = type_option_cell_data.data;
|
||||
if let Ok(timestamp) = cell_data.parse::<i64>() {
|
||||
let native = NaiveDateTime::from_timestamp(timestamp, 0);
|
||||
return DecodedCellData::new(format!("{}", timestamp), self.today_from_native(native));
|
||||
return DecodedCellData::new(format!("{}", timestamp), self.today_desc_from_timestamp(timestamp));
|
||||
}
|
||||
|
||||
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(),
|
||||
};
|
||||
let cell_content = self.today_desc_from_str(cell_data.clone());
|
||||
return DecodedCellData::new(cell_data, cell_content);
|
||||
}
|
||||
|
||||
DecodedCellData::default()
|
||||
@ -79,25 +101,29 @@ impl CellDataOperation for DateTypeOption {
|
||||
fn apply_changeset<T: Into<CellContentChangeset>>(
|
||||
&self,
|
||||
changeset: T,
|
||||
cell_meta: Option<CellMeta>,
|
||||
_cell_meta: Option<CellMeta>,
|
||||
) -> Result<String, FlowyError> {
|
||||
let content_changeset: DateCellContentChangeset = serde_json::from_str(&changeset.into())?;
|
||||
match cell_meta {
|
||||
None => Ok(TypeOptionCellData::new("", self.field_type()).json()),
|
||||
Some(cell_meta) => {
|
||||
let s = match content_changeset.timestamp() {
|
||||
None => get_cell_data(&cell_meta),
|
||||
Some(timestamp) => timestamp.to_string(),
|
||||
};
|
||||
|
||||
Ok(TypeOptionCellData::new(s, self.field_type()).json())
|
||||
|
||||
// let changeset = changeset.into();
|
||||
// if changeset.parse::<f64>().is_err() || changeset.parse::<i64>().is_err() {
|
||||
// return Err(FlowyError::internal().context(format!("Parse {} failed", changeset)));
|
||||
// };
|
||||
let cell_content = match content_changeset.date_timestamp() {
|
||||
None => "".to_owned(),
|
||||
Some(date_timestamp) => {
|
||||
//
|
||||
match (self.include_time, content_changeset.time) {
|
||||
(true, Some(time)) => {
|
||||
let utc = self.utc_date_time_from_timestamp(date_timestamp);
|
||||
let mut date_str = format!(
|
||||
"{}",
|
||||
utc.format_with_items(StrftimeItems::new(self.date_format.format_str()))
|
||||
);
|
||||
date_str = date_str.add(&time);
|
||||
let timestamp = self.timestamp_from_str(&date_str)?;
|
||||
timestamp.to_string()
|
||||
}
|
||||
_ => date_timestamp.to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
Ok(TypeOptionCellData::new(cell_content, self.field_type()).json())
|
||||
}
|
||||
}
|
||||
|
||||
@ -197,7 +223,7 @@ impl TimeFormat {
|
||||
// https://docs.rs/chrono/0.4.19/chrono/format/strftime/index.html
|
||||
pub fn format_str(&self) -> &'static str {
|
||||
match self {
|
||||
TimeFormat::TwelveHour => "%r",
|
||||
TimeFormat::TwelveHour => "%I:%M %p",
|
||||
TimeFormat::TwentyFourHour => "%R",
|
||||
}
|
||||
}
|
||||
@ -240,37 +266,6 @@ impl TryInto<DateChangesetParams> for DateChangesetPayload {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct DateCellContentChangeset {
|
||||
pub date: Option<String>,
|
||||
pub time: Option<String>,
|
||||
}
|
||||
|
||||
impl DateCellContentChangeset {
|
||||
pub fn timestamp(self) -> Option<i64> {
|
||||
let mut timestamp = 0;
|
||||
if let Some(date) = self.date {
|
||||
match date.parse::<i64>() {
|
||||
Ok(date_timestamp) => {
|
||||
timestamp += date_timestamp;
|
||||
}
|
||||
Err(_) => {}
|
||||
}
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
|
||||
if let Some(time) = self.time {
|
||||
match time.parse::<i64>() {
|
||||
Ok(time_timestamp) => timestamp += time_timestamp,
|
||||
Err(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
return Some(timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<DateChangesetParams> for CellChangeset {
|
||||
fn from(params: DateChangesetParams) -> Self {
|
||||
let changeset = DateCellContentChangeset {
|
||||
@ -287,10 +282,36 @@ impl std::convert::From<DateChangesetParams> for CellChangeset {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct DateCellContentChangeset {
|
||||
pub date: Option<String>,
|
||||
pub time: Option<String>,
|
||||
}
|
||||
|
||||
impl DateCellContentChangeset {
|
||||
pub fn date_timestamp(&self) -> Option<i64> {
|
||||
if let Some(date) = &self.date {
|
||||
match date.parse::<i64>() {
|
||||
Ok(date_timestamp) => Some(date_timestamp),
|
||||
Err(_) => None,
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<DateCellContentChangeset> for CellContentChangeset {
|
||||
fn from(changeset: DateCellContentChangeset) -> Self {
|
||||
let s = serde_json::to_string(&changeset).unwrap();
|
||||
CellContentChangeset::from(s)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::services::field::FieldBuilder;
|
||||
use crate::services::field::{DateFormat, DateTypeOption, TimeFormat};
|
||||
use crate::services::field::{DateCellContentChangeset, DateFormat, DateTypeOption, TimeFormat};
|
||||
use crate::services::row::{CellDataOperation, TypeOptionCellData};
|
||||
use flowy_grid_data_model::entities::FieldType;
|
||||
use strum::IntoEnumIterator;
|
||||
@ -362,14 +383,20 @@ mod tests {
|
||||
type_option.time_format = time_format;
|
||||
match time_format {
|
||||
TimeFormat::TwentyFourHour => {
|
||||
assert_eq!("Mar 14,2022".to_owned(), type_option.today_from_timestamp(1647251762));
|
||||
assert_eq!(
|
||||
"Mar 14,2022".to_owned(),
|
||||
type_option.today_desc_from_timestamp(1647251762)
|
||||
);
|
||||
assert_eq!(
|
||||
"Mar 14,2022".to_owned(),
|
||||
type_option.decode_cell_data(data("1647251762"), &field_meta).content
|
||||
);
|
||||
}
|
||||
TimeFormat::TwelveHour => {
|
||||
assert_eq!("Mar 14,2022".to_owned(), type_option.today_from_timestamp(1647251762));
|
||||
assert_eq!(
|
||||
"Mar 14,2022".to_owned(),
|
||||
type_option.today_desc_from_timestamp(1647251762)
|
||||
);
|
||||
assert_eq!(
|
||||
"Mar 14,2022".to_owned(),
|
||||
type_option.decode_cell_data(data("1647251762"), &field_meta).content
|
||||
@ -379,6 +406,72 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn date_description_apply_changeset_test() {
|
||||
let mut type_option = DateTypeOption::default();
|
||||
let field_meta = FieldBuilder::from_field_type(&FieldType::Number).build();
|
||||
let date_timestamp = "1653609600".to_owned();
|
||||
|
||||
let changeset = DateCellContentChangeset {
|
||||
date: Some(date_timestamp.clone()),
|
||||
time: None,
|
||||
};
|
||||
let result = type_option.apply_changeset(changeset, None).unwrap();
|
||||
let content = type_option.decode_cell_data(result.clone(), &field_meta).content;
|
||||
assert_eq!(content, "May 27,2022".to_owned());
|
||||
|
||||
type_option.include_time = true;
|
||||
let content = type_option.decode_cell_data(result, &field_meta).content;
|
||||
assert_eq!(content, "May 27,2022 00:00".to_owned());
|
||||
|
||||
let changeset = DateCellContentChangeset {
|
||||
date: Some(date_timestamp.clone()),
|
||||
time: Some("1:00".to_owned()),
|
||||
};
|
||||
let result = type_option.apply_changeset(changeset, None).unwrap();
|
||||
let content = type_option.decode_cell_data(result, &field_meta).content;
|
||||
assert_eq!(content, "May 27,2022 01:00".to_owned());
|
||||
|
||||
let changeset = DateCellContentChangeset {
|
||||
date: Some(date_timestamp),
|
||||
time: Some("1:00 am".to_owned()),
|
||||
};
|
||||
type_option.time_format = TimeFormat::TwelveHour;
|
||||
let result = type_option.apply_changeset(changeset, None).unwrap();
|
||||
let content = type_option.decode_cell_data(result, &field_meta).content;
|
||||
assert_eq!(content, "May 27,2022 01:00 AM".to_owned());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn date_description_apply_changeset_error_test() {
|
||||
let mut type_option = DateTypeOption::default();
|
||||
type_option.include_time = true;
|
||||
let field_meta = FieldBuilder::from_field_type(&FieldType::Number).build();
|
||||
let date_timestamp = "1653609600".to_owned();
|
||||
|
||||
let changeset = DateCellContentChangeset {
|
||||
date: Some(date_timestamp.clone()),
|
||||
time: Some("1:a0".to_owned()),
|
||||
};
|
||||
let _ = type_option.apply_changeset(changeset, None).unwrap();
|
||||
|
||||
let changeset = DateCellContentChangeset {
|
||||
date: Some(date_timestamp.clone()),
|
||||
time: Some("1:".to_owned()),
|
||||
};
|
||||
let _ = type_option.apply_changeset(changeset, None).unwrap();
|
||||
|
||||
// let changeset = DateCellContentChangeset {
|
||||
// date: Some(date_timestamp),
|
||||
// time: Some("1:00 am".to_owned()),
|
||||
// };
|
||||
// type_option.time_format = TimeFormat::TwelveHour;
|
||||
// let result = type_option.apply_changeset(changeset, None).unwrap();
|
||||
// let content = type_option.decode_cell_data(result, &field_meta).content;
|
||||
// assert_eq!(content, "May 27,2022 01:00 AM".to_owned());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn date_description_invalid_data_test() {
|
||||
|
@ -337,7 +337,7 @@ impl ClientGridEditor {
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "trace", skip_all, err)]
|
||||
pub async fn update_cell(&self, mut cell_changeset: CellChangeset) -> FlowyResult<()> {
|
||||
pub async fn update_cell(&self, cell_changeset: CellChangeset) -> FlowyResult<()> {
|
||||
if cell_changeset.cell_content_changeset.as_ref().is_none() {
|
||||
return Ok(());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user