mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
fix: edit date time issue
This commit is contained in:
parent
a384404814
commit
4b88aa8683
@ -198,6 +198,10 @@
|
|||||||
"colorPannelTitle": "Colors",
|
"colorPannelTitle": "Colors",
|
||||||
"pannelTitle": "Select an option or create one",
|
"pannelTitle": "Select an option or create one",
|
||||||
"searchOption": "Search for an option"
|
"searchOption": "Search for an option"
|
||||||
|
},
|
||||||
|
"date": {
|
||||||
|
"timeHintTextInTwelveHour": "12:00 AM",
|
||||||
|
"timeHintTextInTwentyFourHour": "12:00"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ part of 'cell_service.dart';
|
|||||||
|
|
||||||
typedef GridCellContext = _GridCellContext<String, String>;
|
typedef GridCellContext = _GridCellContext<String, String>;
|
||||||
typedef GridSelectOptionCellContext = _GridCellContext<SelectOptionCellData, String>;
|
typedef GridSelectOptionCellContext = _GridCellContext<SelectOptionCellData, String>;
|
||||||
typedef GridDateCellContext = _GridCellContext<DateCellData, DateCalData>;
|
typedef GridDateCellContext = _GridCellContext<DateCellData, CalendarData>;
|
||||||
typedef GridURLCellContext = _GridCellContext<URLCellData, String>;
|
typedef GridURLCellContext = _GridCellContext<URLCellData, String>;
|
||||||
|
|
||||||
class GridCellContextBuilder {
|
class GridCellContextBuilder {
|
||||||
|
@ -31,18 +31,18 @@ class CellDataPersistence implements _GridCellDataPersistence<String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class DateCalData with _$DateCalData {
|
class CalendarData with _$CalendarData {
|
||||||
const factory DateCalData({required DateTime date, String? time}) = _DateCellPersistenceData;
|
const factory CalendarData({required DateTime date, String? time}) = _CalendarData;
|
||||||
}
|
}
|
||||||
|
|
||||||
class DateCellDataPersistence implements _GridCellDataPersistence<DateCalData> {
|
class DateCellDataPersistence implements _GridCellDataPersistence<CalendarData> {
|
||||||
final GridCell gridCell;
|
final GridCell gridCell;
|
||||||
DateCellDataPersistence({
|
DateCellDataPersistence({
|
||||||
required this.gridCell,
|
required this.gridCell,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Option<FlowyError>> save(DateCalData data) {
|
Future<Option<FlowyError>> save(CalendarData data) {
|
||||||
var payload = DateChangesetPayload.create()..cellIdentifier = _cellIdentifier(gridCell);
|
var payload = DateChangesetPayload.create()..cellIdentifier = _cellIdentifier(gridCell);
|
||||||
|
|
||||||
final date = (data.date.millisecondsSinceEpoch ~/ 1000).toString();
|
final date = (data.date.millisecondsSinceEpoch ~/ 1000).toString();
|
||||||
|
@ -38,9 +38,9 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
|
|||||||
emit(state.copyWith(focusedDay: focusedDay));
|
emit(state.copyWith(focusedDay: focusedDay));
|
||||||
},
|
},
|
||||||
didReceiveCellUpdate: (DateCellData? cellData) {
|
didReceiveCellUpdate: (DateCellData? cellData) {
|
||||||
final dateData = dateDataFromCellData(cellData);
|
final calData = calDataFromCellData(cellData);
|
||||||
final time = dateData.foldRight("", (dateData, previous) => dateData.time);
|
final time = calData.foldRight("", (dateData, previous) => dateData.time);
|
||||||
emit(state.copyWith(dateData: dateData, time: time));
|
emit(state.copyWith(calData: calData, time: time));
|
||||||
},
|
},
|
||||||
setIncludeTime: (includeTime) async {
|
setIncludeTime: (includeTime) async {
|
||||||
await _updateTypeOption(emit, includeTime: includeTime);
|
await _updateTypeOption(emit, includeTime: includeTime);
|
||||||
@ -52,7 +52,12 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
|
|||||||
await _updateTypeOption(emit, timeFormat: timeFormat);
|
await _updateTypeOption(emit, timeFormat: timeFormat);
|
||||||
},
|
},
|
||||||
setTime: (time) async {
|
setTime: (time) async {
|
||||||
|
if (state.calData.isSome()) {
|
||||||
await _updateDateData(emit, time: time);
|
await _updateDateData(emit, time: time);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
didUpdateCalData: (Option<CalendarData> data, Option<String> timeFormatError) {
|
||||||
|
emit(state.copyWith(calData: data, timeFormatError: timeFormatError));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -60,8 +65,8 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _updateDateData(Emitter<DateCalState> emit, {DateTime? date, String? time}) {
|
Future<void> _updateDateData(Emitter<DateCalState> emit, {DateTime? date, String? time}) {
|
||||||
final DateCalData newDateData = state.dateData.fold(
|
final CalendarData newDateData = state.calData.fold(
|
||||||
() => DateCalData(date: date ?? DateTime.now(), time: time),
|
() => CalendarData(date: date ?? DateTime.now(), time: time),
|
||||||
(dateData) {
|
(dateData) {
|
||||||
var newDateData = dateData;
|
var newDateData = dateData;
|
||||||
if (date != null && !isSameDay(newDateData.date, date)) {
|
if (date != null && !isSameDay(newDateData.date, date)) {
|
||||||
@ -78,24 +83,22 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
|
|||||||
return _saveDateData(emit, newDateData);
|
return _saveDateData(emit, newDateData);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _saveDateData(Emitter<DateCalState> emit, DateCalData newDateData) async {
|
Future<void> _saveDateData(Emitter<DateCalState> emit, CalendarData newCalData) async {
|
||||||
if (state.dateData == Some(newDateData)) {
|
if (state.calData == Some(newCalData)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cellContext.saveCellData(newDateData, resultCallback: (result) {
|
updateCalData(Option<CalendarData> calData, Option<String> timeFormatError) {
|
||||||
|
if (!isClosed) add(DateCalEvent.didUpdateCalData(calData, timeFormatError));
|
||||||
|
}
|
||||||
|
|
||||||
|
cellContext.saveCellData(newCalData, resultCallback: (result) {
|
||||||
result.fold(
|
result.fold(
|
||||||
() => emit(state.copyWith(
|
() => updateCalData(Some(newCalData), none()),
|
||||||
dateData: Some(newDateData),
|
|
||||||
timeFormatError: none(),
|
|
||||||
)),
|
|
||||||
(err) {
|
(err) {
|
||||||
switch (ErrorCode.valueOf(err.code)!) {
|
switch (ErrorCode.valueOf(err.code)!) {
|
||||||
case ErrorCode.InvalidDateTimeFormat:
|
case ErrorCode.InvalidDateTimeFormat:
|
||||||
emit(state.copyWith(
|
updateCalData(none(), Some(timeFormatPrompt(err)));
|
||||||
dateData: Some(newDateData),
|
|
||||||
timeFormatError: Some(timeFormatPrompt(err)),
|
|
||||||
));
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Log.error(err);
|
Log.error(err);
|
||||||
@ -168,7 +171,7 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
result.fold(
|
result.fold(
|
||||||
(l) => emit(state.copyWith(dateTypeOption: newDateTypeOption)),
|
(l) => emit(state.copyWith(dateTypeOption: newDateTypeOption, timeHintText: _timeHintText(newDateTypeOption))),
|
||||||
(err) => Log.error(err),
|
(err) => Log.error(err),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -185,6 +188,8 @@ class DateCalEvent with _$DateCalEvent {
|
|||||||
const factory DateCalEvent.setIncludeTime(bool includeTime) = _IncludeTime;
|
const factory DateCalEvent.setIncludeTime(bool includeTime) = _IncludeTime;
|
||||||
const factory DateCalEvent.setTime(String time) = _Time;
|
const factory DateCalEvent.setTime(String time) = _Time;
|
||||||
const factory DateCalEvent.didReceiveCellUpdate(DateCellData? data) = _DidReceiveCellUpdate;
|
const factory DateCalEvent.didReceiveCellUpdate(DateCellData? data) = _DidReceiveCellUpdate;
|
||||||
|
const factory DateCalEvent.didUpdateCalData(Option<CalendarData> data, Option<String> timeFormatError) =
|
||||||
|
_DidUpdateCalData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
@ -194,36 +199,48 @@ class DateCalState with _$DateCalState {
|
|||||||
required CalendarFormat format,
|
required CalendarFormat format,
|
||||||
required DateTime focusedDay,
|
required DateTime focusedDay,
|
||||||
required Option<String> timeFormatError,
|
required Option<String> timeFormatError,
|
||||||
required Option<DateCalData> dateData,
|
required Option<CalendarData> calData,
|
||||||
required String? time,
|
required String? time,
|
||||||
|
required String timeHintText,
|
||||||
}) = _DateCalState;
|
}) = _DateCalState;
|
||||||
|
|
||||||
factory DateCalState.initial(
|
factory DateCalState.initial(
|
||||||
DateTypeOption dateTypeOption,
|
DateTypeOption dateTypeOption,
|
||||||
DateCellData? cellData,
|
DateCellData? cellData,
|
||||||
) {
|
) {
|
||||||
Option<DateCalData> dateData = dateDataFromCellData(cellData);
|
Option<CalendarData> calData = calDataFromCellData(cellData);
|
||||||
final time = dateData.foldRight("", (dateData, previous) => dateData.time);
|
final time = calData.foldRight("", (dateData, previous) => dateData.time);
|
||||||
return DateCalState(
|
return DateCalState(
|
||||||
dateTypeOption: dateTypeOption,
|
dateTypeOption: dateTypeOption,
|
||||||
format: CalendarFormat.month,
|
format: CalendarFormat.month,
|
||||||
focusedDay: DateTime.now(),
|
focusedDay: DateTime.now(),
|
||||||
time: time,
|
time: time,
|
||||||
dateData: dateData,
|
calData: calData,
|
||||||
timeFormatError: none(),
|
timeFormatError: none(),
|
||||||
|
timeHintText: _timeHintText(dateTypeOption),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Option<DateCalData> dateDataFromCellData(DateCellData? cellData) {
|
String _timeHintText(DateTypeOption typeOption) {
|
||||||
|
switch (typeOption.timeFormat) {
|
||||||
|
case TimeFormat.TwelveHour:
|
||||||
|
return LocaleKeys.grid_date_timeHintTextInTwelveHour.tr();
|
||||||
|
case TimeFormat.TwentyFourHour:
|
||||||
|
return LocaleKeys.grid_date_timeHintTextInTwentyFourHour.tr();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
Option<CalendarData> calDataFromCellData(DateCellData? cellData) {
|
||||||
String? time = timeFromCellData(cellData);
|
String? time = timeFromCellData(cellData);
|
||||||
Option<DateCalData> dateData = none();
|
Option<CalendarData> calData = none();
|
||||||
if (cellData != null) {
|
if (cellData != null) {
|
||||||
final timestamp = cellData.timestamp * 1000;
|
final timestamp = cellData.timestamp * 1000;
|
||||||
final date = DateTime.fromMillisecondsSinceEpoch(timestamp.toInt());
|
final date = DateTime.fromMillisecondsSinceEpoch(timestamp.toInt());
|
||||||
dateData = Some(DateCalData(date: date, time: time));
|
calData = Some(CalendarData(date: date, time: time));
|
||||||
}
|
}
|
||||||
return dateData;
|
return calData;
|
||||||
}
|
}
|
||||||
|
|
||||||
$fixnum.Int64 timestampFromDateTime(DateTime dateTime) {
|
$fixnum.Int64 timestampFromDateTime(DateTime dateTime) {
|
||||||
|
@ -4,7 +4,6 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'cell_service/cell_service.dart';
|
import 'cell_service/cell_service.dart';
|
||||||
import 'package:dartz/dartz.dart';
|
|
||||||
part 'date_cell_bloc.freezed.dart';
|
part 'date_cell_bloc.freezed.dart';
|
||||||
|
|
||||||
class DateCellBloc extends Bloc<DateCellEvent, DateCellState> {
|
class DateCellBloc extends Bloc<DateCellEvent, DateCellState> {
|
||||||
@ -17,11 +16,7 @@ class DateCellBloc extends Bloc<DateCellEvent, DateCellState> {
|
|||||||
event.when(
|
event.when(
|
||||||
initial: () => _startListening(),
|
initial: () => _startListening(),
|
||||||
didReceiveCellUpdate: (DateCellData? cellData) {
|
didReceiveCellUpdate: (DateCellData? cellData) {
|
||||||
if (cellData != null) {
|
emit(state.copyWith(data: cellData, dateStr: _dateStrFromCellData(cellData)));
|
||||||
emit(state.copyWith(data: Some(cellData)));
|
|
||||||
} else {
|
|
||||||
emit(state.copyWith(data: none()));
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
didReceiveFieldUpdate: (Field value) => emit(state.copyWith(field: value)),
|
didReceiveFieldUpdate: (Field value) => emit(state.copyWith(field: value)),
|
||||||
);
|
);
|
||||||
@ -60,21 +55,26 @@ class DateCellEvent with _$DateCellEvent {
|
|||||||
@freezed
|
@freezed
|
||||||
class DateCellState with _$DateCellState {
|
class DateCellState with _$DateCellState {
|
||||||
const factory DateCellState({
|
const factory DateCellState({
|
||||||
required Option<DateCellData> data,
|
required DateCellData? data,
|
||||||
|
required String dateStr,
|
||||||
required Field field,
|
required Field field,
|
||||||
}) = _DateCellState;
|
}) = _DateCellState;
|
||||||
|
|
||||||
factory DateCellState.initial(GridDateCellContext context) {
|
factory DateCellState.initial(GridDateCellContext context) {
|
||||||
final cellData = context.getCellData();
|
final cellData = context.getCellData();
|
||||||
Option<DateCellData> data = none();
|
|
||||||
|
|
||||||
if (cellData != null) {
|
|
||||||
data = Some(cellData);
|
|
||||||
}
|
|
||||||
|
|
||||||
return DateCellState(
|
return DateCellState(
|
||||||
field: context.field,
|
field: context.field,
|
||||||
data: data,
|
data: cellData,
|
||||||
|
dateStr: _dateStrFromCellData(cellData),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String _dateStrFromCellData(DateCellData? cellData) {
|
||||||
|
String dateStr = "";
|
||||||
|
if (cellData != null) {
|
||||||
|
dateStr = cellData.date + " " + cellData.time;
|
||||||
|
}
|
||||||
|
return dateStr;
|
||||||
|
}
|
||||||
|
@ -64,7 +64,7 @@ class _DateCellState extends State<DateCell> {
|
|||||||
cursor: SystemMouseCursors.click,
|
cursor: SystemMouseCursors.click,
|
||||||
child: Align(
|
child: Align(
|
||||||
alignment: alignment,
|
alignment: alignment,
|
||||||
child: FlowyText.medium(state.data.foldRight("", (data, _) => data.date), fontSize: 12),
|
child: FlowyText.medium(state.dateStr, fontSize: 12),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -160,18 +160,21 @@ class _CellCalendarWidget extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
selectedDayPredicate: (day) {
|
selectedDayPredicate: (day) {
|
||||||
return state.dateData.fold(
|
return state.calData.fold(
|
||||||
() => false,
|
() => false,
|
||||||
(dateData) => isSameDay(dateData.date, day),
|
(dateData) => isSameDay(dateData.date, day),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
onDaySelected: (selectedDay, focusedDay) {
|
onDaySelected: (selectedDay, focusedDay) {
|
||||||
|
_CalDateTimeSetting.hide(context);
|
||||||
context.read<DateCalBloc>().add(DateCalEvent.selectDay(selectedDay));
|
context.read<DateCalBloc>().add(DateCalEvent.selectDay(selectedDay));
|
||||||
},
|
},
|
||||||
onFormatChanged: (format) {
|
onFormatChanged: (format) {
|
||||||
|
_CalDateTimeSetting.hide(context);
|
||||||
context.read<DateCalBloc>().add(DateCalEvent.setCalFormat(format));
|
context.read<DateCalBloc>().add(DateCalEvent.setCalFormat(format));
|
||||||
},
|
},
|
||||||
onPageChanged: (focusedDay) {
|
onPageChanged: (focusedDay) {
|
||||||
|
_CalDateTimeSetting.hide(context);
|
||||||
context.read<DateCalBloc>().add(DateCalEvent.setFocusedDay(focusedDay));
|
context.read<DateCalBloc>().add(DateCalEvent.setFocusedDay(focusedDay));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -234,6 +237,7 @@ class _TimeTextFieldState extends State<_TimeTextField> {
|
|||||||
if (widget.bloc.state.dateTypeOption.includeTime) {
|
if (widget.bloc.state.dateTypeOption.includeTime) {
|
||||||
_focusNode.addListener(() {
|
_focusNode.addListener(() {
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
|
_CalDateTimeSetting.hide(context);
|
||||||
widget.bloc.add(DateCalEvent.setTime(_controller.text));
|
widget.bloc.add(DateCalEvent.setTime(_controller.text));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -257,6 +261,7 @@ class _TimeTextFieldState extends State<_TimeTextField> {
|
|||||||
child: RoundedInputField(
|
child: RoundedInputField(
|
||||||
height: 40,
|
height: 40,
|
||||||
focusNode: _focusNode,
|
focusNode: _focusNode,
|
||||||
|
hintText: state.timeHintText,
|
||||||
controller: _controller,
|
controller: _controller,
|
||||||
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
|
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
|
||||||
normalBorderColor: theme.shader4,
|
normalBorderColor: theme.shader4,
|
||||||
@ -326,6 +331,7 @@ class _CalDateTimeSetting extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void show(BuildContext context) {
|
void show(BuildContext context) {
|
||||||
|
hide(context);
|
||||||
FlowyOverlay.of(context).insertWithAnchor(
|
FlowyOverlay.of(context).insertWithAnchor(
|
||||||
widget: OverlayContainer(
|
widget: OverlayContainer(
|
||||||
child: this,
|
child: this,
|
||||||
@ -337,6 +343,10 @@ class _CalDateTimeSetting extends StatefulWidget {
|
|||||||
anchorOffset: const Offset(20, 0),
|
anchorOffset: const Offset(20, 0),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void hide(BuildContext context) {
|
||||||
|
FlowyOverlay.of(context).remove(identifier());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _CalDateTimeSettingState extends State<_CalDateTimeSetting> {
|
class _CalDateTimeSettingState extends State<_CalDateTimeSetting> {
|
||||||
|
@ -42,7 +42,7 @@ impl_type_option!(CheckboxTypeOption, FieldType::Checkbox);
|
|||||||
const YES: &str = "Yes";
|
const YES: &str = "Yes";
|
||||||
const NO: &str = "No";
|
const NO: &str = "No";
|
||||||
|
|
||||||
impl CellDataOperation<String, String> for CheckboxTypeOption {
|
impl CellDataOperation<String> for CheckboxTypeOption {
|
||||||
fn decode_cell_data<T>(
|
fn decode_cell_data<T>(
|
||||||
&self,
|
&self,
|
||||||
encoded_data: T,
|
encoded_data: T,
|
||||||
|
@ -4,7 +4,7 @@ use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
|
|||||||
use crate::services::row::{CellContentChangeset, CellDataOperation, DecodedCellData, EncodedCellData};
|
use crate::services::row::{CellContentChangeset, CellDataOperation, DecodedCellData, EncodedCellData};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use chrono::format::strftime::StrftimeItems;
|
use chrono::format::strftime::StrftimeItems;
|
||||||
use chrono::NaiveDateTime;
|
use chrono::{NaiveDateTime, Timelike};
|
||||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||||
use flowy_error::{internal_error, ErrorCode, FlowyError, FlowyResult};
|
use flowy_error::{internal_error, ErrorCode, FlowyError, FlowyResult};
|
||||||
use flowy_grid_data_model::entities::{
|
use flowy_grid_data_model::entities::{
|
||||||
@ -29,35 +29,36 @@ pub struct DateTypeOption {
|
|||||||
impl_type_option!(DateTypeOption, FieldType::DateTime);
|
impl_type_option!(DateTypeOption, FieldType::DateTime);
|
||||||
|
|
||||||
impl DateTypeOption {
|
impl DateTypeOption {
|
||||||
fn today_desc_from_timestamp(&self, timestamp: i64, time: &Option<String>) -> String {
|
|
||||||
let native = chrono::NaiveDateTime::from_timestamp(timestamp, 0);
|
|
||||||
self.today_desc_from_native(native, time)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
fn today_desc_from_str(&self, s: String, time: &Option<String>) -> String {
|
pub fn new() -> Self {
|
||||||
match NaiveDateTime::parse_from_str(&s, &self.date_fmt(time)) {
|
Self::default()
|
||||||
Ok(native) => self.today_desc_from_native(native, time),
|
|
||||||
Err(_) => "".to_owned(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn today_desc_from_native(&self, native: chrono::NaiveDateTime, time: &Option<String>) -> String {
|
fn today_desc_from_timestamp(&self, timestamp: i64) -> DateCellData {
|
||||||
|
let native = chrono::NaiveDateTime::from_timestamp(timestamp, 0);
|
||||||
|
self.date_from_native(native)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn date_from_native(&self, native: chrono::NaiveDateTime) -> DateCellData {
|
||||||
|
if native.timestamp() == 0 {
|
||||||
|
return DateCellData::default();
|
||||||
|
}
|
||||||
|
|
||||||
|
let time = native.time();
|
||||||
|
let has_time = time.hour() != 0 || time.second() != 0;
|
||||||
|
|
||||||
let utc = self.utc_date_time_from_native(native);
|
let utc = self.utc_date_time_from_native(native);
|
||||||
// let china_timezone = FixedOffset::east(8 * 3600);
|
let fmt = self.date_format.format_str();
|
||||||
// let a = utc.with_timezone(&china_timezone);
|
let date = format!("{}", utc.format_with_items(StrftimeItems::new(fmt)));
|
||||||
let fmt = self.date_fmt(time);
|
|
||||||
let output = format!("{}", utc.format_with_items(StrftimeItems::new(&fmt)));
|
let mut time = "".to_string();
|
||||||
output
|
if has_time {
|
||||||
|
let fmt = format!("{} {}", self.date_format.format_str(), self.time_format.format_str());
|
||||||
|
time = format!("{}", utc.format_with_items(StrftimeItems::new(&fmt))).replace(&date, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn utc_date_time_from_timestamp(&self, timestamp: i64) -> chrono::DateTime<chrono::Utc> {
|
let timestamp = native.timestamp();
|
||||||
let native = NaiveDateTime::from_timestamp(timestamp, 0);
|
DateCellData { date, time, timestamp }
|
||||||
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 date_fmt(&self, time: &Option<String>) -> String {
|
fn date_fmt(&self, time: &Option<String>) -> String {
|
||||||
@ -77,14 +78,6 @@ impl DateTypeOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn date_desc_from_timestamp(&self, serde_cell_data: &DateCellDataSerde) -> String {
|
|
||||||
if serde_cell_data.timestamp == 0 {
|
|
||||||
return "".to_owned();
|
|
||||||
}
|
|
||||||
|
|
||||||
self.today_desc_from_timestamp(serde_cell_data.timestamp, &serde_cell_data.time)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn timestamp_from_utc_with_time(
|
fn timestamp_from_utc_with_time(
|
||||||
&self,
|
&self,
|
||||||
utc: &chrono::DateTime<chrono::Utc>,
|
utc: &chrono::DateTime<chrono::Utc>,
|
||||||
@ -113,9 +106,18 @@ impl DateTypeOption {
|
|||||||
|
|
||||||
Ok(utc.timestamp())
|
Ok(utc.timestamp())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CellDataOperation<EncodedCellData<DateCellDataSerde>, DateCellDataSerde> for DateTypeOption {
|
impl CellDataOperation<EncodedCellData<DateCellDataSerde>> for DateTypeOption {
|
||||||
fn decode_cell_data<T>(
|
fn decode_cell_data<T>(
|
||||||
&self,
|
&self,
|
||||||
encoded_data: T,
|
encoded_data: T,
|
||||||
@ -134,14 +136,11 @@ impl CellDataOperation<EncodedCellData<DateCellDataSerde>, DateCellDataSerde> fo
|
|||||||
}
|
}
|
||||||
|
|
||||||
let encoded_data = encoded_data.into().try_into_inner()?;
|
let encoded_data = encoded_data.into().try_into_inner()?;
|
||||||
let date = self.date_desc_from_timestamp(&encoded_data);
|
let date = self.today_desc_from_timestamp(encoded_data.timestamp);
|
||||||
let time = encoded_data.time.unwrap_or_else(|| "".to_owned());
|
DecodedCellData::try_from_bytes(date)
|
||||||
let timestamp = encoded_data.timestamp;
|
|
||||||
|
|
||||||
DecodedCellData::try_from_bytes(DateCellData { date, time, timestamp })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_changeset<C>(&self, changeset: C, _cell_meta: Option<CellMeta>) -> Result<DateCellDataSerde, FlowyError>
|
fn apply_changeset<C>(&self, changeset: C, _cell_meta: Option<CellMeta>) -> Result<String, FlowyError>
|
||||||
where
|
where
|
||||||
C: Into<CellContentChangeset>,
|
C: Into<CellContentChangeset>,
|
||||||
{
|
{
|
||||||
@ -153,13 +152,13 @@ impl CellDataOperation<EncodedCellData<DateCellDataSerde>, DateCellDataSerde> fo
|
|||||||
let time = Some(time.trim().to_uppercase());
|
let time = Some(time.trim().to_uppercase());
|
||||||
let utc = self.utc_date_time_from_timestamp(date_timestamp);
|
let utc = self.utc_date_time_from_timestamp(date_timestamp);
|
||||||
let timestamp = self.timestamp_from_utc_with_time(&utc, &time)?;
|
let timestamp = self.timestamp_from_utc_with_time(&utc, &time)?;
|
||||||
DateCellDataSerde::new(timestamp, time, &self.time_format)
|
DateCellDataSerde::new(timestamp, time)
|
||||||
}
|
}
|
||||||
_ => DateCellDataSerde::from_timestamp(date_timestamp, Some(default_time_str(&self.time_format))),
|
_ => DateCellDataSerde::new(date_timestamp, None),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(cell_data)
|
Ok(cell_data.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,21 +283,16 @@ pub struct DateCellData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Serialize, Deserialize)]
|
#[derive(Default, Serialize, Deserialize)]
|
||||||
pub struct DateCellDataSerde {
|
pub(crate) struct DateCellDataSerde {
|
||||||
pub timestamp: i64,
|
pub timestamp: i64,
|
||||||
|
|
||||||
|
// #[deprecated(since = "0.0.4", note = "No need to same the time that user input")]
|
||||||
pub time: Option<String>,
|
pub time: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DateCellDataSerde {
|
impl DateCellDataSerde {
|
||||||
fn new(timestamp: i64, time: Option<String>, time_format: &TimeFormat) -> Self {
|
pub(crate) fn new(timestamp: i64, _time: Option<String>) -> Self {
|
||||||
Self {
|
Self { timestamp, time: None }
|
||||||
timestamp,
|
|
||||||
time: Some(time.unwrap_or_else(|| default_time_str(time_format))),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn from_timestamp(timestamp: i64, time: Option<String>) -> Self {
|
|
||||||
Self { timestamp, time }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -316,13 +310,6 @@ impl ToString for DateCellDataSerde {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_time_str(time_format: &TimeFormat) -> String {
|
|
||||||
match time_format {
|
|
||||||
TimeFormat::TwelveHour => "12:00 AM".to_string(),
|
|
||||||
TimeFormat::TwentyFourHour => "00:00".to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, ProtoBuf)]
|
#[derive(Clone, Debug, Default, ProtoBuf)]
|
||||||
pub struct DateChangesetPayload {
|
pub struct DateChangesetPayload {
|
||||||
#[pb(index = 1)]
|
#[pb(index = 1)]
|
||||||
@ -403,11 +390,11 @@ mod tests {
|
|||||||
DateCellContentChangeset, DateCellData, DateCellDataSerde, DateFormat, DateTypeOption, TimeFormat,
|
DateCellContentChangeset, DateCellData, DateCellDataSerde, DateFormat, DateTypeOption, TimeFormat,
|
||||||
};
|
};
|
||||||
use crate::services::row::{CellDataOperation, EncodedCellData};
|
use crate::services::row::{CellDataOperation, EncodedCellData};
|
||||||
use flowy_grid_data_model::entities::{FieldMeta, FieldType};
|
use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntry};
|
||||||
use strum::IntoEnumIterator;
|
use strum::IntoEnumIterator;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn date_description_invalid_input_test() {
|
fn date_type_option_invalid_input_test() {
|
||||||
let type_option = DateTypeOption::default();
|
let type_option = DateTypeOption::default();
|
||||||
let field_type = FieldType::DateTime;
|
let field_type = FieldType::DateTime;
|
||||||
let field_meta = FieldBuilder::from_field_type(&field_type).build();
|
let field_meta = FieldBuilder::from_field_type(&field_type).build();
|
||||||
@ -424,7 +411,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn date_description_date_format_test() {
|
fn date_type_option_date_format_test() {
|
||||||
let mut type_option = DateTypeOption::default();
|
let mut type_option = DateTypeOption::default();
|
||||||
let field_meta = FieldBuilder::from_field_type(&FieldType::DateTime).build();
|
let field_meta = FieldBuilder::from_field_type(&FieldType::DateTime).build();
|
||||||
for date_format in DateFormat::iter() {
|
for date_format in DateFormat::iter() {
|
||||||
@ -447,7 +434,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn date_description_time_format_test() {
|
fn date_type_option_time_format_test() {
|
||||||
let mut type_option = DateTypeOption::default();
|
let mut type_option = DateTypeOption::default();
|
||||||
let field_type = FieldType::DateTime;
|
let field_type = FieldType::DateTime;
|
||||||
let field_meta = FieldBuilder::from_field_type(&field_type).build();
|
let field_meta = FieldBuilder::from_field_type(&field_type).build();
|
||||||
@ -465,7 +452,7 @@ mod tests {
|
|||||||
},
|
},
|
||||||
&field_type,
|
&field_type,
|
||||||
&field_meta,
|
&field_meta,
|
||||||
"May 27,2022 00:00",
|
"May 27,2022",
|
||||||
);
|
);
|
||||||
assert_changeset_result(
|
assert_changeset_result(
|
||||||
&type_option,
|
&type_option,
|
||||||
@ -487,9 +474,9 @@ mod tests {
|
|||||||
},
|
},
|
||||||
&field_type,
|
&field_type,
|
||||||
&field_meta,
|
&field_meta,
|
||||||
"May 27,2022 12:00 AM",
|
"May 27,2022",
|
||||||
);
|
);
|
||||||
|
//
|
||||||
assert_changeset_result(
|
assert_changeset_result(
|
||||||
&type_option,
|
&type_option,
|
||||||
DateCellContentChangeset {
|
DateCellContentChangeset {
|
||||||
@ -517,8 +504,8 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn date_description_apply_changeset_test() {
|
fn date_type_option_apply_changeset_test() {
|
||||||
let mut type_option = DateTypeOption::default();
|
let mut type_option = DateTypeOption::new();
|
||||||
let field_type = FieldType::DateTime;
|
let field_type = FieldType::DateTime;
|
||||||
let field_meta = FieldBuilder::from_field_type(&field_type).build();
|
let field_meta = FieldBuilder::from_field_type(&field_type).build();
|
||||||
let date_timestamp = "1653609600".to_owned();
|
let date_timestamp = "1653609600".to_owned();
|
||||||
@ -543,7 +530,7 @@ mod tests {
|
|||||||
},
|
},
|
||||||
&field_type,
|
&field_type,
|
||||||
&field_meta,
|
&field_meta,
|
||||||
"May 27,2022 00:00",
|
"May 27,2022",
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_changeset_result(
|
assert_changeset_result(
|
||||||
@ -572,30 +559,53 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn date_description_apply_changeset_error_test() {
|
fn date_type_option_apply_changeset_error_test() {
|
||||||
let mut type_option = DateTypeOption::default();
|
let mut type_option = DateTypeOption::new();
|
||||||
type_option.include_time = true;
|
type_option.include_time = true;
|
||||||
let _field_meta = FieldBuilder::from_field_type(&FieldType::DateTime).build();
|
let field_meta = FieldBuilder::from_field_type(&type_option.field_type()).build();
|
||||||
let date_timestamp = "1653609600".to_owned();
|
let date_timestamp = "1653609600".to_owned();
|
||||||
|
|
||||||
let changeset = DateCellContentChangeset {
|
assert_changeset_result(
|
||||||
|
&type_option,
|
||||||
|
DateCellContentChangeset {
|
||||||
date: Some(date_timestamp.clone()),
|
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),
|
|
||||||
time: Some("1:".to_owned()),
|
time: Some("1:".to_owned()),
|
||||||
};
|
},
|
||||||
let _ = type_option.apply_changeset(changeset, None).unwrap();
|
&type_option.field_type(),
|
||||||
|
&field_meta,
|
||||||
|
"May 27,2022 01:00",
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_changeset_result(
|
||||||
|
&type_option,
|
||||||
|
DateCellContentChangeset {
|
||||||
|
date: Some(date_timestamp.clone()),
|
||||||
|
time: Some("1:00".to_owned()),
|
||||||
|
},
|
||||||
|
&type_option.field_type(),
|
||||||
|
&field_meta,
|
||||||
|
"May 27,2022 01:00",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn date_description_invalid_data_test() {
|
fn date_type_option_twelve_hours_to_twenty_four_hours() {
|
||||||
let type_option = DateTypeOption::default();
|
let mut type_option = DateTypeOption::new();
|
||||||
type_option.apply_changeset("he", None).unwrap();
|
type_option.include_time = true;
|
||||||
|
let field_meta = FieldBuilder::from_field_type(&type_option.field_type()).build();
|
||||||
|
let date_timestamp = "1653609600".to_owned();
|
||||||
|
|
||||||
|
assert_changeset_result(
|
||||||
|
&type_option,
|
||||||
|
DateCellContentChangeset {
|
||||||
|
date: Some(date_timestamp.clone()),
|
||||||
|
time: Some("1:00 am".to_owned()),
|
||||||
|
},
|
||||||
|
&type_option.field_type(),
|
||||||
|
&field_meta,
|
||||||
|
"May 27,2022 01:00",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assert_changeset_result(
|
fn assert_changeset_result(
|
||||||
@ -605,7 +615,7 @@ mod tests {
|
|||||||
field_meta: &FieldMeta,
|
field_meta: &FieldMeta,
|
||||||
expected: &str,
|
expected: &str,
|
||||||
) {
|
) {
|
||||||
let encoded_data = EncodedCellData(Some(type_option.apply_changeset(changeset, None).unwrap()));
|
let encoded_data = type_option.apply_changeset(changeset, None).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
expected.to_owned(),
|
expected.to_owned(),
|
||||||
decode_cell_data(encoded_data, type_option, field_meta)
|
decode_cell_data(encoded_data, type_option, field_meta)
|
||||||
@ -613,11 +623,19 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn assert_decode_timestamp(timestamp: i64, type_option: &DateTypeOption, field_meta: &FieldMeta, expected: &str) {
|
fn assert_decode_timestamp(timestamp: i64, type_option: &DateTypeOption, field_meta: &FieldMeta, expected: &str) {
|
||||||
let serde_json = DateCellDataSerde { timestamp, time: None }.to_string();
|
let encoded_data = type_option
|
||||||
|
.apply_changeset(
|
||||||
|
DateCellContentChangeset {
|
||||||
|
date: Some(timestamp.to_string()),
|
||||||
|
time: None,
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
expected.to_owned(),
|
expected.to_owned(),
|
||||||
decode_cell_data(serde_json, type_option, field_meta)
|
decode_cell_data(encoded_data, type_option, field_meta)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -626,11 +644,16 @@ mod tests {
|
|||||||
type_option: &DateTypeOption,
|
type_option: &DateTypeOption,
|
||||||
field_meta: &FieldMeta,
|
field_meta: &FieldMeta,
|
||||||
) -> String {
|
) -> String {
|
||||||
type_option
|
let decoded_data = type_option
|
||||||
.decode_cell_data(encoded_data, &FieldType::DateTime, field_meta)
|
.decode_cell_data(encoded_data, &FieldType::DateTime, field_meta)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.parse::<DateCellData>()
|
.parse::<DateCellData>()
|
||||||
.unwrap()
|
.unwrap();
|
||||||
.date
|
|
||||||
|
if type_option.include_time {
|
||||||
|
format!("{}{}", decoded_data.date, decoded_data.time)
|
||||||
|
} else {
|
||||||
|
format!("{}", decoded_data.date)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ pub struct NumberTypeOption {
|
|||||||
}
|
}
|
||||||
impl_type_option!(NumberTypeOption, FieldType::Number);
|
impl_type_option!(NumberTypeOption, FieldType::Number);
|
||||||
|
|
||||||
impl CellDataOperation<String, String> for NumberTypeOption {
|
impl CellDataOperation<String> for NumberTypeOption {
|
||||||
fn decode_cell_data<T>(
|
fn decode_cell_data<T>(
|
||||||
&self,
|
&self,
|
||||||
encoded_data: T,
|
encoded_data: T,
|
||||||
|
@ -95,7 +95,7 @@ impl SelectOptionOperation for SingleSelectTypeOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CellDataOperation<String, String> for SingleSelectTypeOption {
|
impl CellDataOperation<String> for SingleSelectTypeOption {
|
||||||
fn decode_cell_data<T>(
|
fn decode_cell_data<T>(
|
||||||
&self,
|
&self,
|
||||||
encoded_data: T,
|
encoded_data: T,
|
||||||
@ -193,7 +193,7 @@ impl SelectOptionOperation for MultiSelectTypeOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CellDataOperation<String, String> for MultiSelectTypeOption {
|
impl CellDataOperation<String> for MultiSelectTypeOption {
|
||||||
fn decode_cell_data<T>(
|
fn decode_cell_data<T>(
|
||||||
&self,
|
&self,
|
||||||
encoded_data: T,
|
encoded_data: T,
|
||||||
|
@ -31,7 +31,7 @@ pub struct RichTextTypeOption {
|
|||||||
}
|
}
|
||||||
impl_type_option!(RichTextTypeOption, FieldType::RichText);
|
impl_type_option!(RichTextTypeOption, FieldType::RichText);
|
||||||
|
|
||||||
impl CellDataOperation<String, String> for RichTextTypeOption {
|
impl CellDataOperation<String> for RichTextTypeOption {
|
||||||
fn decode_cell_data<T>(
|
fn decode_cell_data<T>(
|
||||||
&self,
|
&self,
|
||||||
encoded_data: T,
|
encoded_data: T,
|
||||||
@ -80,7 +80,7 @@ mod tests {
|
|||||||
// date
|
// date
|
||||||
let field_type = FieldType::DateTime;
|
let field_type = FieldType::DateTime;
|
||||||
let date_time_field_meta = FieldBuilder::from_field_type(&field_type).build();
|
let date_time_field_meta = FieldBuilder::from_field_type(&field_type).build();
|
||||||
let json = serde_json::to_string(&DateCellDataSerde::from_timestamp(1647251762, None)).unwrap();
|
let json = serde_json::to_string(&DateCellDataSerde::new(1647251762, None)).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
type_option
|
type_option
|
||||||
.decode_cell_data(json, &field_type, &date_time_field_meta)
|
.decode_cell_data(json, &field_type, &date_time_field_meta)
|
||||||
|
@ -34,7 +34,7 @@ pub struct URLTypeOption {
|
|||||||
}
|
}
|
||||||
impl_type_option!(URLTypeOption, FieldType::URL);
|
impl_type_option!(URLTypeOption, FieldType::URL);
|
||||||
|
|
||||||
impl CellDataOperation<EncodedCellData<URLCellData>, String> for URLTypeOption {
|
impl CellDataOperation<EncodedCellData<URLCellData>> for URLTypeOption {
|
||||||
fn decode_cell_data<T>(
|
fn decode_cell_data<T>(
|
||||||
&self,
|
&self,
|
||||||
encoded_data: T,
|
encoded_data: T,
|
||||||
|
@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
use std::fmt::Formatter;
|
use std::fmt::Formatter;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
pub trait CellDataOperation<D, CO: ToString> {
|
pub trait CellDataOperation<ED> {
|
||||||
fn decode_cell_data<T>(
|
fn decode_cell_data<T>(
|
||||||
&self,
|
&self,
|
||||||
encoded_data: T,
|
encoded_data: T,
|
||||||
@ -14,14 +14,14 @@ pub trait CellDataOperation<D, CO: ToString> {
|
|||||||
field_meta: &FieldMeta,
|
field_meta: &FieldMeta,
|
||||||
) -> FlowyResult<DecodedCellData>
|
) -> FlowyResult<DecodedCellData>
|
||||||
where
|
where
|
||||||
T: Into<D>;
|
T: Into<ED>;
|
||||||
|
|
||||||
//
|
//
|
||||||
fn apply_changeset<C: Into<CellContentChangeset>>(
|
fn apply_changeset<C: Into<CellContentChangeset>>(
|
||||||
&self,
|
&self,
|
||||||
changeset: C,
|
changeset: C,
|
||||||
cell_meta: Option<CellMeta>,
|
cell_meta: Option<CellMeta>,
|
||||||
) -> FlowyResult<CO>;
|
) -> FlowyResult<String>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -128,9 +128,7 @@ pub fn apply_cell_data_changeset<T: Into<CellContentChangeset>>(
|
|||||||
let s = match field_meta.field_type {
|
let s = match field_meta.field_type {
|
||||||
FieldType::RichText => RichTextTypeOption::from(field_meta).apply_changeset(changeset, cell_meta),
|
FieldType::RichText => RichTextTypeOption::from(field_meta).apply_changeset(changeset, cell_meta),
|
||||||
FieldType::Number => NumberTypeOption::from(field_meta).apply_changeset(changeset, cell_meta),
|
FieldType::Number => NumberTypeOption::from(field_meta).apply_changeset(changeset, cell_meta),
|
||||||
FieldType::DateTime => DateTypeOption::from(field_meta)
|
FieldType::DateTime => DateTypeOption::from(field_meta).apply_changeset(changeset, cell_meta),
|
||||||
.apply_changeset(changeset, cell_meta)
|
|
||||||
.map(|data| data.to_string()),
|
|
||||||
FieldType::SingleSelect => SingleSelectTypeOption::from(field_meta).apply_changeset(changeset, cell_meta),
|
FieldType::SingleSelect => SingleSelectTypeOption::from(field_meta).apply_changeset(changeset, cell_meta),
|
||||||
FieldType::MultiSelect => MultiSelectTypeOption::from(field_meta).apply_changeset(changeset, cell_meta),
|
FieldType::MultiSelect => MultiSelectTypeOption::from(field_meta).apply_changeset(changeset, cell_meta),
|
||||||
FieldType::Checkbox => CheckboxTypeOption::from(field_meta).apply_changeset(changeset, cell_meta),
|
FieldType::Checkbox => CheckboxTypeOption::from(field_meta).apply_changeset(changeset, cell_meta),
|
||||||
|
Loading…
Reference in New Issue
Block a user