mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: config filter service
This commit is contained in:
parent
1b38ff8559
commit
76f260fe04
@ -62,7 +62,6 @@ class GridCell with _$GridCell {
|
||||
required String gridId,
|
||||
required String rowId,
|
||||
required Field field,
|
||||
Cell? cell,
|
||||
}) = _GridCell;
|
||||
|
||||
// ignore: unused_element
|
||||
|
@ -146,7 +146,6 @@ class GridRowCache {
|
||||
cellDataMap[field.id] = GridCell(
|
||||
rowId: rowId,
|
||||
gridId: gridId,
|
||||
cell: row?.cellByFieldId[field.id],
|
||||
field: field,
|
||||
);
|
||||
}
|
||||
|
@ -21,13 +21,15 @@ pub trait GridUser: Send + Sync {
|
||||
fn db_pool(&self) -> Result<Arc<ConnectionPool>, FlowyError>;
|
||||
}
|
||||
|
||||
pub type GridTaskSchedulerRwLock = Arc<RwLock<GridTaskScheduler>>;
|
||||
|
||||
pub struct GridManager {
|
||||
grid_editors: Arc<DashMap<String, Arc<GridRevisionEditor>>>,
|
||||
grid_user: Arc<dyn GridUser>,
|
||||
block_index_cache: Arc<BlockIndexCache>,
|
||||
#[allow(dead_code)]
|
||||
kv_persistence: Arc<GridKVPersistence>,
|
||||
task_scheduler: Arc<RwLock<GridTaskScheduler>>,
|
||||
task_scheduler: GridTaskSchedulerRwLock,
|
||||
}
|
||||
|
||||
impl GridManager {
|
||||
@ -79,18 +81,20 @@ impl GridManager {
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip_all, fields(grid_id), err)]
|
||||
pub fn close_grid<T: AsRef<str>>(&self, grid_id: T) -> FlowyResult<()> {
|
||||
pub async fn close_grid<T: AsRef<str>>(&self, grid_id: T) -> FlowyResult<()> {
|
||||
let grid_id = grid_id.as_ref();
|
||||
tracing::Span::current().record("grid_id", &grid_id);
|
||||
self.grid_editors.remove(grid_id);
|
||||
self.task_scheduler.write().await.unregister_handler(grid_id);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(self, grid_id), fields(doc_id), err)]
|
||||
pub fn delete_grid<T: AsRef<str>>(&self, grid_id: T) -> FlowyResult<()> {
|
||||
pub async fn delete_grid<T: AsRef<str>>(&self, grid_id: T) -> FlowyResult<()> {
|
||||
let grid_id = grid_id.as_ref();
|
||||
tracing::Span::current().record("grid_id", &grid_id);
|
||||
self.grid_editors.remove(grid_id);
|
||||
self.task_scheduler.write().await.unregister_handler(grid_id);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -115,6 +119,7 @@ impl GridManager {
|
||||
tracing::warn!("Grid:{} already exists in cache", grid_id);
|
||||
}
|
||||
self.grid_editors.insert(grid_id.to_string(), editor.clone());
|
||||
self.task_scheduler.write().await.register_handler(editor.clone());
|
||||
Ok(editor)
|
||||
}
|
||||
Some(editor) => Ok(editor.clone()),
|
||||
|
@ -1,6 +1,58 @@
|
||||
pub struct GridFilterService {}
|
||||
use crate::manager::GridTaskSchedulerRwLock;
|
||||
use crate::services::block_manager::GridBlockManager;
|
||||
use crate::services::tasks::Task;
|
||||
use flowy_error::FlowyResult;
|
||||
|
||||
use flowy_sync::client_grid::GridRevisionPad;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
pub(crate) struct GridFilterService {
|
||||
#[allow(dead_code)]
|
||||
scheduler: GridTaskSchedulerRwLock,
|
||||
#[allow(dead_code)]
|
||||
grid_pad: Arc<RwLock<GridRevisionPad>>,
|
||||
#[allow(dead_code)]
|
||||
block_manager: Arc<GridBlockManager>,
|
||||
}
|
||||
impl GridFilterService {
|
||||
pub fn new() -> Self {
|
||||
Self {}
|
||||
pub fn new(
|
||||
grid_pad: Arc<RwLock<GridRevisionPad>>,
|
||||
block_manager: Arc<GridBlockManager>,
|
||||
scheduler: GridTaskSchedulerRwLock,
|
||||
) -> Self {
|
||||
Self {
|
||||
grid_pad,
|
||||
block_manager,
|
||||
scheduler,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn process_task(&self, _task: Task) -> FlowyResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn notify_changed(&self) {
|
||||
//
|
||||
// let grid_pad = self.grid_pad.read().await;
|
||||
// match grid_pad.get_filters(None) {
|
||||
// None => {}
|
||||
// Some(filter_revs) => {
|
||||
// filter_revs
|
||||
// .iter()
|
||||
// .for_each(|filter_rev| match grid_pad.get_field_rev(&filter_rev.field_id) {
|
||||
// None => {}
|
||||
// Some((_, _field_rev)) => match field_rev.field_type {
|
||||
// FieldType::RichText => {}
|
||||
// FieldType::Number => {}
|
||||
// FieldType::DateTime => {}
|
||||
// FieldType::SingleSelect => {}
|
||||
// FieldType::MultiSelect => {}
|
||||
// FieldType::Checkbox => {}
|
||||
// FieldType::URL => {}
|
||||
// },
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
mod filter_service;
|
||||
|
||||
pub use filter_service::*;
|
||||
pub(crate) use filter_service::*;
|
||||
|
@ -1,12 +1,12 @@
|
||||
use crate::dart_notification::{send_dart_notification, GridNotification};
|
||||
use crate::entities::CellIdentifier;
|
||||
use crate::manager::GridUser;
|
||||
use crate::manager::{GridTaskSchedulerRwLock, GridUser};
|
||||
use crate::services::block_manager::GridBlockManager;
|
||||
use crate::services::field::{default_type_option_builder_from_type, type_option_builder_from_bytes, FieldBuilder};
|
||||
use crate::services::filter::GridFilterService;
|
||||
use crate::services::persistence::block_index::BlockIndexCache;
|
||||
use crate::services::row::*;
|
||||
use crate::services::tasks::GridTaskScheduler;
|
||||
|
||||
use bytes::Bytes;
|
||||
use flowy_error::{ErrorCode, FlowyError, FlowyResult};
|
||||
use flowy_grid_data_model::entities::*;
|
||||
@ -28,7 +28,7 @@ pub struct GridRevisionEditor {
|
||||
grid_pad: Arc<RwLock<GridRevisionPad>>,
|
||||
rev_manager: Arc<RevisionManager>,
|
||||
block_manager: Arc<GridBlockManager>,
|
||||
task_scheduler: Arc<RwLock<GridTaskScheduler>>,
|
||||
#[allow(dead_code)]
|
||||
pub(crate) filter_service: Arc<GridFilterService>,
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@ impl GridRevisionEditor {
|
||||
user: Arc<dyn GridUser>,
|
||||
mut rev_manager: RevisionManager,
|
||||
persistence: Arc<BlockIndexCache>,
|
||||
task_scheduler: Arc<RwLock<GridTaskScheduler>>,
|
||||
task_scheduler: GridTaskSchedulerRwLock,
|
||||
) -> FlowyResult<Arc<Self>> {
|
||||
let token = user.token()?;
|
||||
let cloud = Arc::new(GridRevisionCloudService { token });
|
||||
@ -53,7 +53,11 @@ impl GridRevisionEditor {
|
||||
let grid_pad = Arc::new(RwLock::new(grid_pad));
|
||||
let block_meta_revs = grid_pad.read().await.get_block_meta_revs();
|
||||
let block_manager = Arc::new(GridBlockManager::new(grid_id, &user, block_meta_revs, persistence).await?);
|
||||
let filter_service = Arc::new(GridFilterService::new());
|
||||
let filter_service = Arc::new(GridFilterService::new(
|
||||
grid_pad.clone(),
|
||||
block_manager.clone(),
|
||||
task_scheduler.clone(),
|
||||
));
|
||||
let editor = Arc::new(Self {
|
||||
grid_id: grid_id.to_owned(),
|
||||
user,
|
||||
@ -61,11 +65,8 @@ impl GridRevisionEditor {
|
||||
rev_manager,
|
||||
block_manager,
|
||||
filter_service,
|
||||
task_scheduler: task_scheduler.clone(),
|
||||
});
|
||||
|
||||
task_scheduler.write().await.register_handler(editor.clone());
|
||||
|
||||
Ok(editor)
|
||||
}
|
||||
|
||||
@ -459,18 +460,23 @@ impl GridRevisionEditor {
|
||||
}
|
||||
|
||||
pub async fn get_grid_filter(&self, layout_type: &GridLayoutType) -> FlowyResult<Vec<GridFilter>> {
|
||||
let layout_type: GridLayoutRevision = layout_type.clone().into();
|
||||
let read_guard = self.grid_pad.read().await;
|
||||
match read_guard.get_grid_setting_rev().filter.get(&layout_type) {
|
||||
let layout_rev = layout_type.clone().into();
|
||||
match read_guard.get_filters(Some(&layout_rev)) {
|
||||
Some(filter_revs) => Ok(filter_revs.iter().map(GridFilter::from).collect::<Vec<GridFilter>>()),
|
||||
None => Ok(vec![]),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn update_grid_setting(&self, params: GridSettingChangesetParams) -> FlowyResult<()> {
|
||||
let is_filter_changed = params.is_filter_changed();
|
||||
let _ = self
|
||||
.modify(|grid_pad| Ok(grid_pad.update_grid_setting_rev(params)?))
|
||||
.await?;
|
||||
|
||||
if is_filter_changed {
|
||||
self.filter_service.notify_changed().await;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -1,19 +1,19 @@
|
||||
use crate::services::grid_editor::GridRevisionEditor;
|
||||
use crate::services::tasks::{GridTaskHandler, Task, TaskContent};
|
||||
use crate::services::tasks::{GridTaskHandler, Task, TaskContent, TaskHandlerId};
|
||||
use flowy_error::FlowyError;
|
||||
use lib_infra::future::BoxResultFuture;
|
||||
use std::sync::Arc;
|
||||
|
||||
impl GridTaskHandler for Arc<GridRevisionEditor> {
|
||||
fn handler_id(&self) -> &str {
|
||||
use lib_infra::future::BoxResultFuture;
|
||||
|
||||
impl GridTaskHandler for GridRevisionEditor {
|
||||
fn handler_id(&self) -> &TaskHandlerId {
|
||||
&self.grid_id
|
||||
}
|
||||
|
||||
fn process_task(&self, task: Task) -> BoxResultFuture<(), FlowyError> {
|
||||
Box::pin(async move {
|
||||
match task.content {
|
||||
match &task.content {
|
||||
TaskContent::Snapshot { .. } => {}
|
||||
TaskContent::Filter => {}
|
||||
TaskContent::Filter => self.filter_service.process_task(task).await?,
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
|
@ -1,7 +1,6 @@
|
||||
use crate::services::row::decode_cell_data;
|
||||
use flowy_error::FlowyResult;
|
||||
use flowy_grid_data_model::entities::{Cell, GridBlock, RepeatedGridBlock, Row, RowOrder};
|
||||
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, RowRevision};
|
||||
use flowy_grid_data_model::entities::{GridBlock, RepeatedGridBlock, Row, RowOrder};
|
||||
use flowy_grid_data_model::revision::{FieldRevision, RowRevision};
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
@ -22,18 +21,18 @@ pub(crate) fn block_from_row_orders(row_orders: Vec<RowOrder>) -> Vec<GridBlock>
|
||||
});
|
||||
map.into_values().collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn make_cell_by_field_id(
|
||||
field_map: &HashMap<&String, &FieldRevision>,
|
||||
field_id: String,
|
||||
cell_rev: CellRevision,
|
||||
) -> Option<(String, Cell)> {
|
||||
let field_rev = field_map.get(&field_id)?;
|
||||
let data = decode_cell_data(cell_rev.data, field_rev).data;
|
||||
let cell = Cell::new(&field_id, data);
|
||||
Some((field_id, cell))
|
||||
}
|
||||
//
|
||||
// #[inline(always)]
|
||||
// fn make_cell_by_field_id(
|
||||
// field_map: &HashMap<&String, &FieldRevision>,
|
||||
// field_id: String,
|
||||
// cell_rev: CellRevision,
|
||||
// ) -> Option<(String, Cell)> {
|
||||
// let field_rev = field_map.get(&field_id)?;
|
||||
// let data = decode_cell_data(cell_rev.data, field_rev).data;
|
||||
// let cell = Cell::new(&field_id, data);
|
||||
// Some((field_id, cell))
|
||||
// }
|
||||
|
||||
pub(crate) fn make_row_orders_from_row_revs(row_revs: &[Arc<RowRevision>]) -> Vec<RowOrder> {
|
||||
row_revs.iter().map(RowOrder::from).collect::<Vec<_>>()
|
||||
@ -43,23 +42,22 @@ pub(crate) fn make_row_from_row_rev(fields: &[FieldRevision], row_rev: Arc<RowRe
|
||||
make_rows_from_row_revs(fields, &[row_rev]).pop()
|
||||
}
|
||||
|
||||
pub(crate) fn make_rows_from_row_revs(fields: &[FieldRevision], row_revs: &[Arc<RowRevision>]) -> Vec<Row> {
|
||||
let field_rev_map = fields
|
||||
.iter()
|
||||
.map(|field_rev| (&field_rev.id, field_rev))
|
||||
.collect::<HashMap<&String, &FieldRevision>>();
|
||||
pub(crate) fn make_rows_from_row_revs(_fields: &[FieldRevision], row_revs: &[Arc<RowRevision>]) -> Vec<Row> {
|
||||
// let field_rev_map = fields
|
||||
// .iter()
|
||||
// .map(|field_rev| (&field_rev.id, field_rev))
|
||||
// .collect::<HashMap<&String, &FieldRevision>>();
|
||||
|
||||
let make_row = |row_rev: &Arc<RowRevision>| {
|
||||
let cell_by_field_id = row_rev
|
||||
.cells
|
||||
.clone()
|
||||
.into_iter()
|
||||
.flat_map(|(field_id, cell_rev)| make_cell_by_field_id(&field_rev_map, field_id, cell_rev))
|
||||
.collect::<HashMap<String, Cell>>();
|
||||
// let cell_by_field_id = row_rev
|
||||
// .cells
|
||||
// .clone()
|
||||
// .into_iter()
|
||||
// .flat_map(|(field_id, cell_rev)| make_cell_by_field_id(&field_rev_map, field_id, cell_rev))
|
||||
// .collect::<HashMap<String, Cell>>();
|
||||
|
||||
Row {
|
||||
id: row_rev.id.clone(),
|
||||
cell_by_field_id,
|
||||
height: row_rev.height,
|
||||
}
|
||||
};
|
||||
|
@ -1,7 +1,7 @@
|
||||
pub struct GridSnapshotService {}
|
||||
|
||||
impl GridSnapshotService {
|
||||
pub fn new() -> Self {
|
||||
Self {}
|
||||
}
|
||||
}
|
||||
// pub struct GridSnapshotService {}
|
||||
//
|
||||
// impl GridSnapshotService {
|
||||
// pub fn new() -> Self {
|
||||
// Self {}
|
||||
// }
|
||||
// }
|
||||
|
@ -4,5 +4,6 @@ mod scheduler;
|
||||
mod store;
|
||||
mod task;
|
||||
|
||||
pub use queue::TaskHandlerId;
|
||||
pub use scheduler::*;
|
||||
pub use task::*;
|
||||
|
@ -10,7 +10,7 @@ use std::sync::Arc;
|
||||
#[derive(Default)]
|
||||
pub(crate) struct GridTaskQueue {
|
||||
// index_tasks for quick access
|
||||
index_tasks: HashMap<String, Arc<AtomicRefCell<TaskList>>>,
|
||||
index_tasks: HashMap<TaskHandlerId, Arc<AtomicRefCell<TaskList>>>,
|
||||
queue: BinaryHeap<Arc<AtomicRefCell<TaskList>>>,
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@ impl GridTaskQueue {
|
||||
};
|
||||
let pending_task = PendingTask {
|
||||
ty: task_type,
|
||||
id: task.id.clone(),
|
||||
id: task.id,
|
||||
};
|
||||
match self.index_tasks.entry("1".to_owned()) {
|
||||
Entry::Occupied(entry) => {
|
||||
@ -46,7 +46,7 @@ impl GridTaskQueue {
|
||||
|
||||
pub(crate) fn mut_head<T, F>(&mut self, mut f: F) -> Option<T>
|
||||
where
|
||||
F: FnMut(&mut TaskList) -> T,
|
||||
F: FnMut(&mut TaskList) -> Option<T>,
|
||||
{
|
||||
let head = self.queue.pop()?;
|
||||
let result = {
|
||||
@ -58,14 +58,15 @@ impl GridTaskQueue {
|
||||
} else {
|
||||
self.index_tasks.remove(&head.borrow().id);
|
||||
}
|
||||
|
||||
Some(result)
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
pub type TaskHandlerId = String;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct TaskList {
|
||||
id: String,
|
||||
pub(crate) id: TaskHandlerId,
|
||||
tasks: BinaryHeap<PendingTask>,
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ impl GridTaskRunner {
|
||||
let mut interval = interval(self.debounce_duration);
|
||||
interval.tick().await;
|
||||
|
||||
if let Err(e) = self.scheduler.write().await.process_next_task() {
|
||||
if let Err(e) = self.scheduler.write().await.process_next_task().await {
|
||||
tracing::error!("{:?}", e);
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,17 @@
|
||||
use crate::services::tasks::queue::GridTaskQueue;
|
||||
use crate::services::tasks::queue::{GridTaskQueue, TaskHandlerId};
|
||||
use crate::services::tasks::runner::GridTaskRunner;
|
||||
use crate::services::tasks::store::GridTaskStore;
|
||||
use crate::services::tasks::task::Task;
|
||||
|
||||
use flowy_error::{FlowyError, FlowyResult};
|
||||
use lib_infra::future::BoxResultFuture;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use tokio::sync::{watch, RwLock};
|
||||
|
||||
pub trait GridTaskHandler: Send + Sync + 'static {
|
||||
fn handler_id(&self) -> &str;
|
||||
fn handler_id(&self) -> &TaskHandlerId;
|
||||
|
||||
fn process_task(&self, task: Task) -> BoxResultFuture<(), FlowyError>;
|
||||
}
|
||||
@ -18,7 +20,7 @@ pub struct GridTaskScheduler {
|
||||
queue: GridTaskQueue,
|
||||
store: GridTaskStore,
|
||||
notifier: watch::Sender<()>,
|
||||
handlers: Vec<Arc<dyn GridTaskHandler>>,
|
||||
handlers: HashMap<TaskHandlerId, Arc<dyn GridTaskHandler>>,
|
||||
}
|
||||
|
||||
impl GridTaskScheduler {
|
||||
@ -29,7 +31,7 @@ impl GridTaskScheduler {
|
||||
queue: GridTaskQueue::new(),
|
||||
store: GridTaskStore::new(),
|
||||
notifier,
|
||||
handlers: vec![],
|
||||
handlers: HashMap::new(),
|
||||
};
|
||||
// The runner will receive the newest value after start running.
|
||||
scheduler.notify();
|
||||
@ -42,19 +44,41 @@ impl GridTaskScheduler {
|
||||
scheduler
|
||||
}
|
||||
|
||||
pub fn register_handler<T>(&mut self, handler: T)
|
||||
pub fn register_handler<T>(&mut self, handler: Arc<T>)
|
||||
where
|
||||
T: GridTaskHandler,
|
||||
{
|
||||
// todo!()
|
||||
let handler_id = handler.handler_id().to_owned();
|
||||
self.handlers.insert(handler_id, handler);
|
||||
}
|
||||
|
||||
pub fn process_next_task(&mut self) -> FlowyResult<()> {
|
||||
pub fn unregister_handler<T: AsRef<str>>(&mut self, handler_id: T) {
|
||||
let _ = self.handlers.remove(handler_id.as_ref());
|
||||
}
|
||||
|
||||
pub async fn process_next_task(&mut self) -> FlowyResult<()> {
|
||||
let mut get_next_task = || {
|
||||
let pending_task = self.queue.mut_head(|list| list.pop())?;
|
||||
let task = self.store.remove_task(&pending_task.id)?;
|
||||
Some(task)
|
||||
};
|
||||
|
||||
if let Some(task) = get_next_task() {
|
||||
match self.handlers.get(&task.hid) {
|
||||
None => {}
|
||||
Some(handler) => {
|
||||
let _ = handler.process_task(task).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn register_task(&self, task: Task) {
|
||||
pub fn register_task(&mut self, task: Task) {
|
||||
assert!(!task.is_finished());
|
||||
self.queue.push(&task);
|
||||
self.store.insert_task(task);
|
||||
self.notify();
|
||||
}
|
||||
|
||||
pub fn notify(&self) {
|
||||
|
@ -1,11 +1,32 @@
|
||||
use crate::services::tasks::task::Task;
|
||||
use crate::services::tasks::TaskId;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::atomic::AtomicU32;
|
||||
use std::sync::atomic::Ordering::SeqCst;
|
||||
|
||||
pub struct GridTaskStore {
|
||||
tasks: Vec<Task>,
|
||||
tasks: HashMap<TaskId, Task>,
|
||||
task_id_counter: AtomicU32,
|
||||
}
|
||||
|
||||
impl GridTaskStore {
|
||||
pub fn new() -> Self {
|
||||
Self { tasks: vec![] }
|
||||
Self {
|
||||
tasks: HashMap::new(),
|
||||
task_id_counter: AtomicU32::new(0),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert_task(&mut self, task: Task) {
|
||||
self.tasks.insert(task.id, task);
|
||||
}
|
||||
|
||||
pub fn remove_task(&mut self, task_id: &TaskId) -> Option<Task> {
|
||||
self.tasks.remove(task_id)
|
||||
}
|
||||
#[allow(dead_code)]
|
||||
pub fn next_task_id(&self) -> TaskId {
|
||||
let _ = self.task_id_counter.fetch_add(1, SeqCst);
|
||||
self.task_id_counter.load(SeqCst)
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
use crate::services::tasks::queue::TaskHandlerId;
|
||||
use std::cmp::Ordering;
|
||||
|
||||
#[derive(Eq, Debug, Clone, Copy)]
|
||||
@ -56,6 +57,7 @@ pub enum TaskContent {
|
||||
}
|
||||
|
||||
pub struct Task {
|
||||
pub hid: TaskHandlerId,
|
||||
pub id: TaskId,
|
||||
pub content: TaskContent,
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ async fn grid_filter_invalid_condition_panic_test() {
|
||||
async fn grid_filter_delete_test() {
|
||||
let mut test = GridEditorTest::new().await;
|
||||
let field_rev = test.text_field();
|
||||
let payload = CreateGridFilterPayload::new(field_rev, 100, Some("abc".to_owned()));
|
||||
let payload = CreateGridFilterPayload::new(field_rev, TextFilterCondition::TextIsEmpty, Some("abc".to_owned()));
|
||||
let scripts = vec![InsertGridTableFilter { payload }, AssertTableFilterCount { count: 1 }];
|
||||
test.run_scripts(scripts).await;
|
||||
|
||||
|
@ -17,19 +17,21 @@ impl<'a> GridRowTestBuilder<'a> {
|
||||
let inner_builder = CreateRowRevisionBuilder::new(&test.field_revs);
|
||||
Self { test, inner_builder }
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn update_text_cell(mut self, data: String) -> Self {
|
||||
let text_field = self.field_rev_with_type(&FieldType::DateTime);
|
||||
self.inner_builder.add_cell(&text_field.id, data).unwrap();
|
||||
self
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn update_number_cell(mut self, data: String) -> Self {
|
||||
let number_field = self.field_rev_with_type(&FieldType::DateTime);
|
||||
self.inner_builder.add_cell(&number_field.id, data).unwrap();
|
||||
self
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn update_date_cell(mut self, value: i64) -> Self {
|
||||
let value = serde_json::to_string(&DateCellContentChangeset {
|
||||
date: Some(value.to_string()),
|
||||
@ -41,12 +43,14 @@ impl<'a> GridRowTestBuilder<'a> {
|
||||
self
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn update_checkbox_cell(mut self, data: bool) -> Self {
|
||||
let number_field = self.field_rev_with_type(&FieldType::Checkbox);
|
||||
self.inner_builder.add_cell(&number_field.id, data.to_string()).unwrap();
|
||||
self
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn update_url_cell(mut self, data: String) -> Self {
|
||||
let number_field = self.field_rev_with_type(&FieldType::Checkbox);
|
||||
self.inner_builder.add_cell(&number_field.id, data).unwrap();
|
||||
|
@ -1,3 +1,4 @@
|
||||
#![cfg_attr(rustfmt, rustfmt::skip)]
|
||||
use bytes::Bytes;
|
||||
use flowy_grid::services::field::*;
|
||||
use flowy_grid::services::grid_editor::{GridPadBuilder, GridRevisionEditor};
|
||||
@ -64,6 +65,7 @@ pub enum EditorScript {
|
||||
is_err: bool,
|
||||
},
|
||||
AssertRowCount(usize),
|
||||
#[allow(dead_code)]
|
||||
UpdateGridSetting {
|
||||
params: GridSettingChangesetParams,
|
||||
},
|
||||
@ -76,6 +78,7 @@ pub enum EditorScript {
|
||||
DeleteGridTableFilter {
|
||||
filter_id: String,
|
||||
},
|
||||
#[allow(dead_code)]
|
||||
AssertGridSetting {
|
||||
expected_setting: GridSetting,
|
||||
},
|
||||
|
@ -228,7 +228,7 @@ impl ViewDataProcessor for GridViewDataProcessor {
|
||||
let grid_manager = self.0.clone();
|
||||
let view_id = view_id.to_string();
|
||||
FutureResult::new(async move {
|
||||
let _ = grid_manager.delete_grid(view_id)?;
|
||||
let _ = grid_manager.delete_grid(view_id).await?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
@ -237,7 +237,7 @@ impl ViewDataProcessor for GridViewDataProcessor {
|
||||
let grid_manager = self.0.clone();
|
||||
let view_id = view_id.to_string();
|
||||
FutureResult::new(async move {
|
||||
let _ = grid_manager.close_grid(view_id)?;
|
||||
let _ = grid_manager.close_grid(view_id).await?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
@ -4,8 +4,6 @@ use crate::revision::RowRevision;
|
||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||
use flowy_error_code::ErrorCode;
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Debug, Clone, Default, ProtoBuf)]
|
||||
pub struct Grid {
|
||||
#[pb(index = 1)]
|
||||
@ -36,9 +34,6 @@ pub struct Row {
|
||||
pub id: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub cell_by_field_id: HashMap<String, Cell>,
|
||||
|
||||
#[pb(index = 3)]
|
||||
pub height: i32,
|
||||
}
|
||||
|
||||
|
@ -24,19 +24,19 @@ pub struct GridSetting {
|
||||
impl std::convert::From<&GridSettingRevision> for GridSetting {
|
||||
fn from(rev: &GridSettingRevision) -> Self {
|
||||
let filters_by_layout_ty: HashMap<String, RepeatedGridFilter> = rev
|
||||
.filter
|
||||
.filters
|
||||
.iter()
|
||||
.map(|(layout_rev, filter_revs)| (layout_rev.to_string(), filter_revs.into()))
|
||||
.collect();
|
||||
|
||||
let groups_by_layout_ty: HashMap<String, RepeatedGridGroup> = rev
|
||||
.group
|
||||
.groups
|
||||
.iter()
|
||||
.map(|(layout_rev, group_revs)| (layout_rev.to_string(), group_revs.into()))
|
||||
.collect();
|
||||
|
||||
let sorts_by_layout_ty: HashMap<String, RepeatedGridSort> = rev
|
||||
.sort
|
||||
.sorts
|
||||
.iter()
|
||||
.map(|(layout_rev, sort_revs)| (layout_rev.to_string(), sort_revs.into()))
|
||||
.collect();
|
||||
@ -118,6 +118,12 @@ pub struct GridSettingChangesetParams {
|
||||
pub delete_sort: Option<String>,
|
||||
}
|
||||
|
||||
impl GridSettingChangesetParams {
|
||||
pub fn is_filter_changed(&self) -> bool {
|
||||
self.insert_filter.is_some() || self.delete_filter.is_some()
|
||||
}
|
||||
}
|
||||
|
||||
impl TryInto<GridSettingChangesetParams> for GridSettingChangesetPayload {
|
||||
type Error = ErrorCode;
|
||||
|
||||
|
@ -20,13 +20,13 @@ pub struct GridSettingRevision {
|
||||
pub layout: GridLayoutRevision,
|
||||
|
||||
#[serde(with = "indexmap::serde_seq")]
|
||||
pub filter: IndexMap<GridLayoutRevision, Vec<GridFilterRevision>>,
|
||||
pub filters: IndexMap<GridLayoutRevision, Vec<GridFilterRevision>>,
|
||||
|
||||
#[serde(skip, with = "indexmap::serde_seq")]
|
||||
pub group: IndexMap<GridLayoutRevision, Vec<GridGroupRevision>>,
|
||||
pub groups: IndexMap<GridLayoutRevision, Vec<GridGroupRevision>>,
|
||||
|
||||
#[serde(skip, with = "indexmap::serde_seq")]
|
||||
pub sort: IndexMap<GridLayoutRevision, Vec<GridSortRevision>>,
|
||||
pub sorts: IndexMap<GridLayoutRevision, Vec<GridSortRevision>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize_repr, Deserialize_repr)]
|
||||
|
@ -334,6 +334,11 @@ impl GridRevisionPad {
|
||||
&self.grid_rev.setting
|
||||
}
|
||||
|
||||
pub fn get_filters(&self, layout: Option<&GridLayoutRevision>) -> Option<&Vec<GridFilterRevision>> {
|
||||
let layout_ty = layout.unwrap_or(&self.grid_rev.setting.layout);
|
||||
self.grid_rev.setting.filters.get(layout_ty)
|
||||
}
|
||||
|
||||
pub fn update_grid_setting_rev(
|
||||
&mut self,
|
||||
changeset: GridSettingChangesetParams,
|
||||
@ -352,7 +357,7 @@ impl GridRevisionPad {
|
||||
|
||||
grid_rev
|
||||
.setting
|
||||
.filter
|
||||
.filters
|
||||
.entry(layout_rev.clone())
|
||||
.or_insert_with(std::vec::Vec::new)
|
||||
.push(rev);
|
||||
@ -360,7 +365,7 @@ impl GridRevisionPad {
|
||||
is_changed = Some(())
|
||||
}
|
||||
if let Some(delete_filter_id) = changeset.delete_filter {
|
||||
match grid_rev.setting.filter.get_mut(&layout_rev) {
|
||||
match grid_rev.setting.filters.get_mut(&layout_rev) {
|
||||
Some(filters) => filters.retain(|filter| filter.id != delete_filter_id),
|
||||
None => {
|
||||
tracing::warn!("Can't find the filter with {:?}", layout_rev);
|
||||
@ -376,7 +381,7 @@ impl GridRevisionPad {
|
||||
|
||||
grid_rev
|
||||
.setting
|
||||
.group
|
||||
.groups
|
||||
.entry(layout_rev.clone())
|
||||
.or_insert_with(std::vec::Vec::new)
|
||||
.push(rev);
|
||||
@ -384,7 +389,7 @@ impl GridRevisionPad {
|
||||
is_changed = Some(())
|
||||
}
|
||||
if let Some(delete_group_id) = changeset.delete_group {
|
||||
match grid_rev.setting.group.get_mut(&layout_rev) {
|
||||
match grid_rev.setting.groups.get_mut(&layout_rev) {
|
||||
Some(groups) => groups.retain(|group| group.id != delete_group_id),
|
||||
None => {
|
||||
tracing::warn!("Can't find the group with {:?}", layout_rev);
|
||||
@ -399,7 +404,7 @@ impl GridRevisionPad {
|
||||
|
||||
grid_rev
|
||||
.setting
|
||||
.sort
|
||||
.sorts
|
||||
.entry(layout_rev.clone())
|
||||
.or_insert_with(std::vec::Vec::new)
|
||||
.push(rev);
|
||||
@ -407,7 +412,7 @@ impl GridRevisionPad {
|
||||
}
|
||||
|
||||
if let Some(delete_sort_id) = changeset.delete_sort {
|
||||
match grid_rev.setting.sort.get_mut(&layout_rev) {
|
||||
match grid_rev.setting.sorts.get_mut(&layout_rev) {
|
||||
Some(sorts) => sorts.retain(|sort| sort.id != delete_sort_id),
|
||||
None => {
|
||||
tracing::warn!("Can't find the sort with {:?}", layout_rev);
|
||||
|
Loading…
Reference in New Issue
Block a user