feat: enable sort by date + sort fix (#2953)

This commit is contained in:
Richard Shiue
2023-07-21 15:51:20 +08:00
committed by GitHub
parent b1378b4545
commit c368d855c7
16 changed files with 178 additions and 101 deletions

View File

@ -143,4 +143,8 @@ impl TypeOptionCellDataCompare for CheckboxTypeOption {
(false, false) => default_order(),
}
}
fn exempt_from_cmp(&self, _: &<Self as TypeOption>::CellData) -> bool {
false
}
}

View File

@ -202,6 +202,10 @@ impl TypeOptionCellDataCompare for ChecklistTypeOption {
Ordering::Equal
}
}
fn exempt_from_cmp(&self, cell_data: &<Self as TypeOption>::CellData) -> bool {
cell_data.selected_option_ids.is_empty()
}
}
impl TypeOptionTransform for ChecklistTypeOption {}

View File

@ -302,4 +302,8 @@ impl TypeOptionCellDataCompare for DateTypeOption {
(None, None) => default_order(),
}
}
fn exempt_from_cmp(&self, cell_data: &<Self as TypeOption>::CellData) -> bool {
cell_data.timestamp.is_none()
}
}

View File

@ -260,6 +260,10 @@ impl TypeOptionCellDataCompare for NumberTypeOption {
(Err(_), Err(_)) => Ordering::Equal,
}
}
fn exempt_from_cmp(&self, cell_data: &<Self as TypeOption>::CellData) -> bool {
cell_data.0.is_empty()
}
}
impl std::default::Default for NumberTypeOption {
fn default() -> Self {

View File

@ -162,6 +162,10 @@ impl TypeOptionCellDataCompare for MultiSelectTypeOption {
}
default_order()
}
fn exempt_from_cmp(&self, cell_data: &<Self as TypeOption>::CellData) -> bool {
cell_data.is_empty()
}
}
#[cfg(test)]

View File

@ -146,6 +146,10 @@ impl TypeOptionCellDataCompare for SingleSelectTypeOption {
(None, None) => default_order(),
}
}
fn exempt_from_cmp(&self, cell_data: &<Self as TypeOption>::CellData) -> bool {
cell_data.is_empty()
}
}
#[cfg(test)]

View File

@ -155,6 +155,10 @@ impl TypeOptionCellDataCompare for RichTextTypeOption {
) -> Ordering {
cell_data.0.cmp(&other_cell_data.0)
}
fn exempt_from_cmp(&self, cell_data: &<Self as TypeOption>::CellData) -> bool {
cell_data.0.trim().is_empty()
}
}
#[derive(Clone)]

View File

