mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: enable sort by date + sort fix (#2953)
This commit is contained in:
@ -143,4 +143,8 @@ impl TypeOptionCellDataCompare for CheckboxTypeOption {
|
||||
(false, false) => default_order(),
|
||||
}
|
||||
}
|
||||
|
||||
fn exempt_from_cmp(&self, _: &<Self as TypeOption>::CellData) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
@ -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 {}
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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)]
|
||||
|
@ -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)]
|
||||
|
@ -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)]
|
||||
|
@ -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>>(
|
||||
|
@ -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 {
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user