chore: config sort controller

This commit is contained in:
nathan 2022-12-12 10:44:34 +08:00
parent 0cf0b29721
commit 6b4291ccc7
18 changed files with 272 additions and 51 deletions

View File

@ -19,8 +19,8 @@ pub(crate) async fn get_grid_handler(
manager: AFPluginState<Arc<GridManager>>,
) -> DataResult<GridPB, FlowyError> {
let grid_id: GridIdPB = data.into_inner();
let editor = manager.open_grid(grid_id).await?;
let grid = editor.get_grid().await?;
let editor = manager.open_grid(grid_id.as_ref()).await?;
let grid = editor.get_grid(grid_id.as_ref()).await?;
data_result(grid)
}

View File

@ -228,6 +228,7 @@ impl GridBlockManager {
editor.get_row_rev(row_id).await
}
#[allow(dead_code)]
pub async fn get_row_revs(&self, block_id: &str) -> FlowyResult<Vec<Arc<RowRevision>>> {
let editor = self.get_block_editor(block_id).await?;
editor.get_row_revs::<&str>(None).await

View File

@ -44,7 +44,7 @@ impl FilterController {
notifier: GridViewChangedNotifier,
) -> Self
where
T: FilterDelegate,
T: FilterDelegate + 'static,
{
let mut this = Self {
view_id: view_id.to_string(),

View File

@ -71,12 +71,11 @@ pub struct FilterType {
pub field_type: FieldType,
}
impl FilterType {
pub fn field_type_rev(&self) -> FieldTypeRevision {
self.field_type.clone().into()
impl Into<FieldTypeRevision> for FilterType {
fn into(self) -> FieldTypeRevision {
self.field_type.into()
}
}
impl std::convert::From<&Arc<FieldRevision>> for FilterType {
fn from(rev: &Arc<FieldRevision>) -> Self {
Self {

View File

@ -394,11 +394,11 @@ impl GridRevisionEditor {
}
/// Returns all the rows in this block.
pub async fn get_row_pbs(&self, block_id: &str) -> FlowyResult<Vec<RowPB>> {
let rows = self.block_manager.get_row_revs(block_id).await?;
pub async fn get_row_pbs(&self, view_id: &str, block_id: &str) -> FlowyResult<Vec<RowPB>> {
let rows = self.view_manager.get_row_revs(view_id, block_id).await?;
let rows = self
.view_manager
.filter_rows(block_id, rows)
.filter_rows(view_id, block_id, rows)
.await?
.into_iter()
.map(|row_rev| RowPB::from(&row_rev))
@ -535,12 +535,12 @@ impl GridRevisionEditor {
Ok(())
}
pub async fn get_grid(&self) -> FlowyResult<GridPB> {
pub async fn get_grid(&self, view_id: &str) -> FlowyResult<GridPB> {
let pad = self.grid_pad.read().await;
let fields = pad.get_field_revs(None)?.iter().map(FieldIdPB::from).collect();
let mut all_rows = vec![];
for block_rev in pad.get_block_meta_revs() {
if let Ok(rows) = self.get_row_pbs(&block_rev.block_id).await {
if let Ok(rows) = self.get_row_pbs(view_id, &block_rev.block_id).await {
all_rows.extend(rows);
}
}

View File

@ -51,11 +51,11 @@ impl GridViewEditorDelegate for GridViewEditorDelegateImpl {
})
}
fn get_row_revs(&self) -> Fut<Vec<Arc<RowRevision>>> {
fn get_row_revs(&self, block_id: Option<Vec<String>>) -> Fut<Vec<Arc<RowRevision>>> {
let block_manager = self.block_manager.clone();
to_fut(async move {
let blocks = block_manager.get_blocks(None).await.unwrap();
let blocks = block_manager.get_blocks(block_id).await.unwrap();
blocks
.into_iter()
.flat_map(|block| block.row_revs)

View File

@ -1,6 +1,45 @@
pub struct SortController {}
use crate::services::sort::SortType;
use flowy_task::TaskDispatcher;
use grid_rev_model::{FieldRevision, RowRevision, SortRevision};
use lib_infra::future::Fut;
use std::sync::Arc;
use tokio::sync::RwLock;
pub trait SortDelegate: Send + Sync {
fn get_sort_rev(&self, sort_type: SortType) -> Fut<Vec<Arc<SortRevision>>>;
fn get_field_rev(&self, field_id: &str) -> Fut<Option<Arc<FieldRevision>>>;
fn get_field_revs(&self, field_ids: Option<Vec<String>>) -> Fut<Vec<Arc<FieldRevision>>>;
}
pub struct SortController {
view_id: String,
handler_id: String,
delegate: Box<dyn SortDelegate>,
task_scheduler: Arc<RwLock<TaskDispatcher>>,
}
impl SortController {
pub fn new() -> Self {
Self {}
pub fn new<T>(view_id: &str, handler_id: &str, delegate: T, task_scheduler: Arc<RwLock<TaskDispatcher>>) -> Self
where
T: SortDelegate + 'static,
{
Self {
view_id: view_id.to_string(),
handler_id: handler_id.to_string(),
delegate: Box::new(delegate),
task_scheduler,
}
}
pub async fn close(&self) {
self.task_scheduler
.write()
.await
.unregister_handler(&self.handler_id)
.await;
}
pub fn sort_rows(&self, rows: &mut Vec<Arc<RowRevision>>) {
todo!()
}
}

View File

@ -0,0 +1,14 @@
use crate::entities::FieldType;
use grid_rev_model::FieldTypeRevision;
#[derive(Hash, Eq, PartialEq, Debug, Clone)]
pub struct SortType {
pub field_id: String,
pub field_type: FieldType,
}
impl Into<FieldTypeRevision> for SortType {
fn into(self) -> FieldTypeRevision {
self.field_type.into()
}
}

View File

@ -1,3 +1,7 @@
mod controller;
mod entities;
mod task;
pub use controller::*;
pub use entities::*;
pub use task::*;

View File

@ -0,0 +1,29 @@
use crate::services::sort::SortController;
use flowy_task::{TaskContent, TaskHandler};
use lib_infra::future::BoxResultFuture;
use std::sync::Arc;
use tokio::sync::RwLock;
pub struct SortTaskHandler {
handler_id: String,
sort_controller: Arc<RwLock<SortController>>,
}
impl SortTaskHandler {
pub fn new(handler_id: String, sort_controller: Arc<RwLock<SortController>>) -> Self {
Self {
handler_id,
sort_controller,
}
}
}
impl TaskHandler for SortTaskHandler {
fn handler_id(&self) -> &str {
&self.handler_id
}
fn run(&self, content: TaskContent) -> BoxResultFuture<(), anyhow::Error> {
todo!();
}
}

View File

@ -7,7 +7,7 @@ use crate::services::group::{
GroupController, MoveGroupRowContext,
};
use crate::services::row::GridBlockRowRevision;
use crate::services::sort::SortController;
use crate::services::sort::{SortController, SortTaskHandler};
use crate::services::view_editor::changed_notifier::GridViewChangedNotifier;
use crate::services::view_editor::trait_impl::*;
use crate::services::view_editor::GridViewChangedReceiverRunner;
@ -39,17 +39,22 @@ pub trait GridViewEditorDelegate: Send + Sync + 'static {
/// Returns the index of the row with row_id
fn index_of_row(&self, row_id: &str) -> Fut<Option<usize>>;
/// Get the row with row_id
/// Returns the `index` and `RowRevision` with row_id
fn get_row_rev(&self, row_id: &str) -> Fut<Option<(usize, Arc<RowRevision>)>>;
/// Get all the rows that the current Grid has
/// One block has a list of rows
fn get_row_revs(&self) -> Fut<Vec<Arc<RowRevision>>>;
/// Returns all the rows that the block has. If the passed-in block_ids is None, then will return all the rows
/// The relationship between the grid and the block is:
/// A grid has a list of blocks
/// A block has a list of rows
/// A row has a list of cells
///
fn get_row_revs(&self, block_ids: Option<Vec<String>>) -> Fut<Vec<Arc<RowRevision>>>;
/// Get all the blocks that the current Grid has.
/// One grid has a list of blocks
fn get_blocks(&self) -> Fut<Vec<GridBlockRowRevision>>;
/// Returns a `TaskDispatcher` used to poll a `Task`
fn get_task_scheduler(&self) -> Arc<RwLock<TaskDispatcher>>;
}
@ -104,7 +109,7 @@ impl GridViewRevisionEditor {
)
.await?;
let sort_controller = Arc::new(RwLock::new(SortController::new()));
let sort_controller = make_sort_controller(&view_id, delegate.clone(), view_rev_pad.clone()).await;
let user_id = user_id.to_owned();
let group_controller = Arc::new(RwLock::new(group_controller));
@ -159,8 +164,8 @@ impl GridViewRevisionEditor {
.send();
}
pub async fn notify_rows_did_changed(&self) {
//
pub async fn sort_rows(&self, rows: &mut Vec<Arc<RowRevision>>) {
self.sort_controller.read().await.sort_rows(rows)
}
pub async fn filter_rows(&self, _block_id: &str, mut rows: Vec<Arc<RowRevision>>) -> Vec<Arc<RowRevision>> {
@ -420,7 +425,6 @@ impl GridViewRevisionEditor {
#[tracing::instrument(level = "trace", skip(self), err)]
pub async fn delete_view_filter(&self, params: DeleteFilterParams) -> FlowyResult<()> {
let filter_type = params.filter_type;
let field_type_rev = filter_type.field_type_rev();
let changeset = self
.filter_controller
.write()
@ -430,7 +434,7 @@ impl GridViewRevisionEditor {
let _ = self
.modify(|pad| {
let changeset = pad.delete_filter(&params.filter_id, &filter_type.field_id, &field_type_rev)?;
let changeset = pad.delete_filter(&params.filter_id, &filter_type.field_id, filter_type.field_type)?;
Ok(changeset)
})
.await?;
@ -474,7 +478,7 @@ impl GridViewRevisionEditor {
#[tracing::instrument(level = "debug", skip_all, err)]
pub async fn group_by_view_field(&self, field_id: &str) -> FlowyResult<()> {
if let Some(field_rev) = self.delegate.get_field_rev(field_id).await {
let row_revs = self.delegate.get_row_revs().await;
let row_revs = self.delegate.get_row_revs(None).await;
let new_group_controller = new_group_controller_with_field_rev(
self.user_id.clone(),
self.view_id.clone(),
@ -594,7 +598,7 @@ async fn new_group_controller(
) -> FlowyResult<Box<dyn GroupController>> {
let configuration_reader = GroupConfigurationReaderImpl(view_rev_pad.clone());
let field_revs = delegate.get_field_revs(None).await;
let row_revs = delegate.get_row_revs().await;
let row_revs = delegate.get_row_revs(None).await;
let layout = view_rev_pad.read().await.layout();
// Read the group field or find a new group field
let field_rev = configuration_reader
@ -661,6 +665,31 @@ async fn make_filter_controller(
filter_controller
}
async fn make_sort_controller(
view_id: &str,
delegate: Arc<dyn GridViewEditorDelegate>,
pad: Arc<RwLock<GridViewRevisionPad>>,
) -> Arc<RwLock<SortController>> {
let handler_id = gen_handler_id();
let sort_delegate = GridViewSortDelegateImpl {
editor_delegate: delegate.clone(),
view_revision_pad: pad,
};
let task_scheduler = delegate.get_task_scheduler();
let sort_controller = Arc::new(RwLock::new(SortController::new(
view_id,
&handler_id,
sort_delegate,
task_scheduler.clone(),
)));
task_scheduler
.write()
.await
.register_handler(SortTaskHandler::new(handler_id, sort_controller.clone()));
sort_controller
}
fn gen_handler_id() -> String {
nanoid!(10)
}

View File

@ -53,13 +53,24 @@ impl GridViewManager {
Ok(self.get_view_editor(view_id).await?.notifier.subscribe())
}
pub async fn get_rows(&self) -> FlowyResult<Vec<Arc<RowRevision>>> {
todo!()
pub async fn get_row_revs(&self, view_id: &str, block_id: &str) -> FlowyResult<Vec<Arc<RowRevision>>> {
let mut row_revs = self.delegate.get_row_revs(Some(vec![block_id.to_owned()])).await;
if let Ok(view_editor) = self.get_view_editor(view_id).await {
view_editor.sort_rows(&mut row_revs).await;
}
Ok(row_revs)
}
pub async fn filter_rows(&self, block_id: &str, rows: Vec<Arc<RowRevision>>) -> FlowyResult<Vec<Arc<RowRevision>>> {
let editor = self.get_default_view_editor().await?;
let rows = editor.filter_rows(block_id, rows).await;
pub async fn filter_rows(
&self,
view_id: &str,
block_id: &str,
rows: Vec<Arc<RowRevision>>,
) -> FlowyResult<Vec<Arc<RowRevision>>> {
let rows = match self.get_view_editor(view_id).await {
Ok(view_editor) => view_editor.filter_rows(block_id, rows).await,
Err(_) => rows,
};
Ok(rows)
}

View File

@ -2,6 +2,7 @@ use crate::entities::{GridLayout, GridLayoutPB, GridSettingPB};
use crate::services::filter::{FilterDelegate, FilterType};
use crate::services::group::{GroupConfigurationReader, GroupConfigurationWriter};
use crate::services::row::GridBlockRowRevision;
use crate::services::sort::{SortDelegate, SortType};
use crate::services::view_editor::GridViewEditorDelegate;
use bytes::Bytes;
use flowy_database::ConnectionPool;
@ -12,7 +13,9 @@ use flowy_revision::{
};
use flowy_sync::client_grid::{GridViewRevisionChangeset, GridViewRevisionPad};
use flowy_sync::util::make_operations_from_revisions;
use grid_rev_model::{FieldRevision, FieldTypeRevision, FilterRevision, GroupConfigurationRevision, RowRevision};
use grid_rev_model::{
FieldRevision, FieldTypeRevision, FilterRevision, GroupConfigurationRevision, RowRevision, SortRevision,
};
use lib_infra::future::{to_fut, Fut, FutureResult};
use lib_ot::core::EmptyAttributes;
use std::sync::Arc;
@ -132,11 +135,11 @@ pub(crate) struct GridViewFilterDelegateImpl {
}
impl FilterDelegate for GridViewFilterDelegateImpl {
fn get_filter_rev(&self, filter_id: FilterType) -> Fut<Option<Arc<FilterRevision>>> {
fn get_filter_rev(&self, filter_type: FilterType) -> Fut<Option<Arc<FilterRevision>>> {
let pad = self.view_revision_pad.clone();
to_fut(async move {
let field_type_rev: FieldTypeRevision = filter_id.field_type.into();
let mut filters = pad.read().await.get_filters(&filter_id.field_id, &field_type_rev);
let field_type_rev: FieldTypeRevision = filter_type.field_type.into();
let mut filters = pad.read().await.get_filters(&filter_type.field_id, &field_type_rev);
if filters.is_empty() {
None
} else {
@ -162,3 +165,26 @@ impl FilterDelegate for GridViewFilterDelegateImpl {
self.editor_delegate.get_row_rev(row_id)
}
}
pub(crate) struct GridViewSortDelegateImpl {
pub(crate) editor_delegate: Arc<dyn GridViewEditorDelegate>,
pub(crate) view_revision_pad: Arc<RwLock<GridViewRevisionPad>>,
}
impl SortDelegate for GridViewSortDelegateImpl {
fn get_sort_rev(&self, sort_type: SortType) -> Fut<Vec<Arc<SortRevision>>> {
let pad = self.view_revision_pad.clone();
to_fut(async move {
let field_type_rev: FieldTypeRevision = sort_type.field_type.into();
pad.read().await.get_sorts(&sort_type.field_id, &field_type_rev)
})
}
fn get_field_rev(&self, field_id: &str) -> Fut<Option<Arc<FieldRevision>>> {
self.editor_delegate.get_field_rev(field_id)
}
fn get_field_revs(&self, field_ids: Option<Vec<String>>) -> Fut<Vec<Arc<FieldRevision>>> {
self.editor_delegate.get_field_revs(field_ids)
}
}

View File

@ -4,6 +4,7 @@ use flowy_http_model::revision::Revision;
use flowy_http_model::util::md5;
use grid_rev_model::{
FieldRevision, FieldTypeRevision, FilterRevision, GridViewRevision, GroupConfigurationRevision, LayoutRevision,
SortRevision,
};
use lib_ot::core::{DeltaBuilder, DeltaOperations, EmptyAttributes, OperationTransform};
use std::sync::Arc;
@ -126,10 +127,65 @@ impl GridViewRevisionPad {
})
}
pub fn get_all_sorts(&self, field_revs: &[Arc<FieldRevision>]) -> Vec<Arc<SortRevision>> {
self.sorts.get_objects_by_field_revs(field_revs)
}
/// For the moment, a field type only have one filter.
pub fn get_sorts(&self, field_id: &str, field_type_rev: &FieldTypeRevision) -> Vec<Arc<SortRevision>> {
self.sorts.get_objects(field_id, field_type_rev).unwrap_or_default()
}
pub fn get_sort(
&self,
field_id: &str,
field_type_rev: &FieldTypeRevision,
sort_id: &str,
) -> Option<Arc<SortRevision>> {
self.sorts
.get_object(field_id, field_type_rev, |sort| sort.id == sort_id)
}
pub fn update_sort(
&mut self,
field_id: &str,
sort_rev: SortRevision,
) -> CollaborateResult<Option<GridViewRevisionChangeset>> {
self.modify(|view| {
if let Some(sort) = view
.sorts
.get_mut_object(field_id, &sort_rev.field_type, |sort| sort.id == sort_rev.id)
{
let sort = Arc::make_mut(sort);
sort.condition = sort_rev.condition;
Ok(Some(()))
} else {
Ok(None)
}
})
}
pub fn delete_sort(
&mut self,
sort_id: &str,
field_id: &str,
field_type: &FieldTypeRevision,
) -> CollaborateResult<Option<GridViewRevisionChangeset>> {
self.modify(|view| {
if let Some(sorts) = view.sorts.get_mut_objects(field_id, field_type) {
sorts.retain(|sort| sort.id != sort_id);
Ok(Some(()))
} else {
Ok(None)
}
})
}
pub fn get_all_filters(&self, field_revs: &[Arc<FieldRevision>]) -> Vec<Arc<FilterRevision>> {
self.filters.get_objects_by_field_revs(field_revs)
}
/// For the moment, a field type only have one filter.
pub fn get_filters(&self, field_id: &str, field_type_rev: &FieldTypeRevision) -> Vec<Arc<FilterRevision>> {
self.filters.get_objects(field_id, field_type_rev).unwrap_or_default()
}
@ -176,14 +232,15 @@ impl GridViewRevisionPad {
})
}
pub fn delete_filter(
pub fn delete_filter<T: Into<FieldTypeRevision>>(
&mut self,
filter_id: &str,
field_id: &str,
field_type: &FieldTypeRevision,
field_type: T,
) -> CollaborateResult<Option<GridViewRevisionChangeset>> {
let field_type = field_type.into();
self.modify(|view| {
if let Some(filters) = view.filters.get_mut_objects(field_id, field_type) {
if let Some(filters) = view.filters.get_mut_objects(field_id, &field_type) {
filters.retain(|filter| filter.id != filter_id);
Ok(Some(()))
} else {

View File

@ -1,4 +1,4 @@
use crate::{FieldRevision, FieldTypeRevision, FilterRevision, GroupConfigurationRevision};
use crate::{FieldRevision, FieldTypeRevision, FilterRevision, GroupConfigurationRevision, SortRevision};
use indexmap::IndexMap;
use nanoid::nanoid;
use serde::{Deserialize, Serialize};
@ -20,10 +20,10 @@ pub fn gen_grid_sort_id() -> String {
}
pub type FilterConfiguration = Configuration<FilterRevision>;
pub type FilterConfigurationsByFieldId = HashMap<String, Vec<Arc<FilterRevision>>>;
//
pub type GroupConfiguration = Configuration<GroupConfigurationRevision>;
pub type GroupConfigurationsByFieldId = HashMap<String, Vec<Arc<GroupConfigurationRevision>>>;
pub type SortConfiguration = Configuration<SortRevision>;
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
#[serde(transparent)]

View File

@ -1,4 +1,4 @@
use crate::{FilterConfiguration, GroupConfiguration};
use crate::{FilterConfiguration, GroupConfiguration, SortConfiguration};
use nanoid::nanoid;
use serde::{Deserialize, Serialize};
use serde_repr::*;
@ -41,10 +41,9 @@ pub struct GridViewRevision {
#[serde(default)]
pub groups: GroupConfiguration,
// // For the moment, we just use the order returned from the GridRevision
// #[allow(dead_code)]
// #[serde(skip, rename = "rows")]
// pub row_orders: Vec<RowOrderRevision>,
#[serde(default)]
pub sorts: SortConfiguration,
}
impl GridViewRevision {
@ -55,7 +54,7 @@ impl GridViewRevision {
layout,
filters: Default::default(),
groups: Default::default(),
// row_orders: vec![],
sorts: Default::default(),
}
}
@ -81,6 +80,7 @@ mod tests {
layout: Default::default(),
filters: Default::default(),
groups: Default::default(),
sorts: Default::default(),
};
let s = serde_json::to_string(&grid_view_revision).unwrap();
assert_eq!(

View File

@ -4,6 +4,7 @@ mod grid_rev;
mod grid_setting_rev;
mod grid_view;
mod group_rev;
mod sort_rev;
pub use filter_rev::*;
pub use grid_block::*;
@ -11,3 +12,4 @@ pub use grid_rev::*;
pub use grid_setting_rev::*;
pub use grid_view::*;
pub use group_rev::*;
pub use sort_rev::*;

View File

@ -0,0 +1,10 @@
use crate::FieldTypeRevision;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq, Hash)]
pub struct SortRevision {
pub id: String,
pub field_id: String,
pub field_type: FieldTypeRevision,
pub condition: u8,
}