fix: disappearing sorts (#4691)

* chore: copy the field type

* chore: don't store field type in Sort

* fix: sorts disappearing
This commit is contained in:
Richard Shiue 2024-02-21 20:01:57 +08:00 committed by GitHub
parent 58aa73b5be
commit 34fb1bcfa4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 43 additions and 61 deletions

View File

@ -289,7 +289,7 @@ class FieldController {
final fieldInfo = _findFieldInfo(
fieldInfos: fieldInfos,
fieldId: newSortPB.sort.fieldId,
fieldType: newSortPB.sort.fieldType,
fieldType: null,
);
if (fieldInfo != null) {
@ -318,7 +318,7 @@ class FieldController {
final fieldInfo = _findFieldInfo(
fieldInfos: fieldInfos,
fieldId: updatedSort.fieldId,
fieldType: updatedSort.fieldType,
fieldType: null,
);
if (fieldInfo != null) {
@ -688,7 +688,7 @@ class FieldController {
final fieldInfo = _findFieldInfo(
fieldInfos: fieldInfos,
fieldId: sortPB.fieldId,
fieldType: sortPB.fieldType,
fieldType: null,
);
return fieldInfo != null
? SortInfo(sortPB: sortPB, fieldInfo: fieldInfo)
@ -847,9 +847,11 @@ class RowCacheDependenciesImpl extends RowFieldsDelegate with RowLifeCycle {
FieldInfo? _findFieldInfo({
required List<FieldInfo> fieldInfos,
required String fieldId,
required FieldType fieldType,
required FieldType? fieldType,
}) {
return fieldInfos.firstWhereOrNull(
(element) => element.id == fieldId && element.fieldType == fieldType,
(element) =>
element.id == fieldId &&
(fieldType == null || element.fieldType == fieldType),
);
}

View File

@ -31,7 +31,6 @@ class SortBackendService {
}) {
final insertSortPayload = UpdateSortPayloadPB.create()
..fieldId = fieldId
..fieldType = fieldType
..viewId = viewId
..condition = condition
..sortId = sortId;
@ -57,7 +56,6 @@ class SortBackendService {
}) {
final insertSortPayload = UpdateSortPayloadPB.create()
..fieldId = fieldId
..fieldType = fieldType
..viewId = viewId
..condition = condition;

View File

@ -24,7 +24,6 @@ export async function insertSort(viewId: string, sort: Omit<Sort, 'id'>): Promis
update_sort: {
view_id: viewId,
field_id: sort.fieldId,
field_type: sort.fieldType,
condition: sort.condition,
},
});
@ -41,7 +40,6 @@ export async function updateSort(viewId: string, sort: Sort): Promise<void> {
view_id: viewId,
sort_id: sort.id,
field_id: sort.fieldId,
field_type: sort.fieldType,
condition: sort.condition,
},
});

View File

@ -1,9 +1,8 @@
import { FieldType, SortConditionPB, SortPB } from '@/services/backend';
import { SortConditionPB, SortPB } from '@/services/backend';
export interface Sort {
id: string;
fieldId: string;
fieldType: FieldType;
condition: SortConditionPB;
}
@ -11,7 +10,6 @@ export function pbToSort(pb: SortPB): Sort {
return {
id: pb.id,
fieldId: pb.field_id,
fieldType: pb.field_type,
condition: pb.condition,
};
}

View File

@ -18,7 +18,6 @@ const SortFieldsMenu: FC<
async (event: MouseEvent, field: Field) => {
await sortService.insertSort(viewId, {
fieldId: field.id,
fieldType: field.type,
condition: SortConditionPB.Ascending,
});
props.onClose?.({}, 'backdropClick');

View File

@ -21,7 +21,6 @@ export const SortItem: FC<SortItemProps> = ({ className, sort }) => {
void sortService.updateSort(viewId, {
...sort,
fieldId: field.id,
fieldType: field.type,
});
}
},

View File

@ -46,7 +46,7 @@ impl FieldPB {
let field_type = field.field_type.into();
let type_option = field
.get_any_type_option(field_type)
.unwrap_or_else(|| default_type_option_data_from_type(&field_type));
.unwrap_or_else(|| default_type_option_data_from_type(field_type));
Self {
id: field.id,
name: field.name,

View File

@ -1,7 +1,6 @@
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use validator::Validate;
use crate::entities::FieldType;
use crate::services::sort::{Sort, SortCondition};
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
@ -13,9 +12,6 @@ pub struct SortPB {
pub field_id: String,
#[pb(index = 3)]
pub field_type: FieldType,
#[pb(index = 4)]
pub condition: SortConditionPB,
}
@ -24,7 +20,6 @@ impl std::convert::From<&Sort> for SortPB {
Self {
id: sort.id.clone(),
field_id: sort.field_id.clone(),
field_type: sort.field_type,
condition: sort.condition.into(),
}
}
@ -35,7 +30,6 @@ impl std::convert::From<Sort> for SortPB {
Self {
id: sort.id,
field_id: sort.field_id,
field_type: sort.field_type,
condition: sort.condition.into(),
}
}
@ -109,15 +103,12 @@ pub struct UpdateSortPayloadPB {
#[validate(custom = "lib_infra::validator_fn::required_not_empty_str")]
pub field_id: String,
#[pb(index = 3)]
pub field_type: FieldType,
/// Create a new sort if the sort_id is None
#[pb(index = 4, one_of)]
#[pb(index = 3, one_of)]
#[validate(custom = "super::utils::validate_sort_id")]
pub sort_id: Option<String>,
#[pb(index = 5)]
#[pb(index = 4)]
pub condition: SortConditionPB,
}

View File

@ -254,7 +254,7 @@ pub(crate) async fn switch_to_field_handler(
let database_editor = manager.get_database_with_view_id(&params.view_id).await?;
let old_field = database_editor.get_field(&params.field_id);
database_editor
.switch_to_field_type(&params.field_id, &params.field_type)
.switch_to_field_type(&params.field_id, params.field_type)
.await?;
if let Some(new_type_option) = database_editor

View File

@ -373,7 +373,7 @@ impl DatabaseEditor {
pub async fn switch_to_field_type(
&self,
field_id: &str,
new_field_type: &FieldType,
new_field_type: FieldType,
) -> FlowyResult<()> {
let field = self.database.lock().fields.get_field(field_id);
match field {
@ -531,7 +531,7 @@ impl DatabaseEditor {
let type_option_data = params
.type_option_data
.and_then(|data| type_option_data_from_pb(data, &params.field_type).ok())
.unwrap_or(default_type_option_data_from_type(&params.field_type));
.unwrap_or(default_type_option_data_from_type(params.field_type));
let (index, field) = self.database.lock().create_field_with_mut(
&params.view_id,

View File

@ -491,7 +491,6 @@ impl DatabaseViewEditor {
let sort = Sort {
id: sort_id,
field_id: params.field_id.clone(),
field_type: params.field_type,
condition: params.condition.into(),
};
@ -791,10 +790,16 @@ impl DatabaseViewEditor {
.await;
}
pub async fn v_did_update_field_type(&self, field_id: &str, new_field_type: &FieldType) {
pub async fn v_did_update_field_type(&self, field_id: &str, new_field_type: FieldType) {
self
.sort_controller
.read()
.await
.did_update_field_type()
.await;
self
.calculations_controller
.did_receive_field_type_changed(field_id.to_owned(), new_field_type.to_owned())
.did_receive_field_type_changed(field_id.to_owned(), new_field_type)
.await;
}

View File

@ -18,7 +18,7 @@ impl FieldBuilder {
}
pub fn from_field_type(field_type: FieldType) -> Self {
let type_option_data = default_type_option_data_from_type(&field_type);
let type_option_data = default_type_option_data_from_type(field_type);
Self::new(field_type, type_option_data)
}

View File

@ -264,13 +264,13 @@ pub fn type_option_to_pb(type_option: TypeOptionData, field_type: &FieldType) ->
}
}
pub fn default_type_option_data_from_type(field_type: &FieldType) -> TypeOptionData {
pub fn default_type_option_data_from_type(field_type: FieldType) -> TypeOptionData {
match field_type {
FieldType::RichText => RichTextTypeOption::default().into(),
FieldType::Number => NumberTypeOption::default().into(),
FieldType::DateTime => DateTypeOption::default().into(),
FieldType::LastEditedTime | FieldType::CreatedTime => TimestampTypeOption {
field_type: *field_type,
field_type,
include_time: true,
..Default::default()
}

View File

@ -496,7 +496,7 @@ impl<'a> TypeOptionCellExt<'a> {
pub fn transform_type_option(
type_option_data: &TypeOptionData,
new_field_type: &FieldType,
new_field_type: FieldType,
old_type_option_data: Option<TypeOptionData>,
old_field_type: FieldType,
) -> TypeOptionData {
@ -538,7 +538,7 @@ where
}
fn get_type_option_transform_handler(
type_option_data: &TypeOptionData,
field_type: &FieldType,
field_type: FieldType,
) -> Box<dyn TypeOptionTransformHandler> {
let type_option_data = type_option_data.clone();
match field_type {

View File

@ -82,7 +82,7 @@ where
let field_type = FieldType::from(grouping_field.field_type);
let type_option = grouping_field
.get_type_option::<T>(&field_type)
.unwrap_or_else(|| T::from(default_type_option_data_from_type(&field_type)));
.unwrap_or_else(|| T::from(default_type_option_data_from_type(field_type)));
// TODO(nathan): remove block_on
let generated_groups = block_on(G::build(grouping_field, &configuration, &type_option));

View File

@ -143,7 +143,7 @@ fn database_from_fields_and_rows(
fn default_field(field_str: String, is_primary: bool) -> Field {
let field_type = FieldType::RichText;
let type_option_data = default_type_option_data_from_type(&field_type);
let type_option_data = default_type_option_data_from_type(field_type);
Field::new(gen_field_id(), field_str, field_type.into(), is_primary)
.with_type_option_data(field_type, type_option_data)
}

View File

@ -105,6 +105,14 @@ impl SortController {
}
}
pub async fn did_update_field_type(&self) {
if !self.sorts.is_empty() {
self
.gen_task(SortEvent::SortDidChanged, QualityOfService::Background)
.await;
}
}
// #[tracing::instrument(name = "process_sort_task", level = "trace", skip_all, err)]
pub async fn process(&mut self, predicate: &str) -> FlowyResult<()> {
let event_type = SortEvent::from_str(predicate).unwrap();
@ -285,13 +293,13 @@ fn cmp_row(
fields: &[Arc<Field>],
cell_data_cache: &CellCache,
) -> Ordering {
let field_type = sort.field_type;
match fields
.iter()
.find(|field_rev| field_rev.id == sort.field_id)
{
None => default_order(),
Some(field_rev) => {
let field_type = field_rev.field_type.into();
let timestamp_cells = match field_type {
FieldType::LastEditedTime | FieldType::CreatedTime => {
let (left_cell, right_cell) = if field_type.is_created_time() {

View File

@ -5,31 +5,23 @@ use collab::core::any_map::AnyMapExtension;
use collab_database::rows::RowId;
use collab_database::views::{SortMap, SortMapBuilder};
use crate::entities::FieldType;
#[derive(Debug, Clone)]
pub struct Sort {
pub id: String,
pub field_id: String,
pub field_type: FieldType,
pub condition: SortCondition,
}
const SORT_ID: &str = "id";
const FIELD_ID: &str = "field_id";
const FIELD_TYPE: &str = "ty";
const SORT_CONDITION: &str = "condition";
impl TryFrom<SortMap> for Sort {
type Error = anyhow::Error;
fn try_from(value: SortMap) -> Result<Self, Self::Error> {
match (
value.get_str_value(SORT_ID),
value.get_str_value(FIELD_ID),
value.get_i64_value(FIELD_TYPE).map(FieldType::from),
) {
(Some(id), Some(field_id), Some(field_type)) => {
match (value.get_str_value(SORT_ID), value.get_str_value(FIELD_ID)) {
(Some(id), Some(field_id)) => {
let condition = value
.get_i64_value(SORT_CONDITION)
.map(SortCondition::from)
@ -37,7 +29,6 @@ impl TryFrom<SortMap> for Sort {
Ok(Self {
id,
field_id,
field_type,
condition,
})
},
@ -53,15 +44,15 @@ impl From<Sort> for SortMap {
SortMapBuilder::new()
.insert_str_value(SORT_ID, data.id)
.insert_str_value(FIELD_ID, data.field_id)
.insert_i64_value(FIELD_TYPE, data.field_type.into())
.insert_i64_value(SORT_CONDITION, data.condition.value())
.build()
}
}
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, Default)]
#[repr(u8)]
pub enum SortCondition {
#[default]
Ascending = 0,
Descending = 1,
}
@ -82,12 +73,6 @@ impl SortCondition {
}
}
impl Default for SortCondition {
fn default() -> Self {
Self::Ascending
}
}
impl From<i64> for SortCondition {
fn from(value: i64) -> Self {
match value {

View File

@ -87,7 +87,7 @@ impl DatabaseFieldTest {
//
self
.editor
.switch_to_field_type(&field_id, &new_field_type)
.switch_to_field_type(&field_id, new_field_type)
.await
.unwrap();
},

View File

@ -79,7 +79,6 @@ impl DatabaseSortTest {
view_id: self.view_id.clone(),
field_id: field.id.clone(),
sort_id: None,
field_type: FieldType::from(field.field_type),
condition: condition.into(),
};
let _ = self.editor.create_or_update_sort(params).await.unwrap();