fix: grid filters (#6317)

This commit is contained in:
Richard Shiue 2024-09-16 17:34:02 +08:00 committed by GitHub
parent d67d77f442
commit 710e894446
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 69 additions and 108 deletions

View File

@ -1,4 +1,4 @@
use crate::entities::{DatabaseSyncStatePB, DidFetchRowPB, InsertedRowPB, RowMetaPB, RowsChangePB};
use crate::entities::{DatabaseSyncStatePB, DidFetchRowPB, RowsChangePB};
use crate::notification::{send_notification, DatabaseNotification, DATABASE_OBSERVABLE_SOURCE};
use crate::services::database::{DatabaseEditor, UpdatedRow};
use crate::services::database_view::DatabaseViewEditor;
@ -189,7 +189,7 @@ async fn handle_did_update_row_orders(
// Delete row: Next, we delete a from its original position at index 0.
// Delete row indexes: [0]
// Final state after delete: [b, a, c]
let database_view_rows = DashMap::new();
let row_changes = DashMap::new();
// 1. handle insert row orders
for (row_order, index) in insert_row_orders {
if let Err(err) = database_editor.init_database_row(&row_order.id).await {
@ -204,7 +204,7 @@ async fn handle_did_update_row_orders(
is_local_change
);
// insert row order
// insert row order in database view cache
{
let mut view_row_orders = database_view.row_orders.write().await;
if view_row_orders.len() >= index as usize {
@ -219,26 +219,17 @@ async fn handle_did_update_row_orders(
}
let is_move_row = is_move_row(&database_view, &row_order, &delete_row_indexes).await;
if let Some(row) = database_editor
.get_row(&database_view.view_id, &row_order.id)
.await
{
database_view
.v_did_create_row(&row, index, is_move_row, is_local_change)
.await;
}
// gather changes for notification
if let Some((index, row_detail)) = database_view.v_get_row(&row_order.id).await {
database_view_rows
.entry(database_view.view_id.clone())
.or_insert_with(|| {
let mut change = RowsChangePB::new();
change.is_move_row = is_move_row;
change
})
.inserted_rows
.push(InsertedRowPB::new(RowMetaPB::from(row_detail.as_ref())).with_index(index as i32));
database_view
.v_did_create_row(
&row_detail,
index as u32,
is_move_row,
is_local_change,
&row_changes,
)
.await;
}
}
}
@ -252,7 +243,7 @@ async fn handle_did_update_row_orders(
let lazy_row = view_row_orders.remove(index);
// Update changeset in RowsChangePB
let row_id = lazy_row.id.to_string();
let mut row_change = database_view_rows
let mut row_change = row_changes
.entry(database_view.view_id.clone())
.or_default();
row_change.deleted_rows.push(row_id);
@ -283,7 +274,7 @@ async fn handle_did_update_row_orders(
}
// 3. notify the view
for entry in database_view_rows.into_iter() {
for entry in row_changes.into_iter() {
let (view_id, changes) = entry;
trace!("[RowOrder]: {}", changes);
send_notification(&view_id, DatabaseNotification::DidUpdateRow)

View File

@ -1,12 +1,12 @@
#![allow(clippy::while_let_loop)]
use crate::entities::{
CalculationChangesetNotificationPB, DatabaseViewSettingPB, FilterChangesetNotificationPB,
GroupChangesPB, GroupRowsNotificationPB, InsertedRowPB, ReorderAllRowsPB, ReorderSingleRowPB,
RowMetaPB, RowsChangePB, RowsVisibilityChangePB, SortChangesetNotificationPB,
GroupChangesPB, GroupRowsNotificationPB, ReorderAllRowsPB, ReorderSingleRowPB,
RowsVisibilityChangePB, SortChangesetNotificationPB,
};
use crate::notification::{send_notification, DatabaseNotification};
use crate::services::filter::FilterResultNotification;
use crate::services::sort::{InsertRowResult, ReorderAllRowsResult, ReorderSingleRowResult};
use crate::services::sort::{ReorderAllRowsResult, ReorderSingleRowResult};
use async_stream::stream;
use futures::stream::StreamExt;
use tokio::sync::broadcast;
@ -16,7 +16,6 @@ pub enum DatabaseViewChanged {
FilterNotification(FilterResultNotification),
ReorderAllRowsNotification(ReorderAllRowsResult),
ReorderSingleRowNotification(ReorderSingleRowResult),
InsertRowNotification(InsertRowResult),
CalculationValueNotification(CalculationChangesetNotificationPB),
}
@ -79,17 +78,6 @@ impl DatabaseViewChangedReceiverRunner {
.payload(reorder_row)
.send()
},
DatabaseViewChanged::InsertRowNotification(result) => {
let inserted_row = InsertedRowPB {
row_meta: RowMetaPB::from(result.row),
index: Some(result.index as i32),
is_new: true,
};
let changes = RowsChangePB::from_insert(inserted_row);
send_notification(&result.view_id, DatabaseNotification::DidUpdateRow)
.payload(changes)
.send();
},
DatabaseViewChanged::CalculationValueNotification(notification) => send_notification(
&notification.view_id,
DatabaseNotification::DidUpdateCalculation,

View File

@ -6,7 +6,7 @@ use super::notify_did_update_calculation;
use crate::entities::{
CalendarEventPB, CreateRowParams, CreateRowPayloadPB, DatabaseLayoutMetaPB,
DatabaseLayoutSettingPB, DeleteSortPayloadPB, FieldSettingsChangesetPB, FieldType,
GroupChangesPB, GroupPB, LayoutSettingChangeset, LayoutSettingParams,
GroupChangesPB, GroupPB, InsertedRowPB, LayoutSettingChangeset, LayoutSettingParams,
RemoveCalculationChangesetPB, ReorderSortPayloadPB, RowMetaPB, RowsChangePB,
SortChangesetNotificationPB, SortPB, UpdateCalculationChangesetPB, UpdateSortPayloadPB,
};
@ -208,27 +208,41 @@ impl DatabaseViewEditor {
pub async fn v_did_create_row(
&self,
row: &Row,
row_detail: &RowDetail,
index: u32,
is_move_row: bool,
is_local_change: bool,
_is_move_row: bool,
_is_local_change: bool,
row_changes: &DashMap<String, RowsChangePB>,
) {
// Send the group notification if the current view has groups
if !is_move_row || !is_local_change {
if let Some(controller) = self.group_controller.write().await.as_mut() {
let rows = vec![Arc::new(row.clone())];
let mut rows = self.v_filter_rows(rows).await;
if let Some(row) = rows.pop() {
let changesets = controller.did_create_row(&row, index as usize);
for changeset in changesets {
notify_did_update_group_rows(changeset).await;
}
if let Some(controller) = self.group_controller.write().await.as_mut() {
let rows = vec![Arc::new(row_detail.row.clone())];
let mut rows = self.v_filter_rows(rows).await;
if let Some(row) = rows.pop() {
let changesets = controller.did_create_row(&row, index as usize);
for changeset in changesets {
notify_did_update_group_rows(changeset).await;
}
}
}
self.gen_did_create_row_view_tasks(index, row.clone()).await;
if let Some(index) = self
.sort_controller
.write()
.await
.did_create_row(&row_detail.row)
.await
{
row_changes
.entry(self.view_id.clone())
.or_default()
.inserted_rows
.push(InsertedRowPB::new(RowMetaPB::from(row_detail)).with_index(index as i32));
};
self
.gen_did_create_row_view_tasks(row_detail.row.clone())
.await;
}
#[tracing::instrument(level = "trace", skip_all)]
@ -1190,18 +1204,9 @@ impl DatabaseViewEditor {
});
}
async fn gen_did_create_row_view_tasks(&self, preliminary_index: u32, row: Row) {
let weak_sort_controller = Arc::downgrade(&self.sort_controller);
async fn gen_did_create_row_view_tasks(&self, row: Row) {
let weak_calculations_controller = Arc::downgrade(&self.calculations_controller);
tokio::spawn(async move {
if let Some(sort_controller) = weak_sort_controller.upgrade() {
sort_controller
.read()
.await
.did_create_row(preliminary_index, &row)
.await;
}
if let Some(calculations_controller) = weak_calculations_controller.upgrade() {
calculations_controller
.did_receive_row_changed(row.clone())

View File

@ -21,7 +21,7 @@ use crate::services::field::{
default_order, TimestampCellData, TimestampCellDataWrapper, TypeOptionCellExt,
};
use crate::services::sort::{
InsertRowResult, ReorderAllRowsResult, ReorderSingleRowResult, Sort, SortChangeset, SortCondition,
ReorderAllRowsResult, ReorderSingleRowResult, Sort, SortChangeset, SortCondition,
};
#[async_trait]
@ -99,27 +99,31 @@ impl SortController {
}
}
pub async fn did_create_row(&self, preliminary_index: u32, row: &Row) {
pub async fn did_create_row(&mut self, row: &Row) -> Option<u32> {
if !self.delegate.filter_row(row).await {
return;
return None;
}
if !self.sorts.is_empty() {
self
.gen_task(
SortEvent::NewRowInserted(row.clone()),
QualityOfService::Background,
)
.await;
let mut rows = self.delegate.get_rows(&self.view_id).await;
self.sort_rows(&mut rows).await;
let row_index = self
.row_index_cache
.get(&row.id)
.cloned()
.map(|val| val as u32);
if row_index.is_none() {
tracing::trace!("The row index cache is outdated");
}
row_index
} else {
let result = InsertRowResult {
view_id: self.view_id.clone(),
row: row.clone(),
index: preliminary_index,
};
let _ = self
.notifier
.send(DatabaseViewChanged::InsertRowNotification(result));
let rows = self.delegate.get_rows(&self.view_id).await;
rows
.iter()
.position(|val| val.id == row.id)
.map(|val| val as u32)
}
}
@ -164,24 +168,6 @@ impl SortController {
_ => tracing::trace!("The row index cache is outdated"),
}
},
SortEvent::NewRowInserted(row) => {
self.sort_rows(&mut rows).await;
let row_index = self.row_index_cache.get(&row.id).cloned();
match row_index {
Some(row_index) => {
let notification = InsertRowResult {
view_id: self.view_id.clone(),
row: row.clone(),
index: row_index as u32,
};
self.row_index_cache.insert(row.id, row_index);
let _ = self
.notifier
.send(DatabaseViewChanged::InsertRowNotification(notification));
},
_ => tracing::trace!("The row index cache is outdated"),
}
},
}
Ok(())
}
@ -363,7 +349,6 @@ fn cmp_cell(
enum SortEvent {
SortDidChanged,
RowDidChanged(RowId),
NewRowInserted(Row),
DeleteAllSorts,
}

View File

@ -3,7 +3,7 @@ use std::cmp::Ordering;
use anyhow::bail;
use collab::preclude::Any;
use collab::util::AnyMapExt;
use collab_database::rows::{Row, RowId};
use collab_database::rows::RowId;
use collab_database::views::{SortMap, SortMapBuilder};
#[derive(Debug, Clone)]
@ -110,13 +110,6 @@ pub struct ReorderSingleRowResult {
pub new_index: usize,
}
#[derive(Clone)]
pub struct InsertRowResult {
pub view_id: String,
pub row: Row,
pub index: u32,
}
#[derive(Debug, Default)]
pub struct SortChangeset {
pub(crate) insert_sort: Option<Sort>,

View File

@ -232,7 +232,6 @@ async fn assert_sort_changed(
old_row_orders.insert(changed.new_index, old);
assert_eq!(old_row_orders, new_row_orders);
},
DatabaseViewChanged::InsertRowNotification(_changed) => {},
_ => {},
}
})