mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: reload group when group by new field
This commit is contained in:
@ -110,9 +110,11 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
|||||||
emit(state.copyWith(noneOrError: some(error)));
|
emit(state.copyWith(noneOrError: some(error)));
|
||||||
},
|
},
|
||||||
didReceiveGroups: (List<GroupPB> groups) {
|
didReceiveGroups: (List<GroupPB> groups) {
|
||||||
emit(state.copyWith(
|
emit(
|
||||||
groupIds: groups.map((group) => group.groupId).toList(),
|
state.copyWith(
|
||||||
));
|
groupIds: groups.map((group) => group.groupId).toList(),
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -154,6 +156,23 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void initializeGroups(List<GroupPB> groups) {
|
void initializeGroups(List<GroupPB> groups) {
|
||||||
|
for (var controller in groupControllers.values) {
|
||||||
|
controller.dispose();
|
||||||
|
}
|
||||||
|
groupControllers.clear();
|
||||||
|
boardController.clear();
|
||||||
|
|
||||||
|
//
|
||||||
|
List<AFBoardColumnData> columns = groups.map((group) {
|
||||||
|
return AFBoardColumnData(
|
||||||
|
id: group.groupId,
|
||||||
|
name: group.desc,
|
||||||
|
items: _buildRows(group),
|
||||||
|
customData: group,
|
||||||
|
);
|
||||||
|
}).toList();
|
||||||
|
boardController.addColumns(columns);
|
||||||
|
|
||||||
for (final group in groups) {
|
for (final group in groups) {
|
||||||
final delegate = GroupControllerDelegateImpl(
|
final delegate = GroupControllerDelegateImpl(
|
||||||
controller: boardController,
|
controller: boardController,
|
||||||
@ -184,16 +203,6 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
didLoadGroups: (groups) {
|
didLoadGroups: (groups) {
|
||||||
List<AFBoardColumnData> columns = groups.map((group) {
|
|
||||||
return AFBoardColumnData(
|
|
||||||
id: group.groupId,
|
|
||||||
name: group.desc,
|
|
||||||
items: _buildRows(group),
|
|
||||||
customData: group,
|
|
||||||
);
|
|
||||||
}).toList();
|
|
||||||
|
|
||||||
boardController.addColumns(columns);
|
|
||||||
initializeGroups(groups);
|
initializeGroups(groups);
|
||||||
add(BoardEvent.didReceiveGroups(groups));
|
add(BoardEvent.didReceiveGroups(groups));
|
||||||
},
|
},
|
||||||
@ -204,18 +213,19 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
|||||||
//
|
//
|
||||||
},
|
},
|
||||||
onUpdatedGroup: (updatedGroups) {
|
onUpdatedGroup: (updatedGroups) {
|
||||||
//
|
|
||||||
for (final group in updatedGroups) {
|
for (final group in updatedGroups) {
|
||||||
final columnController =
|
final columnController =
|
||||||
boardController.getColumnController(group.groupId);
|
boardController.getColumnController(group.groupId);
|
||||||
if (columnController != null) {
|
columnController?.updateColumnName(group.desc);
|
||||||
columnController.updateColumnName(group.desc);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onError: (err) {
|
onError: (err) {
|
||||||
Log.error(err);
|
Log.error(err);
|
||||||
},
|
},
|
||||||
|
onResetGroups: (groups) {
|
||||||
|
initializeGroups(groups);
|
||||||
|
add(BoardEvent.didReceiveGroups(groups));
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ typedef DidLoadGroups = void Function(List<GroupPB>);
|
|||||||
typedef OnUpdatedGroup = void Function(List<GroupPB>);
|
typedef OnUpdatedGroup = void Function(List<GroupPB>);
|
||||||
typedef OnDeletedGroup = void Function(List<String>);
|
typedef OnDeletedGroup = void Function(List<String>);
|
||||||
typedef OnInsertedGroup = void Function(List<InsertedGroupPB>);
|
typedef OnInsertedGroup = void Function(List<InsertedGroupPB>);
|
||||||
|
typedef OnResetGroups = void Function(List<GroupPB>);
|
||||||
|
|
||||||
typedef OnRowsChanged = void Function(
|
typedef OnRowsChanged = void Function(
|
||||||
List<RowInfo>,
|
List<RowInfo>,
|
||||||
@ -65,6 +66,7 @@ class BoardDataController {
|
|||||||
required OnUpdatedGroup onUpdatedGroup,
|
required OnUpdatedGroup onUpdatedGroup,
|
||||||
required OnDeletedGroup onDeletedGroup,
|
required OnDeletedGroup onDeletedGroup,
|
||||||
required OnInsertedGroup onInsertedGroup,
|
required OnInsertedGroup onInsertedGroup,
|
||||||
|
required OnResetGroups onResetGroups,
|
||||||
required OnError? onError,
|
required OnError? onError,
|
||||||
}) {
|
}) {
|
||||||
_onGridChanged = onGridChanged;
|
_onGridChanged = onGridChanged;
|
||||||
@ -77,24 +79,32 @@ class BoardDataController {
|
|||||||
_onFieldsChanged?.call(UnmodifiableListView(fields));
|
_onFieldsChanged?.call(UnmodifiableListView(fields));
|
||||||
});
|
});
|
||||||
|
|
||||||
_listener.start(onBoardChanged: (result) {
|
_listener.start(
|
||||||
result.fold(
|
onBoardChanged: (result) {
|
||||||
(changeset) {
|
result.fold(
|
||||||
if (changeset.updateGroups.isNotEmpty) {
|
(changeset) {
|
||||||
onUpdatedGroup.call(changeset.updateGroups);
|
if (changeset.updateGroups.isNotEmpty) {
|
||||||
}
|
onUpdatedGroup.call(changeset.updateGroups);
|
||||||
|
}
|
||||||
|
|
||||||
if (changeset.insertedGroups.isNotEmpty) {
|
if (changeset.insertedGroups.isNotEmpty) {
|
||||||
onInsertedGroup.call(changeset.insertedGroups);
|
onInsertedGroup.call(changeset.insertedGroups);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changeset.deletedGroups.isNotEmpty) {
|
if (changeset.deletedGroups.isNotEmpty) {
|
||||||
onDeletedGroup.call(changeset.deletedGroups);
|
onDeletedGroup.call(changeset.deletedGroups);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
(e) => _onError?.call(e),
|
(e) => _onError?.call(e),
|
||||||
);
|
);
|
||||||
});
|
},
|
||||||
|
onGroupByNewField: (result) {
|
||||||
|
result.fold(
|
||||||
|
(groups) => onResetGroups(groups),
|
||||||
|
(e) => _onError?.call(e),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Either<Unit, FlowyError>> loadData() async {
|
Future<Either<Unit, FlowyError>> loadData() async {
|
||||||
|
@ -5,20 +5,26 @@ import 'package:flowy_infra/notifier.dart';
|
|||||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-grid/group.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/group_changeset.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/group_changeset.pb.dart';
|
||||||
|
|
||||||
typedef UpdateBoardNotifiedValue = Either<GroupViewChangesetPB, FlowyError>;
|
typedef GroupUpdateValue = Either<GroupViewChangesetPB, FlowyError>;
|
||||||
|
typedef GroupByNewFieldValue = Either<List<GroupPB>, FlowyError>;
|
||||||
|
|
||||||
class BoardListener {
|
class BoardListener {
|
||||||
final String viewId;
|
final String viewId;
|
||||||
PublishNotifier<UpdateBoardNotifiedValue>? _groupNotifier = PublishNotifier();
|
PublishNotifier<GroupUpdateValue>? _groupUpdateNotifier = PublishNotifier();
|
||||||
|
PublishNotifier<GroupByNewFieldValue>? _groupByNewFieldNotifier =
|
||||||
|
PublishNotifier();
|
||||||
GridNotificationListener? _listener;
|
GridNotificationListener? _listener;
|
||||||
BoardListener(this.viewId);
|
BoardListener(this.viewId);
|
||||||
|
|
||||||
void start({
|
void start({
|
||||||
required void Function(UpdateBoardNotifiedValue) onBoardChanged,
|
required void Function(GroupUpdateValue) onBoardChanged,
|
||||||
|
required void Function(GroupByNewFieldValue) onGroupByNewField,
|
||||||
}) {
|
}) {
|
||||||
_groupNotifier?.addPublishListener(onBoardChanged);
|
_groupUpdateNotifier?.addPublishListener(onBoardChanged);
|
||||||
|
_groupByNewFieldNotifier?.addPublishListener(onGroupByNewField);
|
||||||
_listener = GridNotificationListener(
|
_listener = GridNotificationListener(
|
||||||
objectId: viewId,
|
objectId: viewId,
|
||||||
handler: _handler,
|
handler: _handler,
|
||||||
@ -32,9 +38,16 @@ class BoardListener {
|
|||||||
switch (ty) {
|
switch (ty) {
|
||||||
case GridNotification.DidUpdateGroupView:
|
case GridNotification.DidUpdateGroupView:
|
||||||
result.fold(
|
result.fold(
|
||||||
(payload) => _groupNotifier?.value =
|
(payload) => _groupUpdateNotifier?.value =
|
||||||
left(GroupViewChangesetPB.fromBuffer(payload)),
|
left(GroupViewChangesetPB.fromBuffer(payload)),
|
||||||
(error) => _groupNotifier?.value = right(error),
|
(error) => _groupUpdateNotifier?.value = right(error),
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case GridNotification.DidGroupByNewField:
|
||||||
|
result.fold(
|
||||||
|
(payload) => _groupByNewFieldNotifier?.value =
|
||||||
|
left(GroupViewChangesetPB.fromBuffer(payload).newGroups),
|
||||||
|
(error) => _groupByNewFieldNotifier?.value = right(error),
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -44,7 +57,10 @@ class BoardListener {
|
|||||||
|
|
||||||
Future<void> stop() async {
|
Future<void> stop() async {
|
||||||
await _listener?.stop();
|
await _listener?.stop();
|
||||||
_groupNotifier?.dispose();
|
_groupUpdateNotifier?.dispose();
|
||||||
_groupNotifier = null;
|
_groupUpdateNotifier = null;
|
||||||
|
|
||||||
|
_groupByNewFieldNotifier?.dispose();
|
||||||
|
_groupByNewFieldNotifier = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,6 +89,11 @@ class AFBoardDataController extends ChangeNotifier
|
|||||||
if (columnIds.isNotEmpty && notify) notifyListeners();
|
if (columnIds.isNotEmpty && notify) notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void clear() {
|
||||||
|
_columnDatas.clear();
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
AFBoardColumnDataController? getColumnController(String columnId) {
|
AFBoardColumnDataController? getColumnController(String columnId) {
|
||||||
final columnController = _columnControllers[columnId];
|
final columnController = _columnControllers[columnId];
|
||||||
if (columnController == null) {
|
if (columnController == null) {
|
||||||
|
@ -13,6 +13,7 @@ pub enum GridNotification {
|
|||||||
DidUpdateField = 50,
|
DidUpdateField = 50,
|
||||||
DidUpdateGroupView = 60,
|
DidUpdateGroupView = 60,
|
||||||
DidUpdateGroup = 61,
|
DidUpdateGroup = 61,
|
||||||
|
DidGroupByNewField = 62,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::default::Default for GridNotification {
|
impl std::default::Default for GridNotification {
|
||||||
|
@ -145,7 +145,10 @@ pub struct GroupViewChangesetPB {
|
|||||||
|
|
||||||
impl GroupViewChangesetPB {
|
impl GroupViewChangesetPB {
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
self.inserted_groups.is_empty() && self.deleted_groups.is_empty() && self.update_groups.is_empty()
|
self.new_groups.is_empty()
|
||||||
|
&& self.inserted_groups.is_empty()
|
||||||
|
&& self.deleted_groups.is_empty()
|
||||||
|
&& self.update_groups.is_empty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
use crate::entities::{FieldChangesetParams, FieldType};
|
use crate::services::field::{MultiSelectTypeOptionPB, SingleSelectTypeOptionPB};
|
||||||
use crate::services::field::{select_option_operation, SelectOptionPB};
|
|
||||||
use crate::services::grid_editor::GridRevisionEditor;
|
use crate::services::grid_editor::GridRevisionEditor;
|
||||||
use flowy_error::FlowyResult;
|
use flowy_error::FlowyResult;
|
||||||
use flowy_grid_data_model::revision::{FieldRevision, TypeOptionDataDeserializer, TypeOptionDataFormat};
|
use flowy_grid_data_model::revision::{TypeOptionDataDeserializer, TypeOptionDataFormat};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub async fn edit_field<T>(
|
pub async fn edit_field_type_option<T>(
|
||||||
field_id: &str,
|
field_id: &str,
|
||||||
editor: Arc<GridRevisionEditor>,
|
editor: Arc<GridRevisionEditor>,
|
||||||
action: impl FnOnce(&mut T) -> bool,
|
action: impl FnOnce(&mut T),
|
||||||
) -> FlowyResult<()>
|
) -> FlowyResult<()>
|
||||||
where
|
where
|
||||||
T: TypeOptionDataDeserializer + TypeOptionDataFormat,
|
T: TypeOptionDataDeserializer + TypeOptionDataFormat,
|
||||||
@ -19,29 +18,28 @@ where
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Some(mut type_option) = get_type_option.await {
|
if let Some(mut type_option) = get_type_option.await {
|
||||||
if action(&mut type_option) {
|
action(&mut type_option);
|
||||||
let changeset = FieldChangesetParams { ..Default::default() };
|
let bytes = type_option.protobuf_bytes().to_vec();
|
||||||
let _ = editor.update_field(changeset).await?;
|
let _ = editor
|
||||||
}
|
.update_field_type_option(&editor.grid_id, field_id, bytes)
|
||||||
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_single_select_option(field_rev: &mut FieldRevision, options: Vec<SelectOptionPB>) -> FlowyResult<()> {
|
pub async fn edit_single_select_type_option(
|
||||||
if options.is_empty() {
|
field_id: &str,
|
||||||
return Ok(());
|
editor: Arc<GridRevisionEditor>,
|
||||||
}
|
action: impl FnOnce(&mut SingleSelectTypeOptionPB),
|
||||||
let mut type_option = select_option_operation(field_rev)?;
|
) -> FlowyResult<()> {
|
||||||
options.into_iter().for_each(|option| type_option.insert_option(option));
|
edit_field_type_option(field_id, editor, action).await
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_multi_select_option(field_rev: &mut FieldRevision, options: Vec<SelectOptionPB>) -> FlowyResult<()> {
|
pub async fn edit_multi_select_type_option(
|
||||||
if options.is_empty() {
|
field_id: &str,
|
||||||
return Ok(());
|
editor: Arc<GridRevisionEditor>,
|
||||||
}
|
action: impl FnOnce(&mut MultiSelectTypeOptionPB),
|
||||||
let mut type_option = select_option_operation(field_rev)?;
|
) -> FlowyResult<()> {
|
||||||
options.into_iter().for_each(|option| type_option.insert_option(option));
|
edit_field_type_option(field_id, editor, action).await
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
@ -212,7 +212,8 @@ impl GridRevisionEditor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn group_field(&self, field_id: &str) -> FlowyResult<()> {
|
pub async fn group_field(&self, field_id: &str) -> FlowyResult<()> {
|
||||||
todo!()
|
let _ = self.view_manager.group_by_field(field_id).await?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn switch_to_field_type(&self, field_id: &str, field_type: &FieldType) -> FlowyResult<()> {
|
pub async fn switch_to_field_type(&self, field_id: &str, field_type: &FieldType) -> FlowyResult<()> {
|
||||||
|
@ -7,7 +7,8 @@ use crate::entities::{
|
|||||||
use crate::services::grid_editor_task::GridServiceTaskScheduler;
|
use crate::services::grid_editor_task::GridServiceTaskScheduler;
|
||||||
use crate::services::grid_view_manager::{GridViewFieldDelegate, GridViewRowDelegate};
|
use crate::services::grid_view_manager::{GridViewFieldDelegate, GridViewRowDelegate};
|
||||||
use crate::services::group::{
|
use crate::services::group::{
|
||||||
make_group_controller, GroupConfigurationReader, GroupConfigurationWriter, GroupController, MoveGroupRowContext,
|
find_group_field, make_group_controller, GroupConfigurationReader, GroupConfigurationWriter, GroupController,
|
||||||
|
MoveGroupRowContext,
|
||||||
};
|
};
|
||||||
use flowy_error::{FlowyError, FlowyResult};
|
use flowy_error::{FlowyError, FlowyResult};
|
||||||
use flowy_grid_data_model::revision::{
|
use flowy_grid_data_model::revision::{
|
||||||
@ -34,7 +35,6 @@ pub struct GridViewRevisionEditor {
|
|||||||
group_controller: Arc<RwLock<Box<dyn GroupController>>>,
|
group_controller: Arc<RwLock<Box<dyn GroupController>>>,
|
||||||
scheduler: Arc<dyn GridServiceTaskScheduler>,
|
scheduler: Arc<dyn GridServiceTaskScheduler>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GridViewRevisionEditor {
|
impl GridViewRevisionEditor {
|
||||||
#[tracing::instrument(level = "trace", skip_all, err)]
|
#[tracing::instrument(level = "trace", skip_all, err)]
|
||||||
pub(crate) async fn new(
|
pub(crate) async fn new(
|
||||||
@ -52,25 +52,15 @@ impl GridViewRevisionEditor {
|
|||||||
let view_revision_pad = rev_manager.load::<GridViewRevisionPadBuilder>(Some(cloud)).await?;
|
let view_revision_pad = rev_manager.load::<GridViewRevisionPadBuilder>(Some(cloud)).await?;
|
||||||
let pad = Arc::new(RwLock::new(view_revision_pad));
|
let pad = Arc::new(RwLock::new(view_revision_pad));
|
||||||
let rev_manager = Arc::new(rev_manager);
|
let rev_manager = Arc::new(rev_manager);
|
||||||
|
let group_controller = new_group_controller(
|
||||||
// Load group
|
user_id.to_owned(),
|
||||||
let configuration_reader = GroupConfigurationReaderImpl(pad.clone());
|
|
||||||
let configuration_writer = GroupConfigurationWriterImpl {
|
|
||||||
user_id: user_id.to_owned(),
|
|
||||||
rev_manager: rev_manager.clone(),
|
|
||||||
view_pad: pad.clone(),
|
|
||||||
};
|
|
||||||
let field_revs = field_delegate.get_field_revs().await;
|
|
||||||
let row_revs = row_delegate.gv_row_revs().await;
|
|
||||||
let group_controller = make_group_controller(
|
|
||||||
view_id.clone(),
|
view_id.clone(),
|
||||||
field_revs,
|
pad.clone(),
|
||||||
row_revs,
|
rev_manager.clone(),
|
||||||
configuration_reader,
|
field_delegate.clone(),
|
||||||
configuration_writer,
|
row_delegate.clone(),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let user_id = user_id.to_owned();
|
let user_id = user_id.to_owned();
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
pad,
|
pad,
|
||||||
@ -258,6 +248,37 @@ impl GridViewRevisionEditor {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn group_by_field(&self, field_id: &str) -> FlowyResult<()> {
|
||||||
|
if let Some(field_rev) = self.field_delegate.get_field_rev(field_id).await {
|
||||||
|
let new_group_controller = new_group_controller_with_field_rev(
|
||||||
|
self.user_id.clone(),
|
||||||
|
self.view_id.clone(),
|
||||||
|
self.pad.clone(),
|
||||||
|
self.rev_manager.clone(),
|
||||||
|
field_rev,
|
||||||
|
self.row_delegate.clone(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let new_groups = new_group_controller.groups().into_iter().map(GroupPB::from).collect();
|
||||||
|
|
||||||
|
*self.group_controller.write().await = new_group_controller;
|
||||||
|
let changeset = GroupViewChangesetPB {
|
||||||
|
view_id: self.view_id.clone(),
|
||||||
|
new_groups,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
debug_assert!(!changeset.is_empty());
|
||||||
|
if !changeset.is_empty() {
|
||||||
|
send_dart_notification(&changeset.view_id, GridNotification::DidGroupByNewField)
|
||||||
|
.payload(changeset)
|
||||||
|
.send();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn notify_did_update_group(&self, changeset: GroupChangesetPB) {
|
pub async fn notify_did_update_group(&self, changeset: GroupChangesetPB) {
|
||||||
send_dart_notification(&changeset.group_id, GridNotification::DidUpdateGroup)
|
send_dart_notification(&changeset.group_id, GridNotification::DidUpdateGroup)
|
||||||
.payload(changeset)
|
.payload(changeset)
|
||||||
@ -314,6 +335,48 @@ impl GridViewRevisionEditor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
async fn new_group_controller(
|
||||||
|
user_id: String,
|
||||||
|
view_id: String,
|
||||||
|
pad: Arc<RwLock<GridViewRevisionPad>>,
|
||||||
|
rev_manager: Arc<RevisionManager>,
|
||||||
|
field_delegate: Arc<dyn GridViewFieldDelegate>,
|
||||||
|
row_delegate: Arc<dyn GridViewRowDelegate>,
|
||||||
|
) -> FlowyResult<Box<dyn GroupController>> {
|
||||||
|
let configuration_reader = GroupConfigurationReaderImpl(pad.clone());
|
||||||
|
let field_revs = field_delegate.get_field_revs().await;
|
||||||
|
// Read the group field or find a new group field
|
||||||
|
let field_rev = configuration_reader
|
||||||
|
.get_configuration()
|
||||||
|
.await
|
||||||
|
.and_then(|configuration| {
|
||||||
|
field_revs
|
||||||
|
.iter()
|
||||||
|
.find(|field_rev| field_rev.id == configuration.field_id)
|
||||||
|
.cloned()
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|| find_group_field(&field_revs).unwrap());
|
||||||
|
|
||||||
|
new_group_controller_with_field_rev(user_id, view_id, pad, rev_manager, field_rev, row_delegate).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn new_group_controller_with_field_rev(
|
||||||
|
user_id: String,
|
||||||
|
view_id: String,
|
||||||
|
pad: Arc<RwLock<GridViewRevisionPad>>,
|
||||||
|
rev_manager: Arc<RevisionManager>,
|
||||||
|
field_rev: Arc<FieldRevision>,
|
||||||
|
row_delegate: Arc<dyn GridViewRowDelegate>,
|
||||||
|
) -> FlowyResult<Box<dyn GroupController>> {
|
||||||
|
let configuration_reader = GroupConfigurationReaderImpl(pad.clone());
|
||||||
|
let configuration_writer = GroupConfigurationWriterImpl {
|
||||||
|
user_id,
|
||||||
|
rev_manager,
|
||||||
|
view_pad: pad,
|
||||||
|
};
|
||||||
|
let row_revs = row_delegate.gv_row_revs().await;
|
||||||
|
make_group_controller(view_id, field_rev, row_revs, configuration_reader, configuration_writer).await
|
||||||
|
}
|
||||||
|
|
||||||
async fn apply_change(
|
async fn apply_change(
|
||||||
user_id: &str,
|
user_id: &str,
|
||||||
@ -353,10 +416,10 @@ impl RevisionObjectBuilder for GridViewRevisionPadBuilder {
|
|||||||
struct GroupConfigurationReaderImpl(Arc<RwLock<GridViewRevisionPad>>);
|
struct GroupConfigurationReaderImpl(Arc<RwLock<GridViewRevisionPad>>);
|
||||||
|
|
||||||
impl GroupConfigurationReader for GroupConfigurationReaderImpl {
|
impl GroupConfigurationReader for GroupConfigurationReaderImpl {
|
||||||
fn get_configuration(&self, field_rev: Arc<FieldRevision>) -> AFFuture<Option<Arc<GroupConfigurationRevision>>> {
|
fn get_configuration(&self) -> AFFuture<Option<Arc<GroupConfigurationRevision>>> {
|
||||||
let view_pad = self.0.clone();
|
let view_pad = self.0.clone();
|
||||||
wrap_future(async move {
|
wrap_future(async move {
|
||||||
let mut groups = view_pad.read().await.groups.get_objects(&field_rev.id, &field_rev.ty)?;
|
let mut groups = view_pad.read().await.get_all_groups();
|
||||||
if groups.is_empty() {
|
if groups.is_empty() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
@ -411,7 +474,7 @@ pub fn make_grid_setting(view_pad: &GridViewRevisionPad, field_revs: &[Arc<Field
|
|||||||
})
|
})
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
let groups_by_field_id = view_pad
|
let groups_by_field_id = view_pad
|
||||||
.get_all_groups(field_revs)
|
.get_groups_by_field_revs(field_revs)
|
||||||
.map(|groups_by_field_id| {
|
.map(|groups_by_field_id| {
|
||||||
groups_by_field_id
|
groups_by_field_id
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -84,6 +84,12 @@ impl GridViewManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn group_by_field(&self, field_id: &str) -> FlowyResult<()> {
|
||||||
|
let view_editor = self.get_default_view_editor().await?;
|
||||||
|
let _ = view_editor.group_by_field(field_id).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) async fn did_update_cell(&self, row_id: &str, _field_id: &str) {
|
pub(crate) async fn did_update_cell(&self, row_id: &str, _field_id: &str) {
|
||||||
self.did_update_row(row_id).await
|
self.did_update_row(row_id).await
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::entities::{GroupPB, GroupViewChangesetPB, InsertedGroupPB};
|
use crate::entities::{GroupPB, GroupViewChangesetPB};
|
||||||
use crate::services::group::{default_group_configuration, GeneratedGroup, Group};
|
use crate::services::group::{default_group_configuration, GeneratedGroup, Group};
|
||||||
use flowy_error::{FlowyError, FlowyResult};
|
use flowy_error::{FlowyError, FlowyResult};
|
||||||
use flowy_grid_data_model::revision::{
|
use flowy_grid_data_model::revision::{
|
||||||
@ -12,7 +12,7 @@ use std::marker::PhantomData;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub trait GroupConfigurationReader: Send + Sync + 'static {
|
pub trait GroupConfigurationReader: Send + Sync + 'static {
|
||||||
fn get_configuration(&self, field_rev: Arc<FieldRevision>) -> AFFuture<Option<Arc<GroupConfigurationRevision>>>;
|
fn get_configuration(&self) -> AFFuture<Option<Arc<GroupConfigurationRevision>>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait GroupConfigurationWriter: Send + Sync + 'static {
|
pub trait GroupConfigurationWriter: Send + Sync + 'static {
|
||||||
@ -38,8 +38,8 @@ impl<T> std::fmt::Display for GroupContext<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct GroupContext<C> {
|
pub struct GroupContext<C> {
|
||||||
view_id: String,
|
pub view_id: String,
|
||||||
pub configuration: Arc<GroupConfigurationRevision>,
|
configuration: Arc<GroupConfigurationRevision>,
|
||||||
configuration_content: PhantomData<C>,
|
configuration_content: PhantomData<C>,
|
||||||
field_rev: Arc<FieldRevision>,
|
field_rev: Arc<FieldRevision>,
|
||||||
groups_map: IndexMap<String, Group>,
|
groups_map: IndexMap<String, Group>,
|
||||||
@ -69,7 +69,7 @@ where
|
|||||||
rows: vec![],
|
rows: vec![],
|
||||||
filter_content: "".to_string(),
|
filter_content: "".to_string(),
|
||||||
};
|
};
|
||||||
let configuration = match reader.get_configuration(field_rev.clone()).await {
|
let configuration = match reader.get_configuration().await {
|
||||||
None => {
|
None => {
|
||||||
let default_configuration = default_group_configuration(&field_rev);
|
let default_configuration = default_group_configuration(&field_rev);
|
||||||
writer
|
writer
|
||||||
@ -133,9 +133,10 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn init_group_revs(
|
pub(crate) fn init_groups(
|
||||||
&mut self,
|
&mut self,
|
||||||
generated_groups: Vec<GeneratedGroup>,
|
generated_groups: Vec<GeneratedGroup>,
|
||||||
|
reset: bool,
|
||||||
) -> FlowyResult<Option<GroupViewChangesetPB>> {
|
) -> FlowyResult<Option<GroupViewChangesetPB>> {
|
||||||
let mut new_groups = vec![];
|
let mut new_groups = vec![];
|
||||||
let mut filter_content_map = HashMap::new();
|
let mut filter_content_map = HashMap::new();
|
||||||
@ -149,7 +150,11 @@ where
|
|||||||
new_group_revs,
|
new_group_revs,
|
||||||
updated_group_revs: _,
|
updated_group_revs: _,
|
||||||
deleted_group_revs,
|
deleted_group_revs,
|
||||||
} = merge_groups(&self.configuration.groups, new_groups);
|
} = if reset {
|
||||||
|
merge_groups(&[], new_groups)
|
||||||
|
} else {
|
||||||
|
merge_groups(&self.configuration.groups, new_groups)
|
||||||
|
};
|
||||||
|
|
||||||
let deleted_group_ids = deleted_group_revs
|
let deleted_group_ids = deleted_group_revs
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@ -180,7 +185,7 @@ where
|
|||||||
group_rev.update_with_other(&old_group);
|
group_rev.update_with_other(&old_group);
|
||||||
|
|
||||||
// Take the GroupRevision if the name has changed
|
// Take the GroupRevision if the name has changed
|
||||||
if is_group_changed(&group_rev, &old_group) {
|
if is_group_changed(group_rev, &old_group) {
|
||||||
old_group.name = group_rev.name.clone();
|
old_group.name = group_rev.name.clone();
|
||||||
is_changed = true;
|
is_changed = true;
|
||||||
configuration.groups.insert(pos, old_group);
|
configuration.groups.insert(pos, old_group);
|
||||||
|
@ -74,7 +74,7 @@ pub trait GroupControllerSharedOperation: Send + Sync {
|
|||||||
pub struct GenericGroupController<C, T, G, P> {
|
pub struct GenericGroupController<C, T, G, P> {
|
||||||
pub field_id: String,
|
pub field_id: String,
|
||||||
pub type_option: Option<T>,
|
pub type_option: Option<T>,
|
||||||
pub configuration: GroupContext<C>,
|
pub group_ctx: GroupContext<C>,
|
||||||
group_action_phantom: PhantomData<G>,
|
group_action_phantom: PhantomData<G>,
|
||||||
cell_parser_phantom: PhantomData<P>,
|
cell_parser_phantom: PhantomData<P>,
|
||||||
}
|
}
|
||||||
@ -89,12 +89,12 @@ where
|
|||||||
let field_type_rev = field_rev.ty;
|
let field_type_rev = field_rev.ty;
|
||||||
let type_option = field_rev.get_type_option::<T>(field_type_rev);
|
let type_option = field_rev.get_type_option::<T>(field_type_rev);
|
||||||
let groups = G::generate_groups(&field_rev.id, &configuration, &type_option);
|
let groups = G::generate_groups(&field_rev.id, &configuration, &type_option);
|
||||||
let _ = configuration.init_group_revs(groups)?;
|
let _ = configuration.init_groups(groups, false)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
field_id: field_rev.id.clone(),
|
field_id: field_rev.id.clone(),
|
||||||
type_option,
|
type_option,
|
||||||
configuration,
|
group_ctx: configuration,
|
||||||
group_action_phantom: PhantomData,
|
group_action_phantom: PhantomData,
|
||||||
cell_parser_phantom: PhantomData,
|
cell_parser_phantom: PhantomData,
|
||||||
})
|
})
|
||||||
@ -107,7 +107,7 @@ where
|
|||||||
row_rev: &RowRevision,
|
row_rev: &RowRevision,
|
||||||
other_group_changesets: &[GroupChangesetPB],
|
other_group_changesets: &[GroupChangesetPB],
|
||||||
) -> GroupChangesetPB {
|
) -> GroupChangesetPB {
|
||||||
let default_group = self.configuration.get_mut_default_group();
|
let default_group = self.group_ctx.get_mut_default_group();
|
||||||
|
|
||||||
// [other_group_inserted_row] contains all the inserted rows except the default group.
|
// [other_group_inserted_row] contains all the inserted rows except the default group.
|
||||||
let other_group_inserted_row = other_group_changesets
|
let other_group_inserted_row = other_group_changesets
|
||||||
@ -182,11 +182,11 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn groups(&self) -> Vec<Group> {
|
fn groups(&self) -> Vec<Group> {
|
||||||
self.configuration.clone_groups()
|
self.group_ctx.clone_groups()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_group(&self, group_id: &str) -> Option<(usize, Group)> {
|
fn get_group(&self, group_id: &str) -> Option<(usize, Group)> {
|
||||||
let group = self.configuration.get_group(group_id)?;
|
let group = self.group_ctx.get_group(group_id)?;
|
||||||
Some((group.0, group.1.clone()))
|
Some((group.0, group.1.clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,7 +197,7 @@ where
|
|||||||
let mut grouped_rows: Vec<GroupedRow> = vec![];
|
let mut grouped_rows: Vec<GroupedRow> = vec![];
|
||||||
let cell_bytes = decode_any_cell_data(cell_rev.data.clone(), field_rev);
|
let cell_bytes = decode_any_cell_data(cell_rev.data.clone(), field_rev);
|
||||||
let cell_data = cell_bytes.parser::<P>()?;
|
let cell_data = cell_bytes.parser::<P>()?;
|
||||||
for group in self.configuration.concrete_groups() {
|
for group in self.group_ctx.concrete_groups() {
|
||||||
if self.can_group(&group.filter_content, &cell_data) {
|
if self.can_group(&group.filter_content, &cell_data) {
|
||||||
grouped_rows.push(GroupedRow {
|
grouped_rows.push(GroupedRow {
|
||||||
row: row_rev.into(),
|
row: row_rev.into(),
|
||||||
@ -207,25 +207,25 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
if grouped_rows.is_empty() {
|
if grouped_rows.is_empty() {
|
||||||
self.configuration.get_mut_default_group().add_row(row_rev.into());
|
self.group_ctx.get_mut_default_group().add_row(row_rev.into());
|
||||||
} else {
|
} else {
|
||||||
for group_row in grouped_rows {
|
for group_row in grouped_rows {
|
||||||
if let Some(group) = self.configuration.get_mut_group(&group_row.group_id) {
|
if let Some(group) = self.group_ctx.get_mut_group(&group_row.group_id) {
|
||||||
group.add_row(group_row.row);
|
group.add_row(group_row.row);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.configuration.get_mut_default_group().add_row(row_rev.into());
|
self.group_ctx.get_mut_default_group().add_row(row_rev.into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tracing::Span::current().record("group_result", &format!("{},", self.configuration,).as_str());
|
tracing::Span::current().record("group_result", &format!("{},", self.group_ctx,).as_str());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_group(&mut self, from_group_id: &str, to_group_id: &str) -> FlowyResult<()> {
|
fn move_group(&mut self, from_group_id: &str, to_group_id: &str) -> FlowyResult<()> {
|
||||||
self.configuration.move_group(from_group_id, to_group_id)
|
self.group_ctx.move_group(from_group_id, to_group_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn did_update_row(
|
fn did_update_row(
|
||||||
@ -273,10 +273,9 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn did_update_field(&mut self, field_rev: &FieldRevision) -> FlowyResult<Option<GroupViewChangesetPB>> {
|
fn did_update_field(&mut self, field_rev: &FieldRevision) -> FlowyResult<Option<GroupViewChangesetPB>> {
|
||||||
let field_type_rev = field_rev.ty;
|
let type_option = field_rev.get_type_option::<T>(field_rev.ty);
|
||||||
let type_option = field_rev.get_type_option::<T>(field_type_rev);
|
let groups = G::generate_groups(&field_rev.id, &self.group_ctx, &type_option);
|
||||||
let groups = G::generate_groups(&field_rev.id, &self.configuration, &type_option);
|
let changeset = self.group_ctx.init_groups(groups, false)?;
|
||||||
let changeset = self.configuration.init_group_revs(groups)?;
|
|
||||||
Ok(changeset)
|
Ok(changeset)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ use crate::services::group::configuration::GroupContext;
|
|||||||
use crate::services::group::controller::{
|
use crate::services::group::controller::{
|
||||||
GenericGroupController, GroupController, GroupGenerator, MoveGroupRowContext,
|
GenericGroupController, GroupController, GroupGenerator, MoveGroupRowContext,
|
||||||
};
|
};
|
||||||
use crate::services::group::entities::Group;
|
|
||||||
|
|
||||||
use crate::services::group::GeneratedGroup;
|
use crate::services::group::GeneratedGroup;
|
||||||
use flowy_grid_data_model::revision::{CheckboxGroupConfigurationRevision, FieldRevision, GroupRevision, RowRevision};
|
use flowy_grid_data_model::revision::{CheckboxGroupConfigurationRevision, FieldRevision, GroupRevision, RowRevision};
|
||||||
@ -54,9 +53,9 @@ impl GroupGenerator for CheckboxGroupGenerator {
|
|||||||
type TypeOptionType = CheckboxTypeOptionPB;
|
type TypeOptionType = CheckboxTypeOptionPB;
|
||||||
|
|
||||||
fn generate_groups(
|
fn generate_groups(
|
||||||
field_id: &str,
|
_field_id: &str,
|
||||||
group_ctx: &Self::Context,
|
_group_ctx: &Self::Context,
|
||||||
type_option: &Option<Self::TypeOptionType>,
|
_type_option: &Option<Self::TypeOptionType>,
|
||||||
) -> Vec<GeneratedGroup> {
|
) -> Vec<GeneratedGroup> {
|
||||||
let check_group = GeneratedGroup {
|
let check_group = GeneratedGroup {
|
||||||
group_rev: GroupRevision::new("true".to_string(), CHECK.to_string()),
|
group_rev: GroupRevision::new("true".to_string(), CHECK.to_string()),
|
||||||
|
@ -35,46 +35,46 @@ impl GroupControllerSharedOperation for DefaultGroupController {
|
|||||||
vec![self.group.clone()]
|
vec![self.group.clone()]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_group(&self, group_id: &str) -> Option<(usize, Group)> {
|
fn get_group(&self, _group_id: &str) -> Option<(usize, Group)> {
|
||||||
Some((0, self.group.clone()))
|
Some((0, self.group.clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fill_groups(&mut self, row_revs: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<()> {
|
fn fill_groups(&mut self, row_revs: &[Arc<RowRevision>], _field_rev: &FieldRevision) -> FlowyResult<()> {
|
||||||
row_revs.iter().for_each(|row_rev| {
|
row_revs.iter().for_each(|row_rev| {
|
||||||
self.group.add_row(RowPB::from(row_rev));
|
self.group.add_row(RowPB::from(row_rev));
|
||||||
});
|
});
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_group(&mut self, from_group_id: &str, to_group_id: &str) -> FlowyResult<()> {
|
fn move_group(&mut self, _from_group_id: &str, _to_group_id: &str) -> FlowyResult<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn did_update_row(
|
fn did_update_row(
|
||||||
&mut self,
|
&mut self,
|
||||||
row_rev: &RowRevision,
|
_row_rev: &RowRevision,
|
||||||
field_rev: &FieldRevision,
|
_field_rev: &FieldRevision,
|
||||||
) -> FlowyResult<Vec<GroupChangesetPB>> {
|
) -> FlowyResult<Vec<GroupChangesetPB>> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn did_delete_row(
|
fn did_delete_row(
|
||||||
&mut self,
|
&mut self,
|
||||||
row_rev: &RowRevision,
|
_row_rev: &RowRevision,
|
||||||
field_rev: &FieldRevision,
|
_field_rev: &FieldRevision,
|
||||||
) -> FlowyResult<Vec<GroupChangesetPB>> {
|
) -> FlowyResult<Vec<GroupChangesetPB>> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_group_row(&mut self, context: MoveGroupRowContext) -> FlowyResult<Vec<GroupChangesetPB>> {
|
fn move_group_row(&mut self, _context: MoveGroupRowContext) -> FlowyResult<Vec<GroupChangesetPB>> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn did_update_field(&mut self, field_rev: &FieldRevision) -> FlowyResult<Option<GroupViewChangesetPB>> {
|
fn did_update_field(&mut self, _field_rev: &FieldRevision) -> FlowyResult<Option<GroupViewChangesetPB>> {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GroupController for DefaultGroupController {
|
impl GroupController for DefaultGroupController {
|
||||||
fn will_create_row(&mut self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str) {}
|
fn will_create_row(&mut self, _row_rev: &mut RowRevision, _field_rev: &FieldRevision, _group_id: &str) {}
|
||||||
}
|
}
|
||||||
|
@ -7,11 +7,9 @@ use crate::services::group::controller::{
|
|||||||
GenericGroupController, GroupController, GroupGenerator, MoveGroupRowContext,
|
GenericGroupController, GroupController, GroupGenerator, MoveGroupRowContext,
|
||||||
};
|
};
|
||||||
use crate::services::group::controller_impls::select_option_controller::util::*;
|
use crate::services::group::controller_impls::select_option_controller::util::*;
|
||||||
use crate::services::group::entities::Group;
|
|
||||||
use crate::services::group::GeneratedGroup;
|
use crate::services::group::GeneratedGroup;
|
||||||
use flowy_grid_data_model::revision::{
|
use flowy_grid_data_model::revision::{FieldRevision, RowRevision, SelectOptionGroupConfigurationRevision};
|
||||||
FieldRevision, GroupRevision, RowRevision, SelectOptionGroupConfigurationRevision,
|
|
||||||
};
|
|
||||||
|
|
||||||
// MultiSelect
|
// MultiSelect
|
||||||
pub type MultiSelectGroupController = GenericGroupController<
|
pub type MultiSelectGroupController = GenericGroupController<
|
||||||
@ -30,7 +28,7 @@ impl GroupAction for MultiSelectGroupController {
|
|||||||
|
|
||||||
fn add_row_if_match(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType) -> Vec<GroupChangesetPB> {
|
fn add_row_if_match(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType) -> Vec<GroupChangesetPB> {
|
||||||
let mut changesets = vec![];
|
let mut changesets = vec![];
|
||||||
self.configuration.iter_mut_groups(|group| {
|
self.group_ctx.iter_mut_groups(|group| {
|
||||||
if let Some(changeset) = add_select_option_row(group, cell_data, row_rev) {
|
if let Some(changeset) = add_select_option_row(group, cell_data, row_rev) {
|
||||||
changesets.push(changeset);
|
changesets.push(changeset);
|
||||||
}
|
}
|
||||||
@ -40,7 +38,7 @@ impl GroupAction for MultiSelectGroupController {
|
|||||||
|
|
||||||
fn remove_row_if_match(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType) -> Vec<GroupChangesetPB> {
|
fn remove_row_if_match(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType) -> Vec<GroupChangesetPB> {
|
||||||
let mut changesets = vec![];
|
let mut changesets = vec![];
|
||||||
self.configuration.iter_mut_groups(|group| {
|
self.group_ctx.iter_mut_groups(|group| {
|
||||||
if let Some(changeset) = remove_select_option_row(group, cell_data, row_rev) {
|
if let Some(changeset) = remove_select_option_row(group, cell_data, row_rev) {
|
||||||
changesets.push(changeset);
|
changesets.push(changeset);
|
||||||
}
|
}
|
||||||
@ -50,7 +48,7 @@ impl GroupAction for MultiSelectGroupController {
|
|||||||
|
|
||||||
fn move_row(&mut self, cell_data: &Self::CellDataType, mut context: MoveGroupRowContext) -> Vec<GroupChangesetPB> {
|
fn move_row(&mut self, cell_data: &Self::CellDataType, mut context: MoveGroupRowContext) -> Vec<GroupChangesetPB> {
|
||||||
let mut group_changeset = vec![];
|
let mut group_changeset = vec![];
|
||||||
self.configuration.iter_mut_groups(|group| {
|
self.group_ctx.iter_mut_groups(|group| {
|
||||||
if let Some(changeset) = move_select_option_row(group, cell_data, &mut context) {
|
if let Some(changeset) = move_select_option_row(group, cell_data, &mut context) {
|
||||||
group_changeset.push(changeset);
|
group_changeset.push(changeset);
|
||||||
}
|
}
|
||||||
@ -61,7 +59,7 @@ impl GroupAction for MultiSelectGroupController {
|
|||||||
|
|
||||||
impl GroupController for MultiSelectGroupController {
|
impl GroupController for MultiSelectGroupController {
|
||||||
fn will_create_row(&mut self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str) {
|
fn will_create_row(&mut self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str) {
|
||||||
match self.configuration.get_group(group_id) {
|
match self.group_ctx.get_group(group_id) {
|
||||||
None => tracing::warn!("Can not find the group: {}", group_id),
|
None => tracing::warn!("Can not find the group: {}", group_id),
|
||||||
Some((_, group)) => {
|
Some((_, group)) => {
|
||||||
let cell_rev = insert_select_option_cell(group.id.clone(), field_rev);
|
let cell_rev = insert_select_option_cell(group.id.clone(), field_rev);
|
||||||
|
@ -10,9 +10,7 @@ use crate::services::group::controller_impls::select_option_controller::util::*;
|
|||||||
use crate::services::group::entities::Group;
|
use crate::services::group::entities::Group;
|
||||||
|
|
||||||
use crate::services::group::GeneratedGroup;
|
use crate::services::group::GeneratedGroup;
|
||||||
use flowy_grid_data_model::revision::{
|
use flowy_grid_data_model::revision::{FieldRevision, RowRevision, SelectOptionGroupConfigurationRevision};
|
||||||
FieldRevision, GroupRevision, RowRevision, SelectOptionGroupConfigurationRevision,
|
|
||||||
};
|
|
||||||
|
|
||||||
// SingleSelect
|
// SingleSelect
|
||||||
pub type SingleSelectGroupController = GenericGroupController<
|
pub type SingleSelectGroupController = GenericGroupController<
|
||||||
@ -30,7 +28,7 @@ impl GroupAction for SingleSelectGroupController {
|
|||||||
|
|
||||||
fn add_row_if_match(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType) -> Vec<GroupChangesetPB> {
|
fn add_row_if_match(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType) -> Vec<GroupChangesetPB> {
|
||||||
let mut changesets = vec![];
|
let mut changesets = vec![];
|
||||||
self.configuration.iter_mut_groups(|group| {
|
self.group_ctx.iter_mut_groups(|group| {
|
||||||
if let Some(changeset) = add_select_option_row(group, cell_data, row_rev) {
|
if let Some(changeset) = add_select_option_row(group, cell_data, row_rev) {
|
||||||
changesets.push(changeset);
|
changesets.push(changeset);
|
||||||
}
|
}
|
||||||
@ -40,7 +38,7 @@ impl GroupAction for SingleSelectGroupController {
|
|||||||
|
|
||||||
fn remove_row_if_match(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType) -> Vec<GroupChangesetPB> {
|
fn remove_row_if_match(&mut self, row_rev: &RowRevision, cell_data: &Self::CellDataType) -> Vec<GroupChangesetPB> {
|
||||||
let mut changesets = vec![];
|
let mut changesets = vec![];
|
||||||
self.configuration.iter_mut_groups(|group| {
|
self.group_ctx.iter_mut_groups(|group| {
|
||||||
if let Some(changeset) = remove_select_option_row(group, cell_data, row_rev) {
|
if let Some(changeset) = remove_select_option_row(group, cell_data, row_rev) {
|
||||||
changesets.push(changeset);
|
changesets.push(changeset);
|
||||||
}
|
}
|
||||||
@ -50,7 +48,7 @@ impl GroupAction for SingleSelectGroupController {
|
|||||||
|
|
||||||
fn move_row(&mut self, cell_data: &Self::CellDataType, mut context: MoveGroupRowContext) -> Vec<GroupChangesetPB> {
|
fn move_row(&mut self, cell_data: &Self::CellDataType, mut context: MoveGroupRowContext) -> Vec<GroupChangesetPB> {
|
||||||
let mut group_changeset = vec![];
|
let mut group_changeset = vec![];
|
||||||
self.configuration.iter_mut_groups(|group| {
|
self.group_ctx.iter_mut_groups(|group| {
|
||||||
if let Some(changeset) = move_select_option_row(group, cell_data, &mut context) {
|
if let Some(changeset) = move_select_option_row(group, cell_data, &mut context) {
|
||||||
group_changeset.push(changeset);
|
group_changeset.push(changeset);
|
||||||
}
|
}
|
||||||
@ -61,7 +59,7 @@ impl GroupAction for SingleSelectGroupController {
|
|||||||
|
|
||||||
impl GroupController for SingleSelectGroupController {
|
impl GroupController for SingleSelectGroupController {
|
||||||
fn will_create_row(&mut self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str) {
|
fn will_create_row(&mut self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str) {
|
||||||
let group: Option<&mut Group> = self.configuration.get_mut_group(group_id);
|
let group: Option<&mut Group> = self.group_ctx.get_mut_group(group_id);
|
||||||
match group {
|
match group {
|
||||||
None => {}
|
None => {}
|
||||||
Some(group) => {
|
Some(group) => {
|
||||||
|
@ -127,8 +127,8 @@ pub fn move_select_option_row(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_select_option_groups(
|
pub fn generate_select_option_groups(
|
||||||
field_id: &str,
|
_field_id: &str,
|
||||||
group_ctx: &SelectOptionGroupContext,
|
_group_ctx: &SelectOptionGroupContext,
|
||||||
options: &[SelectOptionPB],
|
options: &[SelectOptionPB],
|
||||||
) -> Vec<GeneratedGroup> {
|
) -> Vec<GeneratedGroup> {
|
||||||
let groups = options
|
let groups = options
|
||||||
|
@ -16,7 +16,7 @@ use std::sync::Arc;
|
|||||||
#[tracing::instrument(level = "trace", skip_all, err)]
|
#[tracing::instrument(level = "trace", skip_all, err)]
|
||||||
pub async fn make_group_controller<R, W>(
|
pub async fn make_group_controller<R, W>(
|
||||||
view_id: String,
|
view_id: String,
|
||||||
field_revs: Vec<Arc<FieldRevision>>,
|
field_rev: Arc<FieldRevision>,
|
||||||
row_revs: Vec<Arc<RowRevision>>,
|
row_revs: Vec<Arc<RowRevision>>,
|
||||||
configuration_reader: R,
|
configuration_reader: R,
|
||||||
configuration_writer: W,
|
configuration_writer: W,
|
||||||
@ -25,11 +25,12 @@ where
|
|||||||
R: GroupConfigurationReader,
|
R: GroupConfigurationReader,
|
||||||
W: GroupConfigurationWriter,
|
W: GroupConfigurationWriter,
|
||||||
{
|
{
|
||||||
let field_rev = find_group_field(&field_revs).unwrap();
|
|
||||||
let field_type: FieldType = field_rev.ty.into();
|
let field_type: FieldType = field_rev.ty.into();
|
||||||
|
|
||||||
let mut group_controller: Box<dyn GroupController>;
|
let mut group_controller: Box<dyn GroupController>;
|
||||||
let configuration_reader = Arc::new(configuration_reader);
|
let configuration_reader = Arc::new(configuration_reader);
|
||||||
let configuration_writer = Arc::new(configuration_writer);
|
let configuration_writer = Arc::new(configuration_writer);
|
||||||
|
|
||||||
match field_type {
|
match field_type {
|
||||||
FieldType::SingleSelect => {
|
FieldType::SingleSelect => {
|
||||||
let configuration =
|
let configuration =
|
||||||
@ -61,7 +62,7 @@ where
|
|||||||
Ok(group_controller)
|
Ok(group_controller)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_group_field(field_revs: &[Arc<FieldRevision>]) -> Option<Arc<FieldRevision>> {
|
pub fn find_group_field(field_revs: &[Arc<FieldRevision>]) -> Option<Arc<FieldRevision>> {
|
||||||
let field_rev = field_revs
|
let field_rev = field_revs
|
||||||
.iter()
|
.iter()
|
||||||
.find(|field_rev| {
|
.find(|field_rev| {
|
||||||
|
@ -195,6 +195,8 @@ fn make_test_grid() -> BuildGridContext {
|
|||||||
FieldType::SingleSelect => {
|
FieldType::SingleSelect => {
|
||||||
row_builder.insert_single_select_cell(|mut options| options.remove(0))
|
row_builder.insert_single_select_cell(|mut options| options.remove(0))
|
||||||
}
|
}
|
||||||
|
FieldType::MultiSelect => row_builder
|
||||||
|
.insert_multi_select_cell(|mut options| vec![options.remove(0), options.remove(0)]),
|
||||||
FieldType::Checkbox => row_builder.insert_checkbox_cell("true"),
|
FieldType::Checkbox => row_builder.insert_checkbox_cell("true"),
|
||||||
_ => "".to_owned(),
|
_ => "".to_owned(),
|
||||||
};
|
};
|
||||||
@ -209,6 +211,8 @@ fn make_test_grid() -> BuildGridContext {
|
|||||||
FieldType::SingleSelect => {
|
FieldType::SingleSelect => {
|
||||||
row_builder.insert_single_select_cell(|mut options| options.remove(0))
|
row_builder.insert_single_select_cell(|mut options| options.remove(0))
|
||||||
}
|
}
|
||||||
|
FieldType::MultiSelect => row_builder
|
||||||
|
.insert_multi_select_cell(|mut options| vec![options.remove(0), options.remove(0)]),
|
||||||
FieldType::Checkbox => row_builder.insert_checkbox_cell("true"),
|
FieldType::Checkbox => row_builder.insert_checkbox_cell("true"),
|
||||||
_ => "".to_owned(),
|
_ => "".to_owned(),
|
||||||
};
|
};
|
||||||
@ -223,6 +227,9 @@ fn make_test_grid() -> BuildGridContext {
|
|||||||
FieldType::SingleSelect => {
|
FieldType::SingleSelect => {
|
||||||
row_builder.insert_single_select_cell(|mut options| options.remove(1))
|
row_builder.insert_single_select_cell(|mut options| options.remove(1))
|
||||||
}
|
}
|
||||||
|
FieldType::MultiSelect => {
|
||||||
|
row_builder.insert_multi_select_cell(|mut options| vec![options.remove(0)])
|
||||||
|
}
|
||||||
FieldType::Checkbox => row_builder.insert_checkbox_cell("false"),
|
FieldType::Checkbox => row_builder.insert_checkbox_cell("false"),
|
||||||
_ => "".to_owned(),
|
_ => "".to_owned(),
|
||||||
};
|
};
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
use crate::grid::grid_editor::GridEditorTest;
|
use crate::grid::grid_editor::GridEditorTest;
|
||||||
use flowy_grid::entities::{
|
use flowy_grid::entities::{
|
||||||
CreateRowParams, FieldChangesetParams, FieldType, GridLayout, GroupPB, MoveGroupParams, MoveGroupRowParams, RowPB,
|
CreateRowParams, FieldType, GridLayout, GroupPB, MoveGroupParams, MoveGroupRowParams, RowPB,
|
||||||
};
|
};
|
||||||
use flowy_grid::services::cell::{delete_select_option_cell, insert_select_option_cell};
|
use flowy_grid::services::cell::{delete_select_option_cell, insert_select_option_cell};
|
||||||
use flowy_grid::services::field::{select_option_operation, SelectOptionOperation};
|
use flowy_grid::services::field::{
|
||||||
|
edit_single_select_type_option, SelectOptionOperation, SelectOptionPB, SingleSelectTypeOptionPB,
|
||||||
|
};
|
||||||
use flowy_grid_data_model::revision::{FieldRevision, RowChangeset};
|
use flowy_grid_data_model::revision::{FieldRevision, RowChangeset};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
|
||||||
use tokio::time::interval;
|
|
||||||
|
|
||||||
pub enum GroupScript {
|
pub enum GroupScript {
|
||||||
AssertGroupRowCount {
|
AssertGroupRowCount {
|
||||||
@ -46,10 +46,10 @@ pub enum GroupScript {
|
|||||||
from_group_index: usize,
|
from_group_index: usize,
|
||||||
to_group_index: usize,
|
to_group_index: usize,
|
||||||
},
|
},
|
||||||
UpdateField {
|
UpdateSingleSelectOption {
|
||||||
changeset: FieldChangesetParams,
|
inserted_options: Vec<SelectOptionPB>,
|
||||||
},
|
},
|
||||||
GroupField {
|
GroupByField {
|
||||||
field_id: String,
|
field_id: String,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -179,12 +179,15 @@ impl GridGroupTest {
|
|||||||
assert_eq!(group.group_id, group_pb.group_id);
|
assert_eq!(group.group_id, group_pb.group_id);
|
||||||
assert_eq!(group.desc, group_pb.desc);
|
assert_eq!(group.desc, group_pb.desc);
|
||||||
}
|
}
|
||||||
GroupScript::UpdateField { changeset } => {
|
GroupScript::UpdateSingleSelectOption { inserted_options } => {
|
||||||
self.editor.update_field(changeset).await.unwrap();
|
self.edit_single_select_type_option(|type_option| {
|
||||||
let mut interval = interval(Duration::from_millis(130));
|
for inserted_option in inserted_options {
|
||||||
interval.tick().await;
|
type_option.insert_option(inserted_option);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
GroupScript::GroupField { field_id } => {
|
GroupScript::GroupByField { field_id } => {
|
||||||
self.editor.group_field(&field_id).await.unwrap();
|
self.editor.group_field(&field_id).await.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -200,6 +203,7 @@ impl GridGroupTest {
|
|||||||
groups.rows.get(row_index).unwrap().clone()
|
groups.rows.get(row_index).unwrap().clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub async fn get_multi_select_field(&self) -> Arc<FieldRevision> {
|
pub async fn get_multi_select_field(&self) -> Arc<FieldRevision> {
|
||||||
let field = self
|
let field = self
|
||||||
.inner
|
.inner
|
||||||
@ -211,7 +215,7 @@ impl GridGroupTest {
|
|||||||
})
|
})
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.clone();
|
.clone();
|
||||||
return field;
|
field
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_single_select_field(&self) -> Arc<FieldRevision> {
|
pub async fn get_single_select_field(&self) -> Arc<FieldRevision> {
|
||||||
@ -226,14 +230,11 @@ impl GridGroupTest {
|
|||||||
.clone()
|
.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn edit_single_select_type_option(&self, f: impl FnOnce(Box<dyn SelectOptionOperation>)) {
|
pub async fn edit_single_select_type_option(&self, action: impl FnOnce(&mut SingleSelectTypeOptionPB)) {
|
||||||
let single_select = self.get_single_select_field().await;
|
let single_select = self.get_single_select_field().await;
|
||||||
let mut field_rev = self.editor.get_field_rev(&single_select.id).await.unwrap();
|
edit_single_select_type_option(&single_select.id, self.editor.clone(), action)
|
||||||
let mut_field_rev = Arc::make_mut(&mut field_rev);
|
.await
|
||||||
let mut type_option = select_option_operation(mut_field_rev)?;
|
.unwrap();
|
||||||
f(type_option);
|
|
||||||
mut_field_rev.insert_type_option(&*type_option);
|
|
||||||
let _ = self.editor.replace_field(field_rev).await?;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use crate::grid::group_test::script::GridGroupTest;
|
use crate::grid::group_test::script::GridGroupTest;
|
||||||
use crate::grid::group_test::script::GroupScript::*;
|
use crate::grid::group_test::script::GroupScript::*;
|
||||||
use flowy_grid::entities::FieldChangesetParams;
|
|
||||||
|
use flowy_grid::services::field::SelectOptionPB;
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn group_init_test() {
|
async fn group_init_test() {
|
||||||
@ -370,32 +371,41 @@ async fn group_move_group_test() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn group_update_field_test() {
|
async fn group_insert_single_select_option_test() {
|
||||||
let mut test = GridGroupTest::new().await;
|
let mut test = GridGroupTest::new().await;
|
||||||
let group = test.group_at_index(0).await;
|
let new_option_name = "New option";
|
||||||
let changeset = FieldChangesetParams {
|
|
||||||
field_id: group.field_id.clone(),
|
|
||||||
grid_id: test.grid_id.clone(),
|
|
||||||
name: Some("ABC".to_string()),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
// group.desc = "ABC".to_string();
|
|
||||||
let scripts = vec![
|
let scripts = vec![
|
||||||
UpdateField { changeset },
|
AssertGroupCount(4),
|
||||||
AssertGroup {
|
UpdateSingleSelectOption {
|
||||||
group_index: 0,
|
inserted_options: vec![SelectOptionPB::new(new_option_name)],
|
||||||
expected_group: group,
|
|
||||||
},
|
},
|
||||||
|
AssertGroupCount(5),
|
||||||
|
];
|
||||||
|
test.run_scripts(scripts).await;
|
||||||
|
|
||||||
|
// the group at index 4 is the default_group, so the new insert group will be the
|
||||||
|
// index 3.
|
||||||
|
let group_3 = test.group_at_index(3).await;
|
||||||
|
assert_eq!(group_3.desc, new_option_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn group_group_by_other_field() {
|
||||||
|
let mut test = GridGroupTest::new().await;
|
||||||
|
let multi_select_field = test.get_multi_select_field().await;
|
||||||
|
let scripts = vec![
|
||||||
|
GroupByField {
|
||||||
|
field_id: multi_select_field.id.clone(),
|
||||||
|
},
|
||||||
|
AssertGroupRowCount {
|
||||||
|
group_index: 0,
|
||||||
|
row_count: 3,
|
||||||
|
},
|
||||||
|
AssertGroupRowCount {
|
||||||
|
group_index: 1,
|
||||||
|
row_count: 2,
|
||||||
|
},
|
||||||
|
AssertGroupCount(4),
|
||||||
];
|
];
|
||||||
test.run_scripts(scripts).await;
|
test.run_scripts(scripts).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[tokio::test]
|
|
||||||
// async fn group_multi_select_field_test() {
|
|
||||||
// let mut test = GridGroupTest::new().await;
|
|
||||||
// let multi_select_field = test.get_multi_select_field().await;
|
|
||||||
//
|
|
||||||
// let scripts = vec![];
|
|
||||||
// test.run_scripts(scripts).await;
|
|
||||||
// }
|
|
||||||
|
@ -60,7 +60,7 @@ where
|
|||||||
.cloned()
|
.cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_all_objects(&self, field_revs: &[Arc<FieldRevision>]) -> Option<HashMap<String, Vec<Arc<T>>>> {
|
pub fn get_objects_by_field_revs(&self, field_revs: &[Arc<FieldRevision>]) -> Option<HashMap<String, Vec<Arc<T>>>> {
|
||||||
// Get the objects according to the FieldType, so we need iterate the field_revs.
|
// Get the objects according to the FieldType, so we need iterate the field_revs.
|
||||||
let objects_by_field_id = field_revs
|
let objects_by_field_id = field_revs
|
||||||
.iter()
|
.iter()
|
||||||
@ -76,6 +76,10 @@ where
|
|||||||
Some(objects_by_field_id)
|
Some(objects_by_field_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_all_objects(&self) -> Vec<Arc<T>> {
|
||||||
|
self.inner.values().map(|map| map.all_objects()).flatten().collect()
|
||||||
|
}
|
||||||
|
|
||||||
/// add object to the end of the list
|
/// add object to the end of the list
|
||||||
pub fn add_object(&mut self, field_id: &str, field_type: &FieldTypeRevision, object: T) {
|
pub fn add_object(&mut self, field_id: &str, field_type: &FieldTypeRevision, object: T) {
|
||||||
let object_rev_map = self
|
let object_rev_map = self
|
||||||
@ -111,6 +115,10 @@ where
|
|||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
ObjectIndexMap::default()
|
ObjectIndexMap::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn all_objects(&self) -> Vec<Arc<T>> {
|
||||||
|
self.object_by_field_type.values().cloned().flatten().collect()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> std::ops::Deref for ObjectIndexMap<T>
|
impl<T> std::ops::Deref for ObjectIndexMap<T>
|
||||||
|
@ -48,8 +48,12 @@ impl GridViewRevisionPad {
|
|||||||
Self::from_delta(delta)
|
Self::from_delta(delta)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_all_groups(&self, field_revs: &[Arc<FieldRevision>]) -> Option<GroupConfigurationsByFieldId> {
|
pub fn get_groups_by_field_revs(&self, field_revs: &[Arc<FieldRevision>]) -> Option<GroupConfigurationsByFieldId> {
|
||||||
self.groups.get_all_objects(field_revs)
|
self.groups.get_objects_by_field_revs(field_revs)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_all_groups(&self) -> Vec<Arc<GroupConfigurationRevision>> {
|
||||||
|
self.groups.get_all_objects()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "trace", skip_all, err)]
|
#[tracing::instrument(level = "trace", skip_all, err)]
|
||||||
@ -111,7 +115,7 @@ impl GridViewRevisionPad {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_all_filters(&self, field_revs: &[Arc<FieldRevision>]) -> Option<FilterConfigurationsByFieldId> {
|
pub fn get_all_filters(&self, field_revs: &[Arc<FieldRevision>]) -> Option<FilterConfigurationsByFieldId> {
|
||||||
self.filters.get_all_objects(field_revs)
|
self.filters.get_objects_by_field_revs(field_revs)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_filters(
|
pub fn get_filters(
|
||||||
|
@ -178,7 +178,7 @@ mod tests {
|
|||||||
node_type: "text".into(),
|
node_type: "text".into(),
|
||||||
attributes: NodeAttributes::new(),
|
attributes: NodeAttributes::new(),
|
||||||
delta: None,
|
delta: None,
|
||||||
children: vec![Box::new(NodeSubTree::new("text".into()))],
|
children: vec![Box::new(NodeSubTree::new("text"))],
|
||||||
})],
|
})],
|
||||||
};
|
};
|
||||||
let result = serde_json::to_string(&insert).unwrap();
|
let result = serde_json::to_string(&insert).unwrap();
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#![allow(clippy::module_inception)]
|
||||||
mod attributes;
|
mod attributes;
|
||||||
mod document;
|
mod document;
|
||||||
mod document_operation;
|
mod document_operation;
|
||||||
|
@ -13,7 +13,7 @@ fn test_documents() {
|
|||||||
let mut document = DocumentTree::new();
|
let mut document = DocumentTree::new();
|
||||||
let transaction = {
|
let transaction = {
|
||||||
let mut tb = TransactionBuilder::new(&document);
|
let mut tb = TransactionBuilder::new(&document);
|
||||||
tb.insert_nodes_at_path(&vec![0].into(), &vec![Box::new(NodeSubTree::new("text"))]);
|
tb.insert_nodes_at_path(&vec![0].into(), &[Box::new(NodeSubTree::new("text"))]);
|
||||||
tb.finalize()
|
tb.finalize()
|
||||||
};
|
};
|
||||||
document.apply(transaction).unwrap();
|
document.apply(transaction).unwrap();
|
||||||
@ -47,16 +47,16 @@ fn test_inserts_nodes() {
|
|||||||
let mut document = DocumentTree::new();
|
let mut document = DocumentTree::new();
|
||||||
let transaction = {
|
let transaction = {
|
||||||
let mut tb = TransactionBuilder::new(&document);
|
let mut tb = TransactionBuilder::new(&document);
|
||||||
tb.insert_nodes_at_path(&vec![0].into(), &vec![Box::new(NodeSubTree::new("text"))]);
|
tb.insert_nodes_at_path(&vec![0].into(), &[Box::new(NodeSubTree::new("text"))]);
|
||||||
tb.insert_nodes_at_path(&vec![1].into(), &vec![Box::new(NodeSubTree::new("text"))]);
|
tb.insert_nodes_at_path(&vec![1].into(), &[Box::new(NodeSubTree::new("text"))]);
|
||||||
tb.insert_nodes_at_path(&vec![2].into(), &vec![Box::new(NodeSubTree::new("text"))]);
|
tb.insert_nodes_at_path(&vec![2].into(), &[Box::new(NodeSubTree::new("text"))]);
|
||||||
tb.finalize()
|
tb.finalize()
|
||||||
};
|
};
|
||||||
document.apply(transaction).unwrap();
|
document.apply(transaction).unwrap();
|
||||||
|
|
||||||
let transaction = {
|
let transaction = {
|
||||||
let mut tb = TransactionBuilder::new(&document);
|
let mut tb = TransactionBuilder::new(&document);
|
||||||
tb.insert_nodes_at_path(&vec![1].into(), &vec![Box::new(NodeSubTree::new("text"))]);
|
tb.insert_nodes_at_path(&vec![1].into(), &[Box::new(NodeSubTree::new("text"))]);
|
||||||
tb.finalize()
|
tb.finalize()
|
||||||
};
|
};
|
||||||
document.apply(transaction).unwrap();
|
document.apply(transaction).unwrap();
|
||||||
@ -69,11 +69,11 @@ fn test_inserts_subtrees() {
|
|||||||
let mut tb = TransactionBuilder::new(&document);
|
let mut tb = TransactionBuilder::new(&document);
|
||||||
tb.insert_nodes_at_path(
|
tb.insert_nodes_at_path(
|
||||||
&vec![0].into(),
|
&vec![0].into(),
|
||||||
&vec![Box::new(NodeSubTree {
|
&[Box::new(NodeSubTree {
|
||||||
node_type: "text".into(),
|
node_type: "text".into(),
|
||||||
attributes: NodeAttributes::new(),
|
attributes: NodeAttributes::new(),
|
||||||
delta: None,
|
delta: None,
|
||||||
children: vec![Box::new(NodeSubTree::new("image".into()))],
|
children: vec![Box::new(NodeSubTree::new("image"))],
|
||||||
})],
|
})],
|
||||||
);
|
);
|
||||||
tb.finalize()
|
tb.finalize()
|
||||||
@ -90,9 +90,9 @@ fn test_update_nodes() {
|
|||||||
let mut document = DocumentTree::new();
|
let mut document = DocumentTree::new();
|
||||||
let transaction = {
|
let transaction = {
|
||||||
let mut tb = TransactionBuilder::new(&document);
|
let mut tb = TransactionBuilder::new(&document);
|
||||||
tb.insert_nodes_at_path(&vec![0].into(), &vec![Box::new(NodeSubTree::new("text"))]);
|
tb.insert_nodes_at_path(&vec![0].into(), &[Box::new(NodeSubTree::new("text"))]);
|
||||||
tb.insert_nodes_at_path(&vec![1].into(), &vec![Box::new(NodeSubTree::new("text"))]);
|
tb.insert_nodes_at_path(&vec![1].into(), &[Box::new(NodeSubTree::new("text"))]);
|
||||||
tb.insert_nodes_at_path(&vec![2].into(), &vec![Box::new(NodeSubTree::new("text"))]);
|
tb.insert_nodes_at_path(&vec![2].into(), &[Box::new(NodeSubTree::new("text"))]);
|
||||||
tb.finalize()
|
tb.finalize()
|
||||||
};
|
};
|
||||||
document.apply(transaction).unwrap();
|
document.apply(transaction).unwrap();
|
||||||
@ -115,9 +115,9 @@ fn test_delete_nodes() {
|
|||||||
let mut document = DocumentTree::new();
|
let mut document = DocumentTree::new();
|
||||||
let transaction = {
|
let transaction = {
|
||||||
let mut tb = TransactionBuilder::new(&document);
|
let mut tb = TransactionBuilder::new(&document);
|
||||||
tb.insert_nodes_at_path(&vec![0].into(), &vec![Box::new(NodeSubTree::new("text"))]);
|
tb.insert_nodes_at_path(&vec![0].into(), &[Box::new(NodeSubTree::new("text"))]);
|
||||||
tb.insert_nodes_at_path(&vec![1].into(), &vec![Box::new(NodeSubTree::new("text"))]);
|
tb.insert_nodes_at_path(&vec![1].into(), &[Box::new(NodeSubTree::new("text"))]);
|
||||||
tb.insert_nodes_at_path(&vec![2].into(), &vec![Box::new(NodeSubTree::new("text"))]);
|
tb.insert_nodes_at_path(&vec![2].into(), &[Box::new(NodeSubTree::new("text"))]);
|
||||||
tb.finalize()
|
tb.finalize()
|
||||||
};
|
};
|
||||||
document.apply(transaction).unwrap();
|
document.apply(transaction).unwrap();
|
||||||
@ -138,8 +138,8 @@ fn test_errors() {
|
|||||||
let mut document = DocumentTree::new();
|
let mut document = DocumentTree::new();
|
||||||
let transaction = {
|
let transaction = {
|
||||||
let mut tb = TransactionBuilder::new(&document);
|
let mut tb = TransactionBuilder::new(&document);
|
||||||
tb.insert_nodes_at_path(&vec![0].into(), &vec![Box::new(NodeSubTree::new("text"))]);
|
tb.insert_nodes_at_path(&vec![0].into(), &[Box::new(NodeSubTree::new("text"))]);
|
||||||
tb.insert_nodes_at_path(&vec![100].into(), &vec![Box::new(NodeSubTree::new("text"))]);
|
tb.insert_nodes_at_path(&vec![100].into(), &[Box::new(NodeSubTree::new("text"))]);
|
||||||
tb.finalize()
|
tb.finalize()
|
||||||
};
|
};
|
||||||
let result = document.apply(transaction);
|
let result = document.apply(transaction);
|
||||||
|
Reference in New Issue
Block a user