@ -132,6 +132,8 @@ pub trait TypeOptionCellDataCompare: TypeOption {
cell_data: &<Self as TypeOption>::CellData,
other_cell_data: &<Self as TypeOption>::CellData,
) -> Ordering;
fn exempt_from_cmp(&self, cell_data: &<Self as TypeOption>::CellData) -> bool;
}
pub fn type_option_data_from_pb_or_default<T: Into<Bytes>>(

View File

@ -19,6 +19,7 @@ use crate::services::field::{
SingleSelectTypeOption, TypeOption, TypeOptionCellData, TypeOptionCellDataCompare,
TypeOptionCellDataFilter, TypeOptionTransform, URLTypeOption,
};
use crate::services::sort::SortCondition;
pub const CELL_DATA: &str = "data";
@ -45,7 +46,13 @@ pub trait TypeOptionCellDataHandler: Send + Sync + 'static {
field: &Field,
) -> FlowyResult<Cell>;
fn handle_cell_compare(&self, left_cell: &Cell, right_cell: &Cell, field: &Field) -> Ordering;
fn handle_cell_compare(
&self,
left_cell: &Cell,
right_cell: &Cell,
field: &Field,
sort_condition: SortCondition,
) -> Ordering;
fn handle_cell_filter(&self, field_type: &FieldType, field: &Field, cell: &Cell) -> bool;
@ -234,7 +241,13 @@ where
Ok(cell)
}
fn handle_cell_compare(&self, left_cell: &Cell, right_cell: &Cell, field: &Field) -> Ordering {
fn handle_cell_compare(
&self,
left_cell: &Cell,
right_cell: &Cell,
field: &Field,
sort_condition: SortCondition,
) -> Ordering {
let field_type = FieldType::from(field.field_type);
let left = self
.get_decoded_cell_data(left_cell, &field_type, field)
@ -242,7 +255,20 @@ where
let right = self
.get_decoded_cell_data(right_cell, &field_type, field)
.unwrap_or_default();
self.apply_cmp(&left, &right)
match (self.exempt_from_cmp(&left), self.exempt_from_cmp(&right)) {
(true, true) => Ordering::Equal,
(true, false) => Ordering::Greater,
(false, true) => Ordering::Less,
(false, false) => {
let order = self.apply_cmp(&left, &right);
// The order is calculated by Ascending. So reverse the order if the SortCondition is descending.
match sort_condition {
SortCondition::Ascending => order,
SortCondition::Descending => order.reverse(),
}
},
}
}
fn handle_cell_filter(&self, field_type: &FieldType, field: &Field, cell: &Cell) -> bool {

View File

@ -126,7 +126,12 @@ impl TypeOptionCellDataCompare for URLTypeOption {
) -> Ordering {
cell_data.data.cmp(&other_cell_data.data)
}
fn exempt_from_cmp(&self, cell_data: &<Self as TypeOption>::CellData) -> bool {
cell_data.data.is_empty()
}
}
fn auto_append_scheme(s: &str) -> String {
// Only support https scheme by now
match url::Url::parse(s) {

View File

@ -156,7 +156,7 @@ impl SortController {
}
let fields = self.delegate.get_fields(&self.view_id, None).await;
for sort in self.sorts.iter() {
for sort in self.sorts.iter().rev() {
rows
.par_sort_by(|left, right| cmp_row(&left.row, &right.row, sort, &fields, &self.cell_cache));
}
@ -240,35 +240,46 @@ fn cmp_row(
fields: &[Arc<Field>],
cell_data_cache: &CellCache,
) -> Ordering {
let order = match (
left.cells.get(&sort.field_id),
right.cells.get(&sort.field_id),
) {
(Some(left_cell), Some(right_cell)) => {
let field_type = sort.field_type.clone();
match fields
.iter()
.find(|field_rev| field_rev.id == sort.field_id)
{
None => default_order(),
Some(field_rev) => cmp_cell(
left_cell,
right_cell,
field_rev,
field_type,
cell_data_cache,
),
}
let field_type = sort.field_type.clone();
match fields
.iter()
.find(|field_rev| field_rev.id == sort.field_id)
{
None => default_order(),
Some(field_rev) => match (
left.cells.get(&sort.field_id),
right.cells.get(&sort.field_id),
) {
(Some(left_cell), Some(right_cell)) => cmp_cell(
left_cell,
right_cell,
field_rev,
field_type,
cell_data_cache,
sort.condition,
),
(Some(_), None) => {
if field_type.is_checkbox() {
match sort.condition {
SortCondition::Ascending => Ordering::Greater,
SortCondition::Descending => Ordering::Less,
}
} else {
Ordering::Less
}
},
(None, Some(_)) => {
if field_type.is_checkbox() {
match sort.condition {
SortCondition::Ascending => Ordering::Less,
SortCondition::Descending => Ordering::Greater,
}
} else {
Ordering::Greater
}
},
_ => default_order(),
},
(Some(_), None) => Ordering::Greater,
(None, Some(_)) => Ordering::Less,
_ => default_order(),
};
// The order is calculated by Ascending. So reverse the order if the SortCondition is descending.
match sort.condition {
SortCondition::Ascending => order,
SortCondition::Descending => order.reverse(),
}
}
@ -278,6 +289,7 @@ fn cmp_cell(
field: &Arc<Field>,
field_type: FieldType,
cell_data_cache: &CellCache,
sort_condition: SortCondition,
) -> Ordering {
match TypeOptionCellExt::new_with_cell_data_cache(field.as_ref(), Some(cell_data_cache.clone()))
.get_type_option_cell_data_handler(&field_type)
@ -285,7 +297,8 @@ fn cmp_cell(
None => default_order(),
Some(handler) => {
let cal_order = || {
let order = handler.handle_cell_compare(left_cell, right_cell, field.as_ref());
let order =
handler.handle_cell_compare(left_cell, right_cell, field.as_ref(), sort_condition);
Option::<Ordering>::Some(order)
};