chore: add cell cmp trait

This commit is contained in:
nathan 2022-12-12 15:29:33 +08:00
parent 1ac1fabb6e
commit e141e7ee63
13 changed files with 271 additions and 44 deletions

View File

@ -171,6 +171,7 @@ class FilterFFIService {
var insertFilterPayload = AlterFilterPayloadPB.create()
..fieldId = fieldId
..fieldType = fieldType
..viewId = viewId
..data = data;
if (filterId != null) {
@ -179,7 +180,7 @@ class FilterFFIService {
final payload = GridSettingChangesetPB.create()
..gridId = viewId
..insertFilter = insertFilterPayload;
..alterFilter = insertFilterPayload;
return GridEventUpdateGridSetting(payload).send().then((result) {
return result.fold(
(l) => left(l),
@ -201,6 +202,7 @@ class FilterFFIService {
final deleteFilterPayload = DeleteFilterPayloadPB.create()
..fieldId = fieldId
..filterId = filterId
..viewId = viewId
..fieldType = fieldType;
final payload = GridSettingChangesetPB.create()

View File

@ -16,6 +16,7 @@ pub enum GridDartNotification {
DidUpdateGroup = 61,
DidGroupByNewField = 62,
DidUpdateFilter = 63,
DidUpdateSort = 64,
DidUpdateGridSetting = 70,
}

View File

@ -79,12 +79,18 @@ pub struct DeleteFilterPayloadPB {
#[pb(index = 3)]
pub filter_id: String,
#[pb(index = 4)]
pub view_id: String,
}
impl TryInto<DeleteFilterParams> for DeleteFilterPayloadPB {
type Error = ErrorCode;
fn try_into(self) -> Result<DeleteFilterParams, Self::Error> {
let view_id = NotEmptyStr::parse(self.view_id)
.map_err(|_| ErrorCode::GridViewIdIsEmpty)?
.0;
let field_id = NotEmptyStr::parse(self.field_id)
.map_err(|_| ErrorCode::FieldIdIsEmpty)?
.0;
@ -98,12 +104,17 @@ impl TryInto<DeleteFilterParams> for DeleteFilterPayloadPB {
field_type: self.field_type,
};
Ok(DeleteFilterParams { filter_id, filter_type })
Ok(DeleteFilterParams {
view_id,
filter_id,
filter_type,
})
}
}
#[derive(Debug)]
pub struct DeleteFilterParams {
pub view_id: String,
pub filter_type: FilterType,
pub filter_id: String,
}
@ -122,13 +133,21 @@ pub struct AlterFilterPayloadPB {
#[pb(index = 4)]
pub data: Vec<u8>,
#[pb(index = 5)]
pub view_id: String,
}
impl AlterFilterPayloadPB {
#[allow(dead_code)]
pub fn new<T: TryInto<Bytes, Error = ::protobuf::ProtobufError>>(field_rev: &FieldRevision, data: T) -> Self {
pub fn new<T: TryInto<Bytes, Error = ::protobuf::ProtobufError>>(
view_id: &str,
field_rev: &FieldRevision,
data: T,
) -> Self {
let data = data.try_into().unwrap_or_else(|_| Bytes::new());
Self {
view_id: view_id.to_owned(),
field_id: field_rev.id.clone(),
field_type: field_rev.ty.into(),
filter_id: None,
@ -141,6 +160,10 @@ impl TryInto<AlterFilterParams> for AlterFilterPayloadPB {
type Error = ErrorCode;
fn try_into(self) -> Result<AlterFilterParams, Self::Error> {
let view_id = NotEmptyStr::parse(self.view_id)
.map_err(|_| ErrorCode::GridViewIdIsEmpty)?
.0;
let field_id = NotEmptyStr::parse(self.field_id)
.map_err(|_| ErrorCode::FieldIdIsEmpty)?
.0;
@ -185,6 +208,7 @@ impl TryInto<AlterFilterParams> for AlterFilterPayloadPB {
}
Ok(AlterFilterParams {
view_id,
field_id,
filter_id,
field_type: self.field_type.into(),
@ -196,6 +220,7 @@ impl TryInto<AlterFilterParams> for AlterFilterPayloadPB {
#[derive(Debug)]
pub struct AlterFilterParams {
pub view_id: String,
pub field_id: String,
/// Create a new filter if the filter_id is None
pub filter_id: Option<String>,

View File

@ -35,16 +35,19 @@ impl std::default::Default for GridSortConditionPB {
#[derive(ProtoBuf, Debug, Default, Clone)]
pub struct AlterSortPayloadPB {
#[pb(index = 1)]
pub field_id: String,
pub view_id: String,
#[pb(index = 2)]
pub field_id: String,
#[pb(index = 3)]
pub field_type: FieldType,
/// Create a new filter if the filter_id is None
#[pb(index = 3, one_of)]
#[pb(index = 4, one_of)]
pub sort_id: Option<String>,
#[pb(index = 4)]
#[pb(index = 5)]
pub condition: GridSortConditionPB,
}
@ -52,6 +55,10 @@ impl TryInto<AlterSortParams> for AlterSortPayloadPB {
type Error = ErrorCode;
fn try_into(self) -> Result<AlterSortParams, Self::Error> {
let view_id = NotEmptyStr::parse(self.view_id)
.map_err(|_| ErrorCode::GridViewIdIsEmpty)?
.0;
let field_id = NotEmptyStr::parse(self.field_id)
.map_err(|_| ErrorCode::FieldIdIsEmpty)?
.0;
@ -61,6 +68,7 @@ impl TryInto<AlterSortParams> for AlterSortPayloadPB {
};
Ok(AlterSortParams {
view_id,
field_id,
sort_id,
field_type: self.field_type.into(),
@ -71,6 +79,7 @@ impl TryInto<AlterSortParams> for AlterSortPayloadPB {
#[derive(Debug)]
pub struct AlterSortParams {
pub view_id: String,
pub field_id: String,
/// Create a new sort if the sort is None
pub sort_id: Option<String>,
@ -81,12 +90,15 @@ pub struct AlterSortParams {
#[derive(ProtoBuf, Debug, Default, Clone)]
pub struct DeleteSortPayloadPB {
#[pb(index = 1)]
pub field_id: String,
pub view_id: String,
#[pb(index = 2)]
pub field_type: FieldType,
pub field_id: String,
#[pb(index = 3)]
pub field_type: FieldType,
#[pb(index = 4)]
pub sort_id: String,
}
@ -94,6 +106,9 @@ impl TryInto<DeleteSortParams> for DeleteSortPayloadPB {
type Error = ErrorCode;
fn try_into(self) -> Result<DeleteSortParams, Self::Error> {
let view_id = NotEmptyStr::parse(self.view_id)
.map_err(|_| ErrorCode::GridViewIdIsEmpty)?
.0;
let field_id = NotEmptyStr::parse(self.field_id)
.map_err(|_| ErrorCode::FieldIdIsEmpty)?
.0;
@ -107,12 +122,32 @@ impl TryInto<DeleteSortParams> for DeleteSortPayloadPB {
field_type: self.field_type,
};
Ok(DeleteSortParams { sort_type, sort_id })
Ok(DeleteSortParams {
view_id,
sort_type,
sort_id,
})
}
}
#[derive(Debug)]
pub struct DeleteSortParams {
pub view_id: String,
pub sort_type: SortType,
pub sort_id: String,
}
#[derive(Debug, Default, ProtoBuf)]
pub struct SortChangesetNotificationPB {
#[pb(index = 1)]
pub view_id: String,
#[pb(index = 2)]
pub insert_sorts: Vec<GridSortPB>,
#[pb(index = 3)]
pub delete_sorts: Vec<GridSortPB>,
#[pb(index = 4)]
pub update_sorts: Vec<GridSortPB>,
}

View File

@ -55,7 +55,7 @@ impl FilterController {
task_scheduler,
notifier,
};
this.cache_filters(filter_revs).await;
this.refresh_filters(filter_revs).await;
this
}
@ -191,17 +191,14 @@ impl FilterController {
}
#[tracing::instrument(level = "trace", skip(self))]
pub async fn did_receive_filter_changed(
&mut self,
changeset: FilterChangeset,
) -> Option<FilterChangesetNotificationPB> {
pub async fn did_receive_changes(&mut self, changeset: FilterChangeset) -> Option<FilterChangesetNotificationPB> {
let mut notification: Option<FilterChangesetNotificationPB> = None;
if let Some(filter_type) = &changeset.insert_filter {
if let Some(filter) = self.filter_from_filter_type(filter_type).await {
notification = Some(FilterChangesetNotificationPB::from_insert(&self.view_id, vec![filter]));
}
if let Some(filter_rev) = self.delegate.get_filter_rev(filter_type.clone()).await {
let _ = self.cache_filters(vec![filter_rev]).await;
let _ = self.refresh_filters(vec![filter_rev]).await;
}
}
@ -218,7 +215,7 @@ impl FilterController {
// Update the corresponding filter in the cache
if let Some(filter_rev) = self.delegate.get_filter_rev(updated_filter_type.new.clone()).await {
let _ = self.cache_filters(vec![filter_rev]).await;
let _ = self.refresh_filters(vec![filter_rev]).await;
}
if let Some(filter_id) = filter_id {
@ -253,7 +250,7 @@ impl FilterController {
}
#[tracing::instrument(level = "trace", skip_all)]
async fn cache_filters(&mut self, filter_revs: Vec<Arc<FilterRevision>>) {
async fn refresh_filters(&mut self, filter_revs: Vec<Arc<FilterRevision>>) {
for filter_rev in filter_revs {
if let Some(field_rev) = self.delegate.get_field_rev(&filter_rev.field_id).await {
let filter_type = FilterType::from(&field_rev);

View File

@ -589,11 +589,13 @@ impl GridRevisionEditor {
}
pub async fn delete_sort(&self, params: DeleteSortParams) -> FlowyResult<()> {
todo!()
let _ = self.view_manager.delete_sort(params).await?;
Ok(())
}
pub async fn create_or_update_sort(&self, params: AlterSortParams) -> FlowyResult<()> {
todo!()
let _ = self.view_manager.create_or_update_sort(params).await?;
Ok(())
}
pub async fn move_row(&self, params: MoveRowParams) -> FlowyResult<()> {

View File

@ -13,6 +13,8 @@ impl GridSettingChangesetBuilder {
delete_filter: None,
insert_group: None,
delete_group: None,
alert_sort: None,
delete_sort: None,
};
Self { params }
}

View File

@ -1,4 +1,5 @@
use crate::services::sort::SortType;
use crate::entities::{GridSortPB, SortChangesetNotificationPB};
use crate::services::sort::{SortChangeset, SortType};
use flowy_task::TaskDispatcher;
use grid_rev_model::{FieldRevision, RowRevision, SortRevision};
use lib_infra::future::Fut;
@ -16,6 +17,7 @@ pub struct SortController {
handler_id: String,
delegate: Box<dyn SortDelegate>,
task_scheduler: Arc<RwLock<TaskDispatcher>>,
sorts: Vec<GridSortPB>,
}
impl SortController {
@ -28,6 +30,7 @@ impl SortController {
handler_id: handler_id.to_string(),
delegate: Box::new(delegate),
task_scheduler,
sorts: vec![],
}
}
@ -42,4 +45,8 @@ impl SortController {
pub fn sort_rows(&self, rows: &mut Vec<Arc<RowRevision>>) {
todo!()
}
pub async fn did_receive_changes(&self, changeset: SortChangeset) -> Option<SortChangesetNotificationPB> {
todo!()
}
}

View File

@ -1,5 +1,6 @@
use crate::entities::FieldType;
use grid_rev_model::FieldTypeRevision;
use crate::entities::{AlterSortParams, FieldType};
use grid_rev_model::{FieldRevision, FieldTypeRevision};
use std::sync::Arc;
#[derive(Hash, Eq, PartialEq, Debug, Clone)]
pub struct SortType {
@ -12,3 +13,54 @@ impl Into<FieldTypeRevision> for SortType {
self.field_type.into()
}
}
impl std::convert::From<&AlterSortParams> for SortType {
fn from(params: &AlterSortParams) -> Self {
Self {
field_id: params.field_id.clone(),
field_type: params.field_type.into(),
}
}
}
impl std::convert::From<&Arc<FieldRevision>> for SortType {
fn from(rev: &Arc<FieldRevision>) -> Self {
Self {
field_id: rev.id.clone(),
field_type: rev.ty.into(),
}
}
}
#[derive(Debug)]
pub struct SortChangeset {
pub(crate) insert_sort: Option<SortType>,
pub(crate) update_sort: Option<SortType>,
pub(crate) delete_sort: Option<SortType>,
}
impl SortChangeset {
pub fn from_insert(sort: SortType) -> Self {
Self {
insert_sort: Some(sort),
update_sort: None,
delete_sort: None,
}
}
pub fn from_update(sort: SortType) -> Self {
Self {
insert_sort: None,
update_sort: Some(sort),
delete_sort: None,
}
}
pub fn from_delete(sort: SortType) -> Self {
Self {
insert_sort: None,
update_sort: None,
delete_sort: Some(sort),
}
}
}

View File

@ -7,7 +7,7 @@ use crate::services::group::{
GroupController, MoveGroupRowContext,
};
use crate::services::row::GridBlockRowRevision;
use crate::services::sort::{SortController, SortTaskHandler};
use crate::services::sort::{SortChangeset, SortController, SortTaskHandler, SortType};
use crate::services::view_editor::changed_notifier::GridViewChangedNotifier;
use crate::services::view_editor::trait_impl::*;
use crate::services::view_editor::GridViewChangedReceiverRunner;
@ -18,7 +18,8 @@ use flowy_revision::RevisionManager;
use flowy_sync::client_grid::{make_grid_view_operations, GridViewRevisionChangeset, GridViewRevisionPad};
use flowy_task::TaskDispatcher;
use grid_rev_model::{
gen_grid_filter_id, FieldRevision, FieldTypeRevision, FilterRevision, LayoutRevision, RowChangeset, RowRevision,
gen_grid_filter_id, gen_grid_sort_id, FieldRevision, FieldTypeRevision, FilterRevision, LayoutRevision,
RowChangeset, RowRevision, SortRevision,
};
use lib_infra::async_trait::async_trait;
use lib_infra::future::Fut;
@ -373,6 +374,70 @@ impl GridViewRevisionEditor {
.await
}
pub async fn insert_view_sort(&self, params: AlterSortParams) -> FlowyResult<()> {
let sort_type = SortType::from(&params);
let is_exist = params.sort_id.is_some();
let sort_id = match params.sort_id {
None => gen_grid_sort_id(),
Some(sort_id) => sort_id,
};
let sort_rev = SortRevision {
id: sort_id,
field_id: params.field_id.clone(),
field_type: params.field_type,
condition: params.condition,
};
let mut sort_controller = self.sort_controller.write().await;
let changeset = if is_exist {
self.modify(|pad| {
let changeset = pad.update_sort(&params.field_id, sort_rev)?;
Ok(changeset)
})
.await?;
sort_controller
.did_receive_changes(SortChangeset::from_update(sort_type))
.await
} else {
self.modify(|pad| {
let changeset = pad.insert_sort(&params.field_id, sort_rev)?;
Ok(changeset)
})
.await?;
sort_controller
.did_receive_changes(SortChangeset::from_insert(sort_type))
.await
};
if let Some(changeset) = changeset {
self.notify_did_update_sort(changeset).await;
}
Ok(())
}
pub async fn delete_view_sort(&self, params: DeleteSortParams) -> FlowyResult<()> {
let sort_type = SortType::from(&params);
let changeset = self
.sort_controller
.write()
.await
.did_receive_changes(SortChangeset::from_delete(sort_type.clone()))
.await;
let _ = self
.modify(|pad| {
let changeset = pad.delete_sort(&params.sort_id, &sort_type.field_id, sort_type.field_type)?;
Ok(changeset)
})
.await?;
if changeset.is_some() {
self.notify_did_update_sort(changeset.unwrap()).await;
}
Ok(())
}
#[tracing::instrument(level = "trace", skip(self), err)]
pub async fn insert_view_filter(&self, params: AlterFilterParams) -> FlowyResult<()> {
let filter_type = FilterType::from(&params);
@ -401,7 +466,7 @@ impl GridViewRevisionEditor {
})
.await?;
filter_controller
.did_receive_filter_changed(FilterChangeset::from_update(UpdatedFilterType::new(
.did_receive_changes(FilterChangeset::from_update(UpdatedFilterType::new(
old_filter_type,
filter_type,
)))
@ -413,7 +478,7 @@ impl GridViewRevisionEditor {
})
.await?;
filter_controller
.did_receive_filter_changed(FilterChangeset::from_insert(filter_type))
.did_receive_changes(FilterChangeset::from_insert(filter_type))
.await
};
@ -430,7 +495,7 @@ impl GridViewRevisionEditor {
.filter_controller
.write()
.await
.did_receive_filter_changed(FilterChangeset::from_delete(filter_type.clone()))
.did_receive_changes(FilterChangeset::from_delete(filter_type.clone()))
.await;
let _ = self
@ -461,7 +526,7 @@ impl GridViewRevisionEditor {
.filter_controller
.write()
.await
.did_receive_filter_changed(filter_changeset)
.did_receive_changes(filter_changeset)
.await
{
self.notify_did_update_filter(changeset).await;
@ -532,6 +597,12 @@ impl GridViewRevisionEditor {
.send();
}
pub async fn notify_did_update_sort(&self, changeset: SortChangesetNotificationPB) {
send_dart_notification(&changeset.view_id, GridDartNotification::DidUpdateSort)
.payload(changeset)
.send();
}
async fn notify_did_update_view(&self, changeset: GroupViewChangesetPB) {
send_dart_notification(&self.view_id, GridDartNotification::DidUpdateGroupView)
.payload(changeset)

View File

@ -1,6 +1,6 @@
use crate::entities::{
AlterFilterParams, CreateRowParams, DeleteFilterParams, DeleteGroupParams, GridSettingPB, InsertGroupParams,
MoveGroupParams, RepeatedGroupPB, RowPB,
AlterFilterParams, AlterSortParams, CreateRowParams, DeleteFilterParams, DeleteGroupParams, DeleteSortParams,
GridSettingPB, InsertGroupParams, MoveGroupParams, RepeatedGroupPB, RowPB,
};
use crate::manager::GridUser;
use crate::services::block_manager::GridBlockEvent;
@ -136,15 +136,25 @@ impl GridViewManager {
}
pub async fn create_or_update_filter(&self, params: AlterFilterParams) -> FlowyResult<()> {
let view_editor = self.get_default_view_editor().await?;
let view_editor = self.get_view_editor(&params.view_id).await?;
view_editor.insert_view_filter(params).await
}
pub async fn delete_filter(&self, params: DeleteFilterParams) -> FlowyResult<()> {
let view_editor = self.get_default_view_editor().await?;
let view_editor = self.get_view_editor(&params.view_id).await?;
view_editor.delete_view_filter(params).await
}
pub async fn create_or_update_sort(&self, params: AlterSortParams) -> FlowyResult<()> {
let view_editor = self.get_view_editor(&params.view_id).await?;
view_editor.insert_view_sort(params).await
}
pub async fn delete_sort(&self, params: DeleteSortParams) -> FlowyResult<()> {
let view_editor = self.get_view_editor(&params.view_id).await?;
view_editor.delete_view_sort(params).await
}
pub async fn load_groups(&self) -> FlowyResult<RepeatedGroupPB> {
let view_editor = self.get_default_view_editor().await?;
let groups = view_editor.load_view_groups().await?;

View File

@ -10,6 +10,7 @@ use flowy_grid::entities::{AlterFilterParams, AlterFilterPayloadPB, DeleteFilter
use flowy_grid::services::field::{SelectOptionCellChangeset, SelectOptionIds};
use flowy_grid::services::setting::GridSettingChangesetBuilder;
use grid_rev_model::{FieldRevision, FieldTypeRevision};
use flowy_database::schema::view_table::dsl::view_table;
use flowy_grid::services::cell::insert_select_option_cell;
use flowy_grid::services::filter::FilterType;
use flowy_grid::services::view_editor::GridViewChanged;
@ -98,6 +99,10 @@ impl GridFilterTest {
}
}
fn view_id(&self) -> String {
self.grid_id.clone()
}
pub async fn get_all_filters(&self) -> Vec<FilterPB> {
self.editor.get_all_filters().await.unwrap()
}
@ -128,11 +133,14 @@ impl GridFilterTest {
content
};
let payload =
AlterFilterPayloadPB::new(field_rev, text_filter);
AlterFilterPayloadPB::new(
view_id: self.view_id(),
field_rev, text_filter);
self.insert_filter(payload).await;
}
FilterScript::UpdateTextFilter { filter, condition, content} => {
let params = AlterFilterParams {
view_id: self.view_id(),
field_id: filter.field_id,
filter_id: Some(filter.id),
field_type: filter.field_type.into(),
@ -148,7 +156,9 @@ impl GridFilterTest {
content
};
let payload =
AlterFilterPayloadPB::new(field_rev, number_filter);
AlterFilterPayloadPB::new(
view_id: self.view_id(),
field_rev, number_filter);
self.insert_filter(payload).await;
}
FilterScript::CreateCheckboxFilter {condition} => {
@ -157,7 +167,7 @@ impl GridFilterTest {
condition
};
let payload =
AlterFilterPayloadPB::new(field_rev, checkbox_filter);
AlterFilterPayloadPB::new(view_id: self.view_id(), field_rev, checkbox_filter);
self.insert_filter(payload).await;
}
FilterScript::CreateDateFilter { condition, start, end, timestamp} => {
@ -170,21 +180,21 @@ impl GridFilterTest {
};
let payload =
AlterFilterPayloadPB::new(field_rev, date_filter);
AlterFilterPayloadPB::new(view_id: self.view_id(), field_rev, date_filter);
self.insert_filter(payload).await;
}
FilterScript::CreateMultiSelectFilter { condition, option_ids} => {
let field_rev = self.get_first_field_rev(FieldType::MultiSelect);
let filter = SelectOptionFilterPB { condition, option_ids };
let payload =
AlterFilterPayloadPB::new(field_rev, filter);
AlterFilterPayloadPB::new(view_id: self.view_id(),field_rev, filter);
self.insert_filter(payload).await;
}
FilterScript::CreateSingleSelectFilter { condition, option_ids} => {
let field_rev = self.get_first_field_rev(FieldType::SingleSelect);
let filter = SelectOptionFilterPB { condition, option_ids };
let payload =
AlterFilterPayloadPB::new(field_rev, filter);
AlterFilterPayloadPB::new(view_id: self.view_id(),field_rev, filter);
self.insert_filter(payload).await;
}
FilterScript::CreateChecklistFilter { condition} => {
@ -192,7 +202,7 @@ impl GridFilterTest {
// let type_option = self.get_checklist_type_option(&field_rev.id);
let filter = ChecklistFilterPB { condition };
let payload =
AlterFilterPayloadPB::new(field_rev, filter);
AlterFilterPayloadPB::new(view_id: self.view_id(),field_rev, filter);
self.insert_filter(payload).await;
}
FilterScript::AssertFilterCount { count } => {
@ -206,7 +216,7 @@ impl GridFilterTest {
}
FilterScript::DeleteFilter { filter_id, filter_type } => {
let params = DeleteFilterParams { filter_type, filter_id };
let params = DeleteFilterParams { view_id: self.view_id(),filter_type, filter_id };
let _ = self.editor.delete_filter(params).await.unwrap();
}
FilterScript::AssertGridSetting { expected_setting } => {
@ -226,7 +236,7 @@ impl GridFilterTest {
}
}
FilterScript::AssertNumberOfVisibleRows { expected } => {
let grid = self.editor.get_grid().await.unwrap();
let grid = self.editor.get_grid(&self.view_id()).await.unwrap();
assert_eq!(grid.rows.len(), expected);
}
FilterScript::Wait { millisecond } => {

View File

@ -146,6 +146,18 @@ impl GridViewRevisionPad {
.get_object(field_id, field_type_rev, |sort| sort.id == sort_id)
}
pub fn insert_sort(
&mut self,
sort_id: &str,
sort_rev: SortRevision,
) -> CollaborateResult<Option<GridViewRevisionChangeset>> {
self.modify(|view| {
let field_type = sort_rev.field_type;
view.sorts.add_object(sort_id, &field_type, sort_rev);
Ok(Some(()))
})
}
pub fn update_sort(
&mut self,
field_id: &str,
@ -165,14 +177,15 @@ impl GridViewRevisionPad {
})
}
pub fn delete_sort(
pub fn delete_sort<T: Into<FieldTypeRevision>>(
&mut self,
sort_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(sorts) = view.sorts.get_mut_objects(field_id, field_type) {
if let Some(sorts) = view.sorts.get_mut_objects(field_id, &field_type) {
sorts.retain(|sort| sort.id != sort_id);
Ok(Some(()))
} else {