refactor: group event (#2640)

* refactor: group event

* fix: tauri build
This commit is contained in:
Nathan.fooo 2023-05-28 22:54:03 +08:00 committed by GitHub
parent 75d40b79d0
commit 6bbdc7ceff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 602 additions and 504 deletions

View File

@ -178,7 +178,7 @@ class FilterBackendService {
required FieldType fieldType,
required List<int> data,
}) {
var insertFilterPayload = AlterFilterPayloadPB.create()
var insertFilterPayload = UpdateFilterPayloadPB.create()
..fieldId = fieldId
..fieldType = fieldType
..viewId = viewId
@ -190,7 +190,7 @@ class FilterBackendService {
final payload = DatabaseSettingChangesetPB.create()
..viewId = viewId
..alterFilter = insertFilterPayload;
..updateFilter = insertFilterPayload;
return DatabaseEventUpdateDatabaseSetting(payload).send().then((result) {
return result.fold(
(l) => left(l),

View File

@ -8,7 +8,7 @@ import 'package:dartz/dartz.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/group.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/group_changeset.pb.dart';
typedef GroupUpdateValue = Either<GroupChangesetPB, FlowyError>;
typedef GroupUpdateValue = Either<GroupChangesPB, FlowyError>;
typedef GroupByNewFieldValue = Either<List<GroupPB>, FlowyError>;
class DatabaseGroupListener {
@ -36,17 +36,17 @@ class DatabaseGroupListener {
Either<Uint8List, FlowyError> result,
) {
switch (ty) {
case DatabaseNotification.DidUpdateGroups:
case DatabaseNotification.DidUpdateNumOfGroups:
result.fold(
(payload) => _numOfGroupsNotifier?.value =
left(GroupChangesetPB.fromBuffer(payload)),
left(GroupChangesPB.fromBuffer(payload)),
(error) => _numOfGroupsNotifier?.value = right(error),
);
break;
case DatabaseNotification.DidGroupByField:
result.fold(
(payload) => _groupByFieldNotifier?.value =
left(GroupChangesetPB.fromBuffer(payload).initialGroups),
left(GroupChangesPB.fromBuffer(payload).initialGroups),
(error) => _groupByFieldNotifier?.value = right(error),
);
break;

View File

@ -0,0 +1,37 @@
import 'package:appflowy_backend/dispatch/dispatch.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pbenum.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/group.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
import 'package:dartz/dartz.dart';
class GroupBackendService {
final String viewId;
GroupBackendService(this.viewId);
Future<Either<Unit, FlowyError>> groupByField({
required String fieldId,
required FieldType fieldType,
}) {
final payload = GroupByFieldPayloadPB.create()
..viewId = viewId
..fieldId = fieldId
..fieldType = fieldType;
return DatabaseEventSetGroupByField(payload).send();
}
Future<Either<Unit, FlowyError>> updateGroup({
required String groupId,
String? name,
bool? visible,
}) {
final payload = UpdateGroupPB.create()..groupId = groupId;
if (name != null) {
payload.name = name;
}
if (visible != null) {
payload.visible = visible;
}
return DatabaseEventUpdateGroup(payload).send();
}
}

View File

@ -1,23 +1,24 @@
import 'package:appflowy/plugins/database_view/application/field/field_controller.dart';
import 'package:appflowy/plugins/database_view/application/setting/setting_service.dart';
import 'package:appflowy_backend/log.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pb.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'dart:async';
import '../group/group_service.dart';
part 'group_bloc.freezed.dart';
class DatabaseGroupBloc extends Bloc<DatabaseGroupEvent, DatabaseGroupState> {
final FieldController _fieldController;
final SettingBackendService _settingBackendSvc;
final GroupBackendService _groupBackendSvc;
Function(List<FieldInfo>)? _onFieldsFn;
DatabaseGroupBloc({
required String viewId,
required FieldController fieldController,
}) : _fieldController = fieldController,
_settingBackendSvc = SettingBackendService(viewId: viewId),
_groupBackendSvc = GroupBackendService(viewId),
super(DatabaseGroupState.initial(viewId, fieldController.fieldInfos)) {
on<DatabaseGroupEvent>(
(event, emit) async {
@ -29,7 +30,7 @@ class DatabaseGroupBloc extends Bloc<DatabaseGroupEvent, DatabaseGroupState> {
emit(state.copyWith(fieldContexts: fieldContexts));
},
setGroupByField: (String fieldId, FieldType fieldType) async {
final result = await _settingBackendSvc.groupByField(
final result = await _groupBackendSvc.groupByField(
fieldId: fieldId,
fieldType: fieldType,
);

View File

@ -2,8 +2,6 @@ import 'package:appflowy_backend/protobuf/flowy-database2/database_entities.pb.d
import 'package:dartz/dartz.dart';
import 'package:appflowy_backend/dispatch/dispatch.dart';
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/group.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/setting_entities.pb.dart';
class SettingBackendService {
@ -15,19 +13,4 @@ class SettingBackendService {
final payload = DatabaseViewIdPB.create()..value = viewId;
return DatabaseEventGetDatabaseSetting(payload).send();
}
Future<Either<Unit, FlowyError>> groupByField({
required String fieldId,
required FieldType fieldType,
}) {
final insertGroupPayload = InsertGroupPayloadPB.create()
..viewId = viewId
..fieldId = fieldId
..fieldType = fieldType;
final payload = DatabaseSettingChangesetPB.create()
..viewId = viewId
..insertGroup = insertGroupPayload;
return DatabaseEventUpdateDatabaseSetting(payload).send();
}
}

View File

@ -29,7 +29,7 @@ class SortBackendService {
required FieldType fieldType,
required SortConditionPB condition,
}) {
var insertSortPayload = AlterSortPayloadPB.create()
var insertSortPayload = UpdateSortPayloadPB.create()
..fieldId = fieldId
..fieldType = fieldType
..viewId = viewId
@ -38,7 +38,7 @@ class SortBackendService {
final payload = DatabaseSettingChangesetPB.create()
..viewId = viewId
..alterSort = insertSortPayload;
..updateSort = insertSortPayload;
return DatabaseEventUpdateDatabaseSetting(payload).send().then((result) {
return result.fold(
(l) => left(l),
@ -55,7 +55,7 @@ class SortBackendService {
required FieldType fieldType,
required SortConditionPB condition,
}) {
var insertSortPayload = AlterSortPayloadPB.create()
var insertSortPayload = UpdateSortPayloadPB.create()
..fieldId = fieldId
..fieldType = fieldType
..viewId = viewId
@ -63,7 +63,7 @@ class SortBackendService {
final payload = DatabaseSettingChangesetPB.create()
..viewId = viewId
..alterSort = insertSortPayload;
..updateSort = insertSortPayload;
return DatabaseEventUpdateDatabaseSetting(payload).send().then((result) {
return result.fold(
(l) => left(l),

View File

@ -1,18 +1,17 @@
import { ChangeNotifier } from "$app/utils/change_notifier";
import { Ok, Result } from "ts-results";
import { DatabaseNotification, FlowyError, GroupChangesetPB, GroupPB } from "@/services/backend";
import { DatabaseNotificationObserver } from "../notifications/observer";
import { ChangeNotifier } from '$app/utils/change_notifier';
import { Ok, Result } from 'ts-results';
import { DatabaseNotification, FlowyError, GroupChangesPB, GroupPB } from '@/services/backend';
import { DatabaseNotificationObserver } from '../notifications/observer';
export type GroupByFieldCallback = (value: Result<GroupPB[], FlowyError>) => void;
export type GroupChangesetSubscribeCallback = (value: Result<GroupChangesetPB, FlowyError>) => void;
export type GroupChangesetSubscribeCallback = (value: Result<GroupChangesPB, FlowyError>) => void;
export class DatabaseGroupObserver {
private groupByNotifier?: ChangeNotifier<Result<GroupPB[], FlowyError>>;
private groupChangesetNotifier?: ChangeNotifier<Result<GroupChangesetPB, FlowyError>>;
private groupChangesetNotifier?: ChangeNotifier<Result<GroupChangesPB, FlowyError>>;
private listener?: DatabaseNotificationObserver;
constructor(public readonly viewId: string) {
}
constructor(public readonly viewId: string) {}
subscribe = async (callbacks: {
onGroupBy: GroupByFieldCallback;
@ -30,14 +29,14 @@ export class DatabaseGroupObserver {
switch (notification) {
case DatabaseNotification.DidGroupByField:
if (result.ok) {
this.groupByNotifier?.notify(Ok(GroupChangesetPB.deserializeBinary(result.val).initial_groups));
this.groupByNotifier?.notify(Ok(GroupChangesPB.deserializeBinary(result.val).initial_groups));
} else {
this.groupByNotifier?.notify(result);
}
break;
case DatabaseNotification.DidUpdateGroups:
case DatabaseNotification.DidUpdateNumOfGroups:
if (result.ok) {
this.groupChangesetNotifier?.notify(Ok(GroupChangesetPB.deserializeBinary(result.val)));
this.groupChangesetNotifier?.notify(Ok(GroupChangesPB.deserializeBinary(result.val)));
} else {
this.groupChangesetNotifier?.notify(result);
}
@ -45,7 +44,7 @@ export class DatabaseGroupObserver {
default:
break;
}
}
},
});
await this.listener.start();

View File

@ -125,7 +125,7 @@ pub struct DeleteFilterParams {
}
#[derive(ProtoBuf, Debug, Default, Clone)]
pub struct AlterFilterPayloadPB {
pub struct UpdateFilterPayloadPB {
#[pb(index = 1)]
pub field_id: String,
@ -143,7 +143,7 @@ pub struct AlterFilterPayloadPB {
pub view_id: String,
}
impl AlterFilterPayloadPB {
impl UpdateFilterPayloadPB {
#[allow(dead_code)]
pub fn new<T: TryInto<Bytes, Error = ::protobuf::ProtobufError>>(
view_id: &str,
@ -162,10 +162,10 @@ impl AlterFilterPayloadPB {
}
}
impl TryInto<AlterFilterParams> for AlterFilterPayloadPB {
impl TryInto<UpdateFilterParams> for UpdateFilterPayloadPB {
type Error = ErrorCode;
fn try_into(self) -> Result<AlterFilterParams, Self::Error> {
fn try_into(self) -> Result<UpdateFilterParams, Self::Error> {
let view_id = NotEmptyStr::parse(self.view_id)
.map_err(|_| ErrorCode::DatabaseViewIdIsEmpty)?
.0;
@ -217,7 +217,7 @@ impl TryInto<AlterFilterParams> for AlterFilterPayloadPB {
},
}
Ok(AlterFilterParams {
Ok(UpdateFilterParams {
view_id,
field_id,
filter_id,
@ -229,7 +229,7 @@ impl TryInto<AlterFilterParams> for AlterFilterPayloadPB {
}
#[derive(Debug)]
pub struct AlterFilterParams {
pub struct UpdateFilterParams {
pub view_id: String,
pub field_id: String,
/// Create a new filter if the filter_id is None

View File

@ -5,7 +5,7 @@ use flowy_error::ErrorCode;
use crate::entities::parser::NotEmptyStr;
use crate::entities::{FieldType, RowPB};
use crate::services::group::{GroupData, GroupSetting};
use crate::services::group::{GroupChangeset, GroupData, GroupSetting};
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
pub struct GroupSettingPB {
@ -25,6 +25,29 @@ impl std::convert::From<&GroupSetting> for GroupSettingPB {
}
}
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
pub struct RepeatedGroupSettingPB {
#[pb(index = 1)]
pub items: Vec<GroupSettingPB>,
}
impl std::convert::From<Vec<GroupSettingPB>> for RepeatedGroupSettingPB {
fn from(items: Vec<GroupSettingPB>) -> Self {
Self { items }
}
}
impl std::convert::From<Vec<GroupSetting>> for RepeatedGroupSettingPB {
fn from(group_settings: Vec<GroupSetting>) -> Self {
RepeatedGroupSettingPB {
items: group_settings
.iter()
.map(|setting| setting.into())
.collect(),
}
}
}
#[derive(ProtoBuf, Debug, Default, Clone)]
pub struct RepeatedGroupPB {
#[pb(index = 1)]
@ -79,107 +102,97 @@ impl std::convert::From<GroupData> for GroupPB {
}
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
pub struct RepeatedGroupSettingPB {
#[pb(index = 1)]
pub items: Vec<GroupSettingPB>,
}
impl std::convert::From<Vec<GroupSettingPB>> for RepeatedGroupSettingPB {
fn from(items: Vec<GroupSettingPB>) -> Self {
Self { items }
}
}
impl std::convert::From<Vec<GroupSetting>> for RepeatedGroupSettingPB {
fn from(group_settings: Vec<GroupSetting>) -> Self {
RepeatedGroupSettingPB {
items: group_settings
.iter()
.map(|setting| setting.into())
.collect(),
}
}
}
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
pub struct InsertGroupPayloadPB {
pub struct GroupByFieldPayloadPB {
#[pb(index = 1)]
pub field_id: String,
#[pb(index = 2)]
pub field_type: FieldType,
#[pb(index = 3)]
pub view_id: String,
}
impl TryInto<InsertGroupParams> for InsertGroupPayloadPB {
type Error = ErrorCode;
fn try_into(self) -> Result<InsertGroupParams, Self::Error> {
let field_id = NotEmptyStr::parse(self.field_id)
.map_err(|_| ErrorCode::FieldIdIsEmpty)?
.0;
let view_id = NotEmptyStr::parse(self.view_id)
.map_err(|_| ErrorCode::ViewIdIsInvalid)?
.0;
Ok(InsertGroupParams {
field_id,
field_type: self.field_type,
view_id,
})
}
}
pub struct InsertGroupParams {
pub view_id: String,
pub field_id: String,
pub field_type: FieldType,
}
#[derive(ProtoBuf, Debug, Default, Clone)]
pub struct DeleteGroupPayloadPB {
#[pb(index = 1)]
pub field_id: String,
#[pb(index = 2)]
pub group_id: String,
#[pb(index = 3)]
pub field_type: FieldType,
#[pb(index = 4)]
pub view_id: String,
}
impl TryInto<DeleteGroupParams> for DeleteGroupPayloadPB {
impl TryInto<GroupByFieldParams> for GroupByFieldPayloadPB {
type Error = ErrorCode;
fn try_into(self) -> Result<DeleteGroupParams, Self::Error> {
fn try_into(self) -> Result<GroupByFieldParams, Self::Error> {
let field_id = NotEmptyStr::parse(self.field_id)
.map_err(|_| ErrorCode::FieldIdIsEmpty)?
.0;
let group_id = NotEmptyStr::parse(self.group_id)
.map_err(|_| ErrorCode::FieldIdIsEmpty)?
.0;
let view_id = NotEmptyStr::parse(self.view_id)
.map_err(|_| ErrorCode::ViewIdIsInvalid)?
.0;
Ok(DeleteGroupParams {
Ok(GroupByFieldParams {
field_id,
field_type: self.field_type,
group_id,
view_id,
field_type: self.field_type,
})
}
}
pub struct GroupByFieldParams {
pub field_id: String,
pub view_id: String,
pub field_type: FieldType,
}
pub struct DeleteGroupParams {
pub view_id: String,
pub field_id: String,
pub group_id: String,
pub field_type: FieldType,
}
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
pub struct UpdateGroupPB {
#[pb(index = 1)]
pub view_id: String,
#[pb(index = 2)]
pub group_id: String,
#[pb(index = 3, one_of)]
pub name: Option<String>,
#[pb(index = 4, one_of)]
pub visible: Option<bool>,
}
impl TryInto<UpdateGroupParams> for UpdateGroupPB {
type Error = ErrorCode;
fn try_into(self) -> Result<UpdateGroupParams, Self::Error> {
let view_id = NotEmptyStr::parse(self.view_id)
.map_err(|_| ErrorCode::ViewIdIsInvalid)?
.0;
let group_id = NotEmptyStr::parse(self.group_id)
.map_err(|_| ErrorCode::GroupIdIsEmpty)?
.0;
Ok(UpdateGroupParams {
view_id,
group_id,
name: self.name,
visible: self.visible,
})
}
}
pub struct UpdateGroupParams {
pub view_id: String,
pub group_id: String,
pub name: Option<String>,
pub visible: Option<bool>,
}
impl From<UpdateGroupParams> for GroupChangeset {
fn from(params: UpdateGroupParams) -> Self {
Self {
group_id: params.group_id,
name: params.name,
visible: params.visible,
}
}
}

View File

@ -129,7 +129,7 @@ impl TryInto<MoveGroupParams> for MoveGroupPayloadPB {
}
#[derive(Debug, Default, ProtoBuf)]
pub struct GroupChangesetPB {
pub struct GroupChangesPB {
#[pb(index = 1)]
pub view_id: String,
@ -146,7 +146,7 @@ pub struct GroupChangesetPB {
pub update_groups: Vec<GroupPB>,
}
impl GroupChangesetPB {
impl GroupChangesPB {
pub fn is_empty(&self) -> bool {
self.initial_groups.is_empty()
&& self.inserted_groups.is_empty()

View File

@ -8,10 +8,9 @@ use flowy_error::ErrorCode;
use crate::entities::parser::NotEmptyStr;
use crate::entities::{
AlterFilterParams, AlterFilterPayloadPB, AlterSortParams, AlterSortPayloadPB,
CalendarLayoutSettingPB, DeleteFilterParams, DeleteFilterPayloadPB, DeleteGroupParams,
DeleteGroupPayloadPB, DeleteSortParams, DeleteSortPayloadPB, InsertGroupParams,
InsertGroupPayloadPB, RepeatedFilterPB, RepeatedGroupSettingPB, RepeatedSortPB,
CalendarLayoutSettingPB, DeleteFilterParams, DeleteFilterPayloadPB, DeleteSortParams,
DeleteSortPayloadPB, RepeatedFilterPB, RepeatedGroupSettingPB, RepeatedSortPB,
UpdateFilterParams, UpdateFilterPayloadPB, UpdateGroupPB, UpdateSortParams, UpdateSortPayloadPB,
};
use crate::services::setting::CalendarLayoutSetting;
@ -77,21 +76,18 @@ pub struct DatabaseSettingChangesetPB {
pub layout_type: DatabaseLayoutPB,
#[pb(index = 3, one_of)]
pub alter_filter: Option<AlterFilterPayloadPB>,
pub update_filter: Option<UpdateFilterPayloadPB>,
#[pb(index = 4, one_of)]
pub delete_filter: Option<DeleteFilterPayloadPB>,
#[pb(index = 5, one_of)]
pub insert_group: Option<InsertGroupPayloadPB>,
pub update_group: Option<UpdateGroupPB>,
#[pb(index = 6, one_of)]
pub delete_group: Option<DeleteGroupPayloadPB>,
pub update_sort: Option<UpdateSortPayloadPB>,
#[pb(index = 7, one_of)]
pub alter_sort: Option<AlterSortPayloadPB>,
#[pb(index = 8, one_of)]
pub delete_sort: Option<DeleteSortPayloadPB>,
}
@ -103,7 +99,7 @@ impl TryInto<DatabaseSettingChangesetParams> for DatabaseSettingChangesetPB {
.map_err(|_| ErrorCode::ViewIdIsInvalid)?
.0;
let insert_filter = match self.alter_filter {
let insert_filter = match self.update_filter {
None => None,
Some(payload) => Some(payload.try_into()?),
};
@ -113,17 +109,7 @@ impl TryInto<DatabaseSettingChangesetParams> for DatabaseSettingChangesetPB {
Some(payload) => Some(payload.try_into()?),
};
let insert_group = match self.insert_group {
Some(payload) => Some(payload.try_into()?),
None => None,
};
let delete_group = match self.delete_group {
Some(payload) => Some(payload.try_into()?),
None => None,
};
let alert_sort = match self.alter_sort {
let alert_sort = match self.update_sort {
None => None,
Some(payload) => Some(payload.try_into()?),
};
@ -138,8 +124,6 @@ impl TryInto<DatabaseSettingChangesetParams> for DatabaseSettingChangesetPB {
layout_type: self.layout_type.into(),
insert_filter,
delete_filter,
insert_group,
delete_group,
alert_sort,
delete_sort,
})
@ -149,11 +133,9 @@ impl TryInto<DatabaseSettingChangesetParams> for DatabaseSettingChangesetPB {
pub struct DatabaseSettingChangesetParams {
pub view_id: String,
pub layout_type: DatabaseLayout,
pub insert_filter: Option<AlterFilterParams>,
pub insert_filter: Option<UpdateFilterParams>,
pub delete_filter: Option<DeleteFilterParams>,
pub insert_group: Option<InsertGroupParams>,
pub delete_group: Option<DeleteGroupParams>,
pub alert_sort: Option<AlterSortParams>,
pub alert_sort: Option<UpdateSortParams>,
pub delete_sort: Option<DeleteSortParams>,
}

View File

@ -92,7 +92,7 @@ impl std::convert::From<SortConditionPB> for SortCondition {
}
#[derive(ProtoBuf, Debug, Default, Clone)]
pub struct AlterSortPayloadPB {
pub struct UpdateSortPayloadPB {
#[pb(index = 1)]
pub view_id: String,
@ -110,10 +110,10 @@ pub struct AlterSortPayloadPB {
pub condition: SortConditionPB,
}
impl TryInto<AlterSortParams> for AlterSortPayloadPB {
impl TryInto<UpdateSortParams> for UpdateSortPayloadPB {
type Error = ErrorCode;
fn try_into(self) -> Result<AlterSortParams, Self::Error> {
fn try_into(self) -> Result<UpdateSortParams, Self::Error> {
let view_id = NotEmptyStr::parse(self.view_id)
.map_err(|_| ErrorCode::DatabaseViewIdIsEmpty)?
.0;
@ -131,7 +131,7 @@ impl TryInto<AlterSortParams> for AlterSortPayloadPB {
),
};
Ok(AlterSortParams {
Ok(UpdateSortParams {
view_id,
field_id,
sort_id,
@ -142,7 +142,7 @@ impl TryInto<AlterSortParams> for AlterSortPayloadPB {
}
#[derive(Debug)]
pub struct AlterSortParams {
pub struct UpdateSortParams {
pub view_id: String,
pub field_id: String,
/// Create a new sort if the sort is None

View File

@ -15,9 +15,10 @@ use crate::services::cell::CellBuilder;
use crate::services::field::{
type_option_data_from_pb_or_default, DateCellChangeset, SelectOptionCellChangeset,
};
use crate::services::group::{GroupChangeset, GroupSettingChangeset};
use crate::services::share::csv::CSVFormat;
#[tracing::instrument(level = "trace", skip(data, manager), err)]
#[tracing::instrument(level = "trace", skip_all, err)]
pub(crate) async fn get_database_data_handler(
data: AFPluginData<DatabaseViewIdPB>,
manager: AFPluginState<Arc<DatabaseManager2>>,
@ -49,24 +50,16 @@ pub(crate) async fn update_database_setting_handler(
let params: DatabaseSettingChangesetParams = data.into_inner().try_into()?;
let editor = manager.get_database_with_view_id(&params.view_id).await?;
if let Some(insert_params) = params.insert_group {
editor.insert_group(insert_params).await?;
}
if let Some(delete_params) = params.delete_group {
editor.delete_group(delete_params).await?;
}
if let Some(alter_filter) = params.insert_filter {
editor.create_or_update_filter(alter_filter).await?;
if let Some(update_filter) = params.insert_filter {
editor.create_or_update_filter(update_filter).await?;
}
if let Some(delete_filter) = params.delete_filter {
editor.delete_filter(delete_filter).await?;
}
if let Some(alter_sort) = params.alert_sort {
let _ = editor.create_or_update_sort(alter_sort).await?;
if let Some(update_sort) = params.alert_sort {
let _ = editor.create_or_update_sort(update_sort).await?;
}
if let Some(delete_sort) = params.delete_sort {
editor.delete_sort(delete_sort).await?;
@ -525,6 +518,36 @@ pub(crate) async fn get_group_handler(
data_result_ok(group)
}
#[tracing::instrument(level = "trace", skip_all, err)]
pub(crate) async fn set_group_by_field_handler(
data: AFPluginData<GroupByFieldPayloadPB>,
manager: AFPluginState<Arc<DatabaseManager2>>,
) -> FlowyResult<()> {
let params: GroupByFieldParams = data.into_inner().try_into()?;
let database_editor = manager.get_database_with_view_id(&params.view_id).await?;
database_editor
.set_group_by_field(&params.view_id, &params.field_id)
.await?;
Ok(())
}
#[tracing::instrument(level = "trace", skip_all, err)]
pub(crate) async fn update_group_handler(
data: AFPluginData<UpdateGroupPB>,
manager: AFPluginState<Arc<DatabaseManager2>>,
) -> FlowyResult<()> {
let params: UpdateGroupParams = data.into_inner().try_into()?;
let view_id = params.view_id.clone();
let database_editor = manager.get_database_with_view_id(&view_id).await?;
let group_setting_changeset = GroupSettingChangeset {
update_groups: vec![GroupChangeset::from(params)],
};
database_editor
.update_group_setting(&view_id, group_setting_changeset)
.await?;
Ok(())
}
#[tracing::instrument(level = "debug", skip(data, manager), err)]
pub(crate) async fn move_group_handler(
data: AFPluginData<MoveGroupPayloadPB>,

View File

@ -51,6 +51,8 @@ pub fn init(database_manager: Arc<DatabaseManager2>) -> AFPlugin {
.event(DatabaseEvent::MoveGroupRow, move_group_row_handler)
.event(DatabaseEvent::GetGroups, get_groups_handler)
.event(DatabaseEvent::GetGroup, get_group_handler)
.event(DatabaseEvent::SetGroupByField, set_group_by_field_handler)
.event(DatabaseEvent::UpdateGroup, update_group_handler)
// Database
.event(DatabaseEvent::GetDatabases, get_databases_handler)
// Calendar
@ -243,25 +245,31 @@ pub enum DatabaseEvent {
#[event(input = "MoveGroupRowPayloadPB")]
MoveGroupRow = 112,
#[event(input = "GroupByFieldPayloadPB")]
SetGroupByField = 113,
#[event(input = "UpdateGroupPB")]
UpdateGroup = 114,
/// Returns all the databases
#[event(output = "RepeatedDatabaseDescriptionPB")]
GetDatabases = 114,
GetDatabases = 120,
#[event(input = "LayoutSettingChangesetPB")]
SetLayoutSetting = 115,
SetLayoutSetting = 121,
#[event(input = "DatabaseLayoutIdPB", output = "LayoutSettingPB")]
GetLayoutSetting = 116,
GetLayoutSetting = 122,
#[event(input = "CalendarEventRequestPB", output = "RepeatedCalendarEventPB")]
GetAllCalendarEvents = 117,
GetAllCalendarEvents = 123,
#[event(input = "RowIdPB", output = "CalendarEventPB")]
GetCalendarEvent = 118,
GetCalendarEvent = 124,
#[event(input = "MoveCalendarEventPB")]
MoveCalendarEvent = 119,
MoveCalendarEvent = 125,
#[event(input = "DatabaseImportPB")]
ImportCSV = 120,
ImportCSV = 130,
}

View File

@ -16,7 +16,7 @@ pub enum DatabaseNotification {
/// Trigger after editing a field properties including rename,update type option, etc
DidUpdateField = 50,
/// Trigger after the number of groups is changed
DidUpdateGroups = 60,
DidUpdateNumOfGroups = 60,
/// Trigger after inserting/deleting/updating/moving a row
DidUpdateGroupRow = 61,
/// Trigger when setting a new grouping field

View File

@ -15,11 +15,11 @@ use flowy_task::TaskDispatcher;
use lib_infra::future::{to_fut, Fut};
use crate::entities::{
AlterFilterParams, AlterSortParams, CalendarEventPB, CellChangesetNotifyPB, CellPB,
DatabaseFieldChangesetPB, DatabasePB, DatabaseViewSettingPB, DeleteFilterParams,
DeleteGroupParams, DeleteSortParams, FieldChangesetParams, FieldIdPB, FieldPB, FieldType,
GroupPB, IndexFieldPB, InsertGroupParams, InsertedRowPB, LayoutSettingParams, RepeatedFilterPB,
RepeatedGroupPB, RepeatedSortPB, RowPB, RowsChangePB, SelectOptionCellDataPB, SelectOptionPB,
CalendarEventPB, CellChangesetNotifyPB, CellPB, DatabaseFieldChangesetPB, DatabasePB,
DatabaseViewSettingPB, DeleteFilterParams, DeleteGroupParams, DeleteSortParams,
FieldChangesetParams, FieldIdPB, FieldPB, FieldType, GroupPB, IndexFieldPB, InsertedRowPB,
LayoutSettingParams, RepeatedFilterPB, RepeatedGroupPB, RepeatedSortPB, RowPB, RowsChangePB,
SelectOptionCellDataPB, SelectOptionPB, UpdateFilterParams, UpdateSortParams,
};
use crate::notification::{send_notification, DatabaseNotification};
use crate::services::cell::{
@ -34,7 +34,9 @@ use crate::services::field::{
SelectOptionIds, TypeOptionCellDataHandler, TypeOptionCellExt,
};
use crate::services::filter::Filter;
use crate::services::group::{default_group_setting, GroupSetting, RowChangeset};
use crate::services::group::{
default_group_setting, GroupSetting, GroupSettingChangeset, RowChangeset,
};
use crate::services::share::csv::{CSVExport, CSVFormat};
use crate::services::sort::Sort;
@ -85,18 +87,18 @@ impl DatabaseEditor {
self.database.lock().fields.get_field(field_id)
}
pub async fn insert_group(&self, params: InsertGroupParams) -> FlowyResult<()> {
pub async fn set_group_by_field(&self, view_id: &str, field_id: &str) -> FlowyResult<()> {
{
let database = self.database.lock();
let field = database.fields.get_field(&params.field_id);
let field = database.fields.get_field(field_id);
if let Some(field) = field {
let group_setting = default_group_setting(&field);
database.insert_group_setting(&params.view_id, group_setting);
database.insert_group_setting(view_id, group_setting);
}
}
let view_editor = self.database_views.get_view_editor(&params.view_id).await?;
view_editor.v_initialize_new_group(params).await?;
let view_editor = self.database_views.get_view_editor(view_id).await?;
view_editor.v_initialize_new_group(field_id).await?;
Ok(())
}
@ -111,8 +113,20 @@ impl DatabaseEditor {
Ok(())
}
pub async fn update_group_setting(
&self,
view_id: &str,
group_setting_changeset: GroupSettingChangeset,
) -> FlowyResult<()> {
let view_editor = self.database_views.get_view_editor(view_id).await?;
view_editor
.update_group_setting(group_setting_changeset)
.await?;
Ok(())
}
#[tracing::instrument(level = "trace", skip_all, err)]
pub async fn create_or_update_filter(&self, params: AlterFilterParams) -> FlowyResult<()> {
pub async fn create_or_update_filter(&self, params: UpdateFilterParams) -> FlowyResult<()> {
let view_editor = self.database_views.get_view_editor(&params.view_id).await?;
view_editor.v_insert_filter(params).await?;
Ok(())
@ -124,7 +138,7 @@ impl DatabaseEditor {
Ok(())
}
pub async fn create_or_update_sort(&self, params: AlterSortParams) -> FlowyResult<Sort> {
pub async fn create_or_update_sort(&self, params: UpdateSortParams) -> FlowyResult<Sort> {
let view_editor = self.database_views.get_view_editor(&params.view_id).await?;
let sort = view_editor.v_insert_sort(params).await?;
Ok(sort)
@ -549,6 +563,8 @@ impl DatabaseEditor {
Some(SelectOptionPB::from(select_option))
}
/// Insert the options into the field's type option and update the cell content with the new options.
/// Only used for single select and multiple select.
pub async fn insert_select_options(
&self,
view_id: &str,
@ -556,30 +572,25 @@ impl DatabaseEditor {
row_id: RowId,
options: Vec<SelectOptionPB>,
) -> FlowyResult<()> {
let field = match self.database.lock().fields.get_field(field_id) {
Some(field) => Ok(field),
None => {
let msg = format!("Field with id:{} not found", &field_id);
Err(FlowyError::internal().context(msg))
},
}?;
let field = self.database.lock().fields.get_field(field_id).ok_or(
FlowyError::record_not_found().context(format!("Field with id:{} not found", &field_id)),
)?;
debug_assert!(FieldType::from(field.field_type).is_select_option());
let mut type_option = select_type_option_from_field(&field)?;
let cell_changeset = SelectOptionCellChangeset {
insert_option_ids: options.iter().map(|option| option.id.clone()).collect(),
..Default::default()
};
options
.into_iter()
.for_each(|option| type_option.insert_option(option.into()));
for option in options {
type_option.insert_option(option.into());
}
// Update the field's type option
self
.database
.lock()
.fields
.update_field(field_id, |update| {
update.set_type_option(field.field_type, Some(type_option.to_type_option_data()));
});
.update_field_type_option(view_id, field_id, type_option.to_type_option_data(), field)
.await?;
// Insert the options into the cell
self
.update_cell_with_changeset(view_id, row_id, field_id, cell_changeset)
.await?;
@ -709,7 +720,7 @@ impl DatabaseEditor {
pub async fn group_by_field(&self, view_id: &str, field_id: &str) -> FlowyResult<()> {
let view = self.database_views.get_view_editor(view_id).await?;
view.v_update_group_setting(field_id).await?;
view.v_update_grouping_field(field_id).await?;
Ok(())
}

View File

@ -1,6 +1,6 @@
#![allow(clippy::while_let_loop)]
use crate::entities::{
DatabaseViewSettingPB, FilterChangesetNotificationPB, GroupChangesetPB, GroupRowsNotificationPB,
DatabaseViewSettingPB, FilterChangesetNotificationPB, GroupChangesPB, GroupRowsNotificationPB,
ReorderAllRowsPB, ReorderSingleRowPB, RowsVisibilityChangePB, SortChangesetNotificationPB,
};
use crate::notification::{send_notification, DatabaseNotification};
@ -102,8 +102,8 @@ pub async fn notify_did_update_sort(notification: SortChangesetNotificationPB) {
}
}
pub(crate) async fn notify_did_update_groups(view_id: &str, changeset: GroupChangesetPB) {
send_notification(view_id, DatabaseNotification::DidUpdateGroups)
pub(crate) async fn notify_did_update_num_of_groups(view_id: &str, changeset: GroupChangesPB) {
send_notification(view_id, DatabaseNotification::DidUpdateNumOfGroups)
.payload(changeset)
.send();
}

View File

@ -13,10 +13,10 @@ use flowy_task::TaskDispatcher;
use lib_infra::future::Fut;
use crate::entities::{
AlterFilterParams, AlterSortParams, CalendarEventPB, DeleteFilterParams, DeleteGroupParams,
DeleteSortParams, FieldType, GroupChangesetPB, GroupPB, GroupRowsNotificationPB,
InsertGroupParams, InsertedGroupPB, InsertedRowPB, LayoutSettingPB, LayoutSettingParams, RowPB,
RowsChangePB, SortChangesetNotificationPB, SortPB,
CalendarEventPB, DeleteFilterParams, DeleteGroupParams, DeleteSortParams, FieldType,
GroupChangesPB, GroupPB, GroupRowsNotificationPB, InsertedRowPB, LayoutSettingPB,
LayoutSettingParams, RowPB, RowsChangePB, SortChangesetNotificationPB, SortPB,
UpdateFilterParams, UpdateSortParams,
};
use crate::notification::{send_notification, DatabaseNotification};
use crate::services::cell::CellCache;
@ -27,7 +27,7 @@ use crate::services::database_view::view_group::{
};
use crate::services::database_view::view_sort::make_sort_controller;
use crate::services::database_view::{
notify_did_update_filter, notify_did_update_group_rows, notify_did_update_groups,
notify_did_update_filter, notify_did_update_group_rows, notify_did_update_num_of_groups,
notify_did_update_setting, notify_did_update_sort, DatabaseViewChangedNotifier,
DatabaseViewChangedReceiverRunner,
};
@ -35,7 +35,9 @@ use crate::services::field::TypeOptionCellDataHandler;
use crate::services::filter::{
Filter, FilterChangeset, FilterController, FilterType, UpdatedFilterType,
};
use crate::services::group::{GroupController, GroupSetting, MoveGroupRowContext, RowChangeset};
use crate::services::group::{
GroupController, GroupSetting, GroupSettingChangeset, MoveGroupRowContext, RowChangeset,
};
use crate::services::setting::CalendarLayoutSetting;
use crate::services::sort::{DeletedSortType, Sort, SortChangeset, SortController, SortType};
@ -237,26 +239,28 @@ impl DatabaseViewEditor {
.await;
if let Some(Ok(result)) = result {
let mut changeset = GroupChangesetPB {
let mut group_changes = GroupChangesPB {
view_id: self.view_id.clone(),
..Default::default()
};
if let Some(inserted_group) = result.inserted_group {
tracing::trace!("Create group after editing the row: {:?}", inserted_group);
changeset.inserted_groups.push(inserted_group);
group_changes.inserted_groups.push(inserted_group);
}
if let Some(delete_group) = result.deleted_group {
tracing::trace!("Delete group after editing the row: {:?}", delete_group);
changeset.deleted_groups.push(delete_group.group_id);
group_changes.deleted_groups.push(delete_group.group_id);
}
if !group_changes.is_empty() {
notify_did_update_num_of_groups(&self.view_id, group_changes).await;
}
notify_did_update_groups(&self.view_id, changeset).await;
tracing::trace!(
"Group changesets after editing the row: {:?}",
result.row_changesets
);
for changeset in result.row_changesets {
notify_did_update_group_rows(changeset).await;
if !changeset.is_empty() {
tracing::trace!("Group change after editing the row: {:?}", changeset);
notify_did_update_group_rows(changeset).await;
}
}
} else {
let update_row = UpdatedRow {
@ -326,15 +330,15 @@ impl DatabaseViewEditor {
.await;
if let Some(result) = result {
let mut changeset = GroupChangesetPB {
view_id: self.view_id.clone(),
..Default::default()
};
if let Some(delete_group) = result.deleted_group {
tracing::info!("Delete group after moving the row: {:?}", delete_group);
changeset.deleted_groups.push(delete_group.group_id);
tracing::trace!("Delete group after moving the row: {:?}", delete_group);
let mut changes = GroupChangesPB {
view_id: self.view_id.clone(),
..Default::default()
};
changes.deleted_groups.push(delete_group.group_id);
notify_did_update_num_of_groups(&self.view_id, changes).await;
}
notify_did_update_groups(&self.view_id, changeset).await;
for changeset in result.row_changesets {
notify_did_update_group_rows(changeset).await;
@ -371,25 +375,6 @@ impl DatabaseViewEditor {
.write()
.await
.move_group(from_group, to_group)?;
match self.group_controller.read().await.get_group(from_group) {
None => tracing::warn!("Can not find the group with id: {}", from_group),
Some((index, group)) => {
let inserted_group = InsertedGroupPB {
group: GroupPB::from(group),
index: index as i32,
};
let changeset = GroupChangesetPB {
view_id: self.view_id.clone(),
inserted_groups: vec![inserted_group],
deleted_groups: vec![from_group.to_string()],
update_groups: vec![],
initial_groups: vec![],
};
notify_did_update_groups(&self.view_id, changeset).await;
},
}
Ok(())
}
@ -397,9 +382,9 @@ impl DatabaseViewEditor {
self.group_controller.read().await.field_id().to_string()
}
pub async fn v_initialize_new_group(&self, params: InsertGroupParams) -> FlowyResult<()> {
if self.group_controller.read().await.field_id() != params.field_id {
self.v_update_group_setting(&params.field_id).await?;
pub async fn v_initialize_new_group(&self, field_id: &str) -> FlowyResult<()> {
if self.group_controller.read().await.field_id() != field_id {
self.v_update_grouping_field(field_id).await?;
if let Some(view) = self.delegate.get_view_setting(&self.view_id).await {
let setting = database_view_setting_pb_from_view(view);
@ -413,12 +398,20 @@ impl DatabaseViewEditor {
Ok(())
}
pub async fn update_group_setting(&self, changeset: GroupSettingChangeset) -> FlowyResult<()> {
self
.group_controller
.write()
.await
.apply_group_setting_changeset(changeset)
}
pub async fn v_get_all_sorts(&self) -> Vec<Sort> {
self.delegate.get_all_sorts(&self.view_id)
}
#[tracing::instrument(level = "trace", skip(self), err)]
pub async fn v_insert_sort(&self, params: AlterSortParams) -> FlowyResult<Sort> {
pub async fn v_insert_sort(&self, params: UpdateSortParams) -> FlowyResult<Sort> {
let is_exist = params.sort_id.is_some();
let sort_id = match params.sort_id {
None => gen_database_sort_id(),
@ -479,7 +472,7 @@ impl DatabaseViewEditor {
}
#[tracing::instrument(level = "trace", skip(self), err)]
pub async fn v_insert_filter(&self, params: AlterFilterParams) -> FlowyResult<()> {
pub async fn v_insert_filter(&self, params: UpdateFilterParams) -> FlowyResult<()> {
let is_exist = params.filter_id.is_some();
let filter_id = match params.filter_id {
None => gen_database_filter_id(),
@ -634,9 +627,15 @@ impl DatabaseViewEditor {
.sort_controller
.read()
.await
.did_update_view_field_type_option(&field)
.did_update_field_type_option(&field)
.await;
self
.group_controller
.write()
.await
.did_update_field_type_option(&field);
if let Some(filter) = self
.delegate
.get_filter_by_field_id(&self.view_id, field_id)
@ -660,14 +659,9 @@ impl DatabaseViewEditor {
Ok(())
}
///
///
/// # Arguments
///
/// * `field_id`:
///
/// Called when a grouping field is updated.
#[tracing::instrument(level = "debug", skip_all, err)]
pub async fn v_update_group_setting(&self, field_id: &str) -> FlowyResult<()> {
pub async fn v_update_grouping_field(&self, field_id: &str) -> FlowyResult<()> {
if let Some(field) = self.delegate.get_field(field_id).await {
let new_group_controller =
new_group_controller_with_field(self.view_id.clone(), self.delegate.clone(), field).await?;
@ -679,7 +673,7 @@ impl DatabaseViewEditor {
.collect();
*self.group_controller.write().await = new_group_controller;
let changeset = GroupChangesetPB {
let changeset = GroupChangesPB {
view_id: self.view_id.clone(),
initial_groups: new_groups,
..Default::default()

View File

@ -5,7 +5,6 @@ use collab_database::rows::RowId;
use flowy_error::{FlowyError, FlowyResult};
use lib_infra::future::{to_fut, Fut};
use tracing::trace;
use crate::entities::FieldType;
use crate::services::database_view::DatabaseViewData;
@ -43,7 +42,6 @@ pub async fn new_group_controller(
let fields = delegate.get_fields(&view_id, None).await;
let rows = delegate.get_rows(&view_id).await;
let layout = delegate.get_layout_for_view(&view_id);
trace!(?fields, ?rows, ?layout, "new_group_controller");
// Read the grouping field or find a new grouping field
let mut grouping_field = setting_reader

View File

@ -94,7 +94,7 @@ impl DatabaseViews {
// If the id of the grouping field is equal to the updated field's id, then we need to
// update the group setting
if view_editor.group_id().await == field_id {
view_editor.v_update_group_setting(field_id).await?;
view_editor.v_update_grouping_field(field_id).await?;
}
view_editor
.v_did_update_field_type_option(field_id, old_field)
@ -108,7 +108,6 @@ impl DatabaseViews {
return Ok(editor.clone());
}
tracing::trace!("{:p} create view:{} editor", self, view_id);
let mut editor_map = self.editor_map.write().await;
let editor = Arc::new(
DatabaseViewEditor::new(

View File

@ -22,6 +22,8 @@ pub trait SelectTypeOptionSharedAction: Send + Sync {
fn number_of_max_options(&self) -> Option<usize>;
/// Insert the `SelectOption` into corresponding type option.
/// If the option already exists, it will be updated.
/// If the option does not exist, it will be inserted at the beginning.
fn insert_option(&mut self, new_option: SelectOption) {
let options = self.mut_options();
if let Some(index) = options

View File

@ -131,12 +131,12 @@ where
if let Some(cell_data_cache) = self.cell_data_cache.as_ref() {
let read_guard = cell_data_cache.read();
if let Some(cell_data) = read_guard.get(key.as_ref()).cloned() {
tracing::trace!(
"Cell cache hit: field_type:{}, cell: {:?}, cell_data: {:?}",
decoded_field_type,
cell,
cell_data
);
// tracing::trace!(
// "Cell cache hit: field_type:{}, cell: {:?}, cell_data: {:?}",
// decoded_field_type,
// cell,
// cell_data
// );
return Ok(cell_data);
}
}

View File

@ -219,12 +219,14 @@ impl FilterController {
}
pub async fn did_receive_row_changed(&self, row_id: RowId) {
self
.gen_task(
FilterEvent::RowDidChanged(row_id),
QualityOfService::UserInteractive,
)
.await
if !self.cell_filter_cache.read().is_empty() {
self
.gen_task(
FilterEvent::RowDidChanged(row_id),
QualityOfService::UserInteractive,
)
.await
}
}
#[tracing::instrument(level = "trace", skip(self))]

View File

@ -1,7 +1,7 @@
use crate::entities::{GroupChangesetPB, GroupPB, GroupRowsNotificationPB, InsertedGroupPB};
use crate::entities::{GroupChangesPB, GroupPB, GroupRowsNotificationPB, InsertedGroupPB};
use crate::services::cell::DecodedCellData;
use crate::services::group::controller::MoveGroupRowContext;
use crate::services::group::GroupData;
use crate::services::group::{GroupData, GroupSettingChangeset};
use collab_database::fields::Field;
use collab_database::rows::{Cell, Row};
@ -65,7 +65,7 @@ pub trait GroupCustomize: Send + Sync {
}
/// Defines the shared actions any group controller can perform.
pub trait GroupControllerActions: Send + Sync {
pub trait GroupControllerOperation: Send + Sync {
/// The field that is used for grouping the rows
fn field_id(&self) -> &str;
@ -100,7 +100,9 @@ pub trait GroupControllerActions: Send + Sync {
fn move_group_row(&mut self, context: MoveGroupRowContext) -> FlowyResult<DidMoveGroupRowResult>;
/// Update the group if the corresponding field is changed
fn did_update_group_field(&mut self, field: &Field) -> FlowyResult<Option<GroupChangesetPB>>;
fn did_update_group_field(&mut self, field: &Field) -> FlowyResult<Option<GroupChangesPB>>;
fn apply_group_setting_changeset(&mut self, changeset: GroupSettingChangeset) -> FlowyResult<()>;
}
#[derive(Debug)]

View File

@ -1,7 +1,7 @@
use crate::entities::{GroupChangesetPB, GroupPB, InsertedGroupPB};
use crate::entities::{GroupChangesPB, GroupPB, InsertedGroupPB};
use crate::services::field::RowSingleCellData;
use crate::services::group::{
default_group_setting, GeneratedGroupContext, Group, GroupData, GroupSetting,
default_group_setting, GeneratedGroups, Group, GroupChangeset, GroupData, GroupSetting,
};
use collab_database::fields::Field;
use flowy_error::{FlowyError, FlowyResult};
@ -25,7 +25,7 @@ pub trait GroupSettingWriter: Send + Sync + 'static {
impl<T> std::fmt::Display for GroupContext<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
self.groups_map.iter().for_each(|(_, group)| {
self.group_by_id.iter().for_each(|(_, group)| {
let _ = f.write_fmt(format_args!(
"Group:{} has {} rows \n",
group.id,
@ -54,8 +54,9 @@ pub struct GroupContext<C> {
/// The grouping field
field: Arc<Field>,
/// Cache all the groups
groups_map: IndexMap<String, GroupData>,
/// Cache all the groups. Cache the group by its id.
/// We use the id of the [Field] as the [No Status] group id.
group_by_id: IndexMap<String, GroupData>,
/// A reader that implement the [GroupSettingReader] trait
///
@ -93,7 +94,7 @@ where
Ok(Self {
view_id,
field,
groups_map: IndexMap::new(),
group_by_id: IndexMap::new(),
reader,
writer,
setting,
@ -105,26 +106,26 @@ where
///
/// We take the `id` of the `field` as the no status group id
pub(crate) fn get_no_status_group(&self) -> Option<&GroupData> {
self.groups_map.get(&self.field.id)
self.group_by_id.get(&self.field.id)
}
pub(crate) fn get_mut_no_status_group(&mut self) -> Option<&mut GroupData> {
self.groups_map.get_mut(&self.field.id)
self.group_by_id.get_mut(&self.field.id)
}
pub(crate) fn groups(&self) -> Vec<&GroupData> {
self.groups_map.values().collect()
self.group_by_id.values().collect()
}
pub(crate) fn get_mut_group(&mut self, group_id: &str) -> Option<&mut GroupData> {
self.groups_map.get_mut(group_id)
self.group_by_id.get_mut(group_id)
}
// Returns the index and group specified by the group_id
pub(crate) fn get_group(&self, group_id: &str) -> Option<(usize, &GroupData)> {
match (
self.groups_map.get_index_of(group_id),
self.groups_map.get(group_id),
self.group_by_id.get_index_of(group_id),
self.group_by_id.get(group_id),
) {
(Some(index), Some(group)) => Some((index, group)),
_ => None,
@ -133,7 +134,7 @@ where
/// Iterate mut the groups without `No status` group
pub(crate) fn iter_mut_status_groups(&mut self, mut each: impl FnMut(&mut GroupData)) {
self.groups_map.iter_mut().for_each(|(_, group)| {
self.group_by_id.iter_mut().for_each(|(_, group)| {
if group.id != self.field.id {
each(group);
}
@ -141,7 +142,7 @@ where
}
pub(crate) fn iter_mut_groups(&mut self, mut each: impl FnMut(&mut GroupData)) {
self.groups_map.iter_mut().for_each(|(_, group)| {
self.group_by_id.iter_mut().for_each(|(_, group)| {
each(group);
});
}
@ -153,7 +154,7 @@ where
group.name.clone(),
group.id.clone(),
);
self.groups_map.insert(group.id.clone(), group_data);
self.group_by_id.insert(group.id.clone(), group_data);
let (index, group_data) = self.get_group(&group.id).unwrap();
let insert_group = InsertedGroupPB {
group: GroupPB::from(group_data.clone()),
@ -170,7 +171,7 @@ where
#[tracing::instrument(level = "trace", skip(self))]
pub(crate) fn delete_group(&mut self, deleted_group_id: &str) -> FlowyResult<()> {
self.groups_map.remove(deleted_group_id);
self.group_by_id.remove(deleted_group_id);
self.mut_configuration(|configuration| {
configuration
.groups
@ -181,11 +182,11 @@ where
}
pub(crate) fn move_group(&mut self, from_id: &str, to_id: &str) -> FlowyResult<()> {
let from_index = self.groups_map.get_index_of(from_id);
let to_index = self.groups_map.get_index_of(to_id);
let from_index = self.group_by_id.get_index_of(from_id);
let to_index = self.group_by_id.get_index_of(to_id);
match (from_index, to_index) {
(Some(from_index), Some(to_index)) => {
self.groups_map.move_index(from_index, to_index);
self.group_by_id.move_index(from_index, to_index);
self.mut_configuration(|configuration| {
let from_index = configuration
@ -205,7 +206,7 @@ where
let group = configuration.groups.remove(*from);
configuration.groups.insert(*to, group);
}
tracing::debug!(
tracing::trace!(
"Group order: {:?} ",
configuration
.groups
@ -237,15 +238,15 @@ where
/// [GroupConfigurationRevision] as old groups. The old groups and the new groups will be merged
/// while keeping the order of the old groups.
///
#[tracing::instrument(level = "trace", skip(self, generated_group_context), err)]
#[tracing::instrument(level = "trace", skip_all, err)]
pub(crate) fn init_groups(
&mut self,
generated_group_context: GeneratedGroupContext,
) -> FlowyResult<Option<GroupChangesetPB>> {
let GeneratedGroupContext {
generated_groups: GeneratedGroups,
) -> FlowyResult<Option<GroupChangesPB>> {
let GeneratedGroups {
no_status_group,
group_configs,
} = generated_group_context;
} = generated_groups;
let mut new_groups = vec![];
let mut filter_content_map = HashMap::new();
@ -310,18 +311,13 @@ where
})?;
// Update the memory cache of the groups
all_groups.into_iter().for_each(|group_rev| {
all_groups.into_iter().for_each(|group| {
let filter_content = filter_content_map
.get(&group_rev.id)
.get(&group.id)
.cloned()
.unwrap_or_else(|| "".to_owned());
let group = GroupData::new(
group_rev.id,
self.field.id.clone(),
group_rev.name,
filter_content,
);
self.groups_map.insert(group.id.clone(), group);
let group = GroupData::new(group.id, self.field.id.clone(), group.name, filter_content);
self.group_by_id.insert(group.id.clone(), group);
});
let initial_groups = new_groups
@ -338,13 +334,14 @@ where
})
.collect();
let changeset = GroupChangesetPB {
let changeset = GroupChangesPB {
view_id: self.view_id.clone(),
initial_groups,
deleted_groups: deleted_group_ids,
update_groups: vec![],
inserted_groups: vec![],
};
tracing::trace!("Group changeset: {:?}", changeset);
if changeset.is_empty() {
Ok(None)
@ -353,18 +350,15 @@ where
}
}
#[allow(dead_code)]
pub(crate) async fn hide_group(&mut self, group_id: &str) -> FlowyResult<()> {
self.mut_group_rev(group_id, |group_rev| {
group_rev.visible = false;
})?;
Ok(())
}
pub(crate) fn update_group(&mut self, group_changeset: GroupChangeset) -> FlowyResult<()> {
self.mut_group(&group_changeset.group_id, |group| {
if let Some(visible) = group_changeset.visible {
group.visible = visible;
}
#[allow(dead_code)]
pub(crate) async fn show_group(&mut self, group_id: &str) -> FlowyResult<()> {
self.mut_group_rev(group_id, |group_rev| {
group_rev.visible = true;
if let Some(name) = &group_changeset.name {
group.name = name.clone();
}
})?;
Ok(())
}
@ -398,11 +392,7 @@ where
Ok(())
}
fn mut_group_rev(
&mut self,
group_id: &str,
mut_groups_fn: impl Fn(&mut Group),
) -> FlowyResult<()> {
fn mut_group(&mut self, group_id: &str, mut_groups_fn: impl Fn(&mut Group)) -> FlowyResult<()> {
self.mut_configuration(|configuration| {
match configuration
.groups

View File

@ -9,14 +9,14 @@ use serde::Serialize;
use flowy_error::FlowyResult;
use crate::entities::{FieldType, GroupChangesetPB, GroupRowsNotificationPB, InsertedRowPB};
use crate::entities::{FieldType, GroupChangesPB, GroupRowsNotificationPB, InsertedRowPB};
use crate::services::cell::{get_cell_protobuf, CellProtobufBlobParser, DecodedCellData};
use crate::services::group::action::{
DidMoveGroupRowResult, DidUpdateGroupRowResult, GroupControllerActions, GroupCustomize,
DidMoveGroupRowResult, DidUpdateGroupRowResult, GroupControllerOperation, GroupCustomize,
};
use crate::services::group::configuration::GroupContext;
use crate::services::group::entities::GroupData;
use crate::services::group::Group;
use crate::services::group::{Group, GroupSettingChangeset};
// use collab_database::views::Group;
@ -28,24 +28,30 @@ use crate::services::group::Group;
/// If the [FieldType] doesn't implement its group controller, then the [DefaultGroupController] will
/// be used.
///
pub trait GroupController: GroupControllerActions + Send + Sync {
pub trait GroupController: GroupControllerOperation + Send + Sync {
/// Called when the type option of the [Field] was updated.
fn did_update_field_type_option(&mut self, field: &Arc<Field>);
/// Called before the row was created.
fn will_create_row(&mut self, cells: &mut Cells, field: &Field, group_id: &str);
/// Called after the row was created.
fn did_create_row(&mut self, row: &Row, group_id: &str);
}
/// The [GroupGenerator] trait is used to generate the groups for different [FieldType]
pub trait GroupGenerator {
/// The [GroupsBuilder] trait is used to generate the groups for different [FieldType]
pub trait GroupsBuilder {
type Context;
type TypeOptionType;
fn generate_groups(
fn build(
field: &Field,
group_ctx: &Self::Context,
context: &Self::Context,
type_option: &Option<Self::TypeOptionType>,
) -> GeneratedGroupContext;
) -> GeneratedGroups;
}
pub struct GeneratedGroupContext {
pub struct GeneratedGroups {
pub no_status_group: Option<Group>,
pub group_configs: Vec<GeneratedGroupConfig>,
}
@ -90,21 +96,21 @@ impl RowChangeset {
/// C: represents the group configuration that impl [GroupConfigurationSerde]
/// T: the type-option data deserializer that impl [TypeOptionDataDeserializer]
/// G: the group generator, [GroupGenerator]
/// G: the group generator, [GroupsBuilder]
/// P: the parser that impl [CellProtobufBlobParser] for the CellBytes
pub struct GenericGroupController<C, T, G, P> {
pub struct BaseGroupController<C, T, G, P> {
pub grouping_field_id: String,
pub type_option: Option<T>,
pub group_ctx: GroupContext<C>,
pub context: GroupContext<C>,
group_action_phantom: PhantomData<G>,
cell_parser_phantom: PhantomData<P>,
}
impl<C, T, G, P> GenericGroupController<C, T, G, P>
impl<C, T, G, P> BaseGroupController<C, T, G, P>
where
C: Serialize + DeserializeOwned,
T: From<TypeOptionData>,
G: GroupGenerator<Context = GroupContext<C>, TypeOptionType = T>,
G: GroupsBuilder<Context = GroupContext<C>, TypeOptionType = T>,
{
pub async fn new(
grouping_field: &Arc<Field>,
@ -112,13 +118,13 @@ where
) -> FlowyResult<Self> {
let field_type = FieldType::from(grouping_field.field_type);
let type_option = grouping_field.get_type_option::<T>(field_type);
let generated_group_context = G::generate_groups(grouping_field, &configuration, &type_option);
let _ = configuration.init_groups(generated_group_context)?;
let generated_groups = G::build(grouping_field, &configuration, &type_option);
let _ = configuration.init_groups(generated_groups)?;
Ok(Self {
grouping_field_id: grouping_field.id.clone(),
type_option,
group_ctx: configuration,
context: configuration,
group_action_phantom: PhantomData,
cell_parser_phantom: PhantomData,
})
@ -131,7 +137,7 @@ where
row: &Row,
other_group_changesets: &[GroupRowsNotificationPB],
) -> Option<GroupRowsNotificationPB> {
let no_status_group = self.group_ctx.get_mut_no_status_group()?;
let no_status_group = self.context.get_mut_no_status_group()?;
// [other_group_inserted_row] contains all the inserted rows except the default group.
let other_group_inserted_row = other_group_changesets
@ -196,12 +202,12 @@ where
}
}
impl<C, T, G, P> GroupControllerActions for GenericGroupController<C, T, G, P>
impl<C, T, G, P> GroupControllerOperation for BaseGroupController<C, T, G, P>
where
P: CellProtobufBlobParser,
C: Serialize + DeserializeOwned,
T: From<TypeOptionData>,
G: GroupGenerator<Context = GroupContext<C>, TypeOptionType = T>,
G: GroupsBuilder<Context = GroupContext<C>, TypeOptionType = T>,
Self: GroupCustomize<CellData = P::Object>,
{
@ -210,11 +216,11 @@ where
}
fn groups(&self) -> Vec<&GroupData> {
self.group_ctx.groups()
self.context.groups()
}
fn get_group(&self, group_id: &str) -> Option<(usize, GroupData)> {
let group = self.group_ctx.get_group(group_id)?;
let group = self.context.get_group(group_id)?;
Some((group.0, group.1.clone()))
}
@ -230,7 +236,7 @@ where
let mut grouped_rows: Vec<GroupedRow> = vec![];
let cell_bytes = get_cell_protobuf(&cell, field, None);
let cell_data = cell_bytes.parser::<P>()?;
for group in self.group_ctx.groups() {
for group in self.context.groups() {
if self.can_group(&group.filter_content, &cell_data) {
grouped_rows.push(GroupedRow {
row: (*row).clone(),
@ -241,25 +247,25 @@ where
if !grouped_rows.is_empty() {
for group_row in grouped_rows {
if let Some(group) = self.group_ctx.get_mut_group(&group_row.group_id) {
if let Some(group) = self.context.get_mut_group(&group_row.group_id) {
group.add_row(group_row.row);
}
}
continue;
}
}
match self.group_ctx.get_mut_no_status_group() {
match self.context.get_mut_no_status_group() {
None => {},
Some(no_status_group) => no_status_group.add_row((*row).clone()),
}
}
tracing::Span::current().record("group_result", format!("{},", self.group_ctx,).as_str());
tracing::Span::current().record("group_result", format!("{},", self.context,).as_str());
Ok(())
}
fn move_group(&mut self, from_group_id: &str, to_group_id: &str) -> FlowyResult<()> {
self.group_ctx.move_group(from_group_id, to_group_id)
self.context.move_group(from_group_id, to_group_id)
}
fn did_update_group_row(
@ -320,7 +326,7 @@ where
}
}
match self.group_ctx.get_no_status_group() {
match self.context.get_no_status_group() {
None => {
tracing::error!("Unexpected None value. It should have the no status group");
},
@ -359,9 +365,18 @@ where
Ok(result)
}
fn did_update_group_field(&mut self, _field: &Field) -> FlowyResult<Option<GroupChangesetPB>> {
fn did_update_group_field(&mut self, _field: &Field) -> FlowyResult<Option<GroupChangesPB>> {
Ok(None)
}
fn apply_group_setting_changeset(&mut self, changeset: GroupSettingChangeset) -> FlowyResult<()> {
for group_changeset in changeset.update_groups {
if let Err(e) = self.context.update_group(group_changeset) {
tracing::error!("Failed to update group: {:?}", e);
}
}
Ok(())
}
}
struct GroupedRow {

View File

@ -1,6 +1,7 @@
use collab_database::fields::Field;
use collab_database::rows::{new_cell_builder, Cell, Cells, Row};
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use crate::entities::{FieldType, GroupRowsNotificationPB, InsertedRowPB, RowPB};
use crate::services::cell::insert_checkbox_cell;
@ -10,16 +11,16 @@ use crate::services::field::{
use crate::services::group::action::GroupCustomize;
use crate::services::group::configuration::GroupContext;
use crate::services::group::controller::{
GenericGroupController, GroupController, GroupGenerator, MoveGroupRowContext,
BaseGroupController, GroupController, GroupsBuilder, MoveGroupRowContext,
};
use crate::services::group::{move_group_row, GeneratedGroupConfig, GeneratedGroupContext, Group};
use crate::services::group::{move_group_row, GeneratedGroupConfig, GeneratedGroups, Group};
#[derive(Default, Serialize, Deserialize)]
pub struct CheckboxGroupConfiguration {
pub hide_empty: bool,
}
pub type CheckboxGroupController = GenericGroupController<
pub type CheckboxGroupController = BaseGroupController<
CheckboxGroupConfiguration,
CheckboxTypeOption,
CheckboxGroupGenerator,
@ -52,7 +53,7 @@ impl GroupCustomize for CheckboxGroupController {
cell_data: &Self::CellData,
) -> Vec<GroupRowsNotificationPB> {
let mut changesets = vec![];
self.group_ctx.iter_mut_status_groups(|group| {
self.context.iter_mut_status_groups(|group| {
let mut changeset = GroupRowsNotificationPB::new(group.id.clone());
let is_not_contained = !group.contains_row(&row.id);
if group.id == CHECK {
@ -96,7 +97,7 @@ impl GroupCustomize for CheckboxGroupController {
fn delete_row(&mut self, row: &Row, _cell_data: &Self::CellData) -> Vec<GroupRowsNotificationPB> {
let mut changesets = vec![];
self.group_ctx.iter_mut_groups(|group| {
self.context.iter_mut_groups(|group| {
let mut changeset = GroupRowsNotificationPB::new(group.id.clone());
if group.contains_row(&row.id) {
changeset.deleted_rows.push(row.id.clone().into_inner());
@ -116,7 +117,7 @@ impl GroupCustomize for CheckboxGroupController {
mut context: MoveGroupRowContext,
) -> Vec<GroupRowsNotificationPB> {
let mut group_changeset = vec![];
self.group_ctx.iter_mut_groups(|group| {
self.context.iter_mut_groups(|group| {
if let Some(changeset) = move_group_row(group, &mut context) {
group_changeset.push(changeset);
}
@ -126,8 +127,12 @@ impl GroupCustomize for CheckboxGroupController {
}
impl GroupController for CheckboxGroupController {
fn did_update_field_type_option(&mut self, _field: &Arc<Field>) {
// Do nothing
}
fn will_create_row(&mut self, cells: &mut Cells, field: &Field, group_id: &str) {
match self.group_ctx.get_group(group_id) {
match self.context.get_group(group_id) {
None => tracing::warn!("Can not find the group: {}", group_id),
Some((_, group)) => {
let is_check = group.id == CHECK;
@ -138,22 +143,22 @@ impl GroupController for CheckboxGroupController {
}
fn did_create_row(&mut self, row: &Row, group_id: &str) {
if let Some(group) = self.group_ctx.get_mut_group(group_id) {
if let Some(group) = self.context.get_mut_group(group_id) {
group.add_row(row.clone())
}
}
}
pub struct CheckboxGroupGenerator();
impl GroupGenerator for CheckboxGroupGenerator {
impl GroupsBuilder for CheckboxGroupGenerator {
type Context = CheckboxGroupContext;
type TypeOptionType = CheckboxTypeOption;
fn generate_groups(
fn build(
_field: &Field,
_group_ctx: &Self::Context,
_context: &Self::Context,
_type_option: &Option<Self::TypeOptionType>,
) -> GeneratedGroupContext {
) -> GeneratedGroups {
let check_group = GeneratedGroupConfig {
group: Group::new(CHECK.to_string(), "".to_string()),
filter_content: CHECK.to_string(),
@ -164,7 +169,7 @@ impl GroupGenerator for CheckboxGroupGenerator {
filter_content: UNCHECK.to_string(),
};
GeneratedGroupContext {
GeneratedGroups {
no_status_group: None,
group_configs: vec![check_group, uncheck_group],
}

View File

@ -5,11 +5,13 @@ use collab_database::rows::{Cells, Row};
use flowy_error::FlowyResult;
use crate::entities::GroupChangesetPB;
use crate::entities::GroupChangesPB;
use crate::services::group::action::{
DidMoveGroupRowResult, DidUpdateGroupRowResult, GroupControllerActions,
DidMoveGroupRowResult, DidUpdateGroupRowResult, GroupControllerOperation,
};
use crate::services::group::{
GroupController, GroupData, GroupSettingChangeset, MoveGroupRowContext,
};
use crate::services::group::{GroupController, GroupData, MoveGroupRowContext};
/// A [DefaultGroupController] is used to handle the group actions for the [FieldType] that doesn't
/// implement its own group controller. The default group controller only contains one group, which
@ -37,7 +39,7 @@ impl DefaultGroupController {
}
}
impl GroupControllerActions for DefaultGroupController {
impl GroupControllerOperation for DefaultGroupController {
fn field_id(&self) -> &str {
&self.field_id
}
@ -95,12 +97,23 @@ impl GroupControllerActions for DefaultGroupController {
})
}
fn did_update_group_field(&mut self, _field: &Field) -> FlowyResult<Option<GroupChangesetPB>> {
fn did_update_group_field(&mut self, _field: &Field) -> FlowyResult<Option<GroupChangesPB>> {
Ok(None)
}
fn apply_group_setting_changeset(
&mut self,
_changeset: GroupSettingChangeset,
) -> FlowyResult<()> {
Ok(())
}
}
impl GroupController for DefaultGroupController {
fn did_update_field_type_option(&mut self, _field: &Arc<Field>) {
// Do nothing
}
fn will_create_row(&mut self, _cells: &mut Cells, _field: &Field, _group_id: &str) {}
fn did_create_row(&mut self, _row: &Row, _group_id: &str) {}

View File

@ -3,14 +3,15 @@ use crate::services::cell::insert_select_option_cell;
use crate::services::field::{MultiSelectTypeOption, SelectOptionCellDataParser};
use crate::services::group::action::GroupCustomize;
use crate::services::group::controller::{
GenericGroupController, GroupController, GroupGenerator, MoveGroupRowContext,
BaseGroupController, GroupController, GroupsBuilder, MoveGroupRowContext,
};
use crate::services::group::{
add_or_remove_select_option_row, generate_select_option_groups, make_no_status_group,
move_group_row, remove_select_option_row, GeneratedGroupContext, GroupContext,
move_group_row, remove_select_option_row, GeneratedGroups, GroupContext,
};
use collab_database::fields::Field;
use collab_database::rows::{Cells, Row};
use std::sync::Arc;
use serde::{Deserialize, Serialize};
@ -21,7 +22,7 @@ pub struct MultiSelectGroupConfiguration {
pub type MultiSelectOptionGroupContext = GroupContext<MultiSelectGroupConfiguration>;
// MultiSelect
pub type MultiSelectGroupController = GenericGroupController<
pub type MultiSelectGroupController = BaseGroupController<
MultiSelectGroupConfiguration,
MultiSelectTypeOption,
MultiSelectGroupGenerator,
@ -44,7 +45,7 @@ impl GroupCustomize for MultiSelectGroupController {
cell_data: &Self::CellData,
) -> Vec<GroupRowsNotificationPB> {
let mut changesets = vec![];
self.group_ctx.iter_mut_status_groups(|group| {
self.context.iter_mut_status_groups(|group| {
if let Some(changeset) = add_or_remove_select_option_row(group, cell_data, row) {
changesets.push(changeset);
}
@ -54,7 +55,7 @@ impl GroupCustomize for MultiSelectGroupController {
fn delete_row(&mut self, row: &Row, cell_data: &Self::CellData) -> Vec<GroupRowsNotificationPB> {
let mut changesets = vec![];
self.group_ctx.iter_mut_status_groups(|group| {
self.context.iter_mut_status_groups(|group| {
if let Some(changeset) = remove_select_option_row(group, cell_data, row) {
changesets.push(changeset);
}
@ -68,7 +69,7 @@ impl GroupCustomize for MultiSelectGroupController {
mut context: MoveGroupRowContext,
) -> Vec<GroupRowsNotificationPB> {
let mut group_changeset = vec![];
self.group_ctx.iter_mut_groups(|group| {
self.context.iter_mut_groups(|group| {
if let Some(changeset) = move_group_row(group, &mut context) {
group_changeset.push(changeset);
}
@ -78,8 +79,10 @@ impl GroupCustomize for MultiSelectGroupController {
}
impl GroupController for MultiSelectGroupController {
fn did_update_field_type_option(&mut self, _field: &Arc<Field>) {}
fn will_create_row(&mut self, cells: &mut Cells, field: &Field, group_id: &str) {
match self.group_ctx.get_group(group_id) {
match self.context.get_group(group_id) {
None => tracing::warn!("Can not find the group: {}", group_id),
Some((_, group)) => {
let cell = insert_select_option_cell(vec![group.id.clone()], field);
@ -89,28 +92,28 @@ impl GroupController for MultiSelectGroupController {
}
fn did_create_row(&mut self, row: &Row, group_id: &str) {
if let Some(group) = self.group_ctx.get_mut_group(group_id) {
if let Some(group) = self.context.get_mut_group(group_id) {
group.add_row(row.clone())
}
}
}
pub struct MultiSelectGroupGenerator();
impl GroupGenerator for MultiSelectGroupGenerator {
pub struct MultiSelectGroupGenerator;
impl GroupsBuilder for MultiSelectGroupGenerator {
type Context = MultiSelectOptionGroupContext;
type TypeOptionType = MultiSelectTypeOption;
fn generate_groups(
fn build(
field: &Field,
_group_ctx: &Self::Context,
_context: &Self::Context,
type_option: &Option<Self::TypeOptionType>,
) -> GeneratedGroupContext {
) -> GeneratedGroups {
let group_configs = match type_option {
None => vec![],
Some(type_option) => generate_select_option_groups(&field.id, &type_option.options),
};
GeneratedGroupContext {
GeneratedGroups {
no_status_group: Some(make_no_status_group(field)),
group_configs,
}

View File

@ -4,13 +4,14 @@ use crate::services::field::{SelectOptionCellDataParser, SingleSelectTypeOption}
use crate::services::group::action::GroupCustomize;
use collab_database::fields::Field;
use collab_database::rows::{Cells, Row};
use std::sync::Arc;
use crate::services::group::controller::{
GenericGroupController, GroupController, GroupGenerator, MoveGroupRowContext,
BaseGroupController, GroupController, GroupsBuilder, MoveGroupRowContext,
};
use crate::services::group::controller_impls::select_option_controller::util::*;
use crate::services::group::entities::GroupData;
use crate::services::group::{make_no_status_group, GeneratedGroupContext, GroupContext};
use crate::services::group::{make_no_status_group, GeneratedGroups, GroupContext};
use serde::{Deserialize, Serialize};
@ -22,7 +23,7 @@ pub struct SingleSelectGroupConfiguration {
pub type SingleSelectOptionGroupContext = GroupContext<SingleSelectGroupConfiguration>;
// SingleSelect
pub type SingleSelectGroupController = GenericGroupController<
pub type SingleSelectGroupController = BaseGroupController<
SingleSelectGroupConfiguration,
SingleSelectTypeOption,
SingleSelectGroupGenerator,
@ -44,7 +45,7 @@ impl GroupCustomize for SingleSelectGroupController {
cell_data: &Self::CellData,
) -> Vec<GroupRowsNotificationPB> {
let mut changesets = vec![];
self.group_ctx.iter_mut_status_groups(|group| {
self.context.iter_mut_status_groups(|group| {
if let Some(changeset) = add_or_remove_select_option_row(group, cell_data, row) {
changesets.push(changeset);
}
@ -54,7 +55,7 @@ impl GroupCustomize for SingleSelectGroupController {
fn delete_row(&mut self, row: &Row, cell_data: &Self::CellData) -> Vec<GroupRowsNotificationPB> {
let mut changesets = vec![];
self.group_ctx.iter_mut_status_groups(|group| {
self.context.iter_mut_status_groups(|group| {
if let Some(changeset) = remove_select_option_row(group, cell_data, row) {
changesets.push(changeset);
}
@ -68,7 +69,7 @@ impl GroupCustomize for SingleSelectGroupController {
mut context: MoveGroupRowContext,
) -> Vec<GroupRowsNotificationPB> {
let mut group_changeset = vec![];
self.group_ctx.iter_mut_groups(|group| {
self.context.iter_mut_groups(|group| {
if let Some(changeset) = move_group_row(group, &mut context) {
group_changeset.push(changeset);
}
@ -78,8 +79,10 @@ impl GroupCustomize for SingleSelectGroupController {
}
impl GroupController for SingleSelectGroupController {
fn did_update_field_type_option(&mut self, _field: &Arc<Field>) {}
fn will_create_row(&mut self, cells: &mut Cells, field: &Field, group_id: &str) {
let group: Option<&mut GroupData> = self.group_ctx.get_mut_group(group_id);
let group: Option<&mut GroupData> = self.context.get_mut_group(group_id);
match group {
None => {},
Some(group) => {
@ -89,27 +92,27 @@ impl GroupController for SingleSelectGroupController {
}
}
fn did_create_row(&mut self, row: &Row, group_id: &str) {
if let Some(group) = self.group_ctx.get_mut_group(group_id) {
if let Some(group) = self.context.get_mut_group(group_id) {
group.add_row(row.clone())
}
}
}
pub struct SingleSelectGroupGenerator();
impl GroupGenerator for SingleSelectGroupGenerator {
impl GroupsBuilder for SingleSelectGroupGenerator {
type Context = SingleSelectOptionGroupContext;
type TypeOptionType = SingleSelectTypeOption;
fn generate_groups(
fn build(
field: &Field,
_group_ctx: &Self::Context,
_context: &Self::Context,
type_option: &Option<Self::TypeOptionType>,
) -> GeneratedGroupContext {
) -> GeneratedGroups {
let group_configs = match type_option {
None => vec![],
Some(type_option) => generate_select_option_groups(&field.id, &type_option.options),
};
GeneratedGroupContext {
GeneratedGroups {
no_status_group: Some(make_no_status_group(field)),
group_configs,
}

View File

@ -1,6 +1,7 @@
use collab_database::fields::Field;
use collab_database::rows::{new_cell_builder, Cell, Cells, Row};
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use flowy_error::FlowyResult;
@ -12,10 +13,10 @@ use crate::services::field::{URLCellData, URLCellDataParser, URLTypeOption};
use crate::services::group::action::GroupCustomize;
use crate::services::group::configuration::GroupContext;
use crate::services::group::controller::{
GenericGroupController, GroupController, GroupGenerator, MoveGroupRowContext,
BaseGroupController, GroupController, GroupsBuilder, MoveGroupRowContext,
};
use crate::services::group::{
make_no_status_group, move_group_row, GeneratedGroupConfig, GeneratedGroupContext, Group,
make_no_status_group, move_group_row, GeneratedGroupConfig, GeneratedGroups, Group,
};
#[derive(Default, Serialize, Deserialize)]
@ -23,12 +24,8 @@ pub struct URLGroupConfiguration {
pub hide_empty: bool,
}
pub type URLGroupController = GenericGroupController<
URLGroupConfiguration,
URLTypeOption,
URLGroupGenerator,
URLCellDataParser,
>;
pub type URLGroupController =
BaseGroupController<URLGroupConfiguration, URLTypeOption, URLGroupGenerator, URLCellDataParser>;
pub type URLGroupContext = GroupContext<URLGroupConfiguration>;
@ -55,17 +52,17 @@ impl GroupCustomize for URLGroupController {
) -> FlowyResult<(Option<InsertedGroupPB>, Option<GroupPB>)> {
// Just return if the group with this url already exists
let mut inserted_group = None;
if self.group_ctx.get_group(&_cell_data.url).is_none() {
if self.context.get_group(&_cell_data.url).is_none() {
let cell_data: URLCellData = _cell_data.clone().into();
let group = make_group_from_url_cell(&cell_data);
let mut new_group = self.group_ctx.add_new_group(group)?;
let mut new_group = self.context.add_new_group(group)?;
new_group.group.rows.push(RowPB::from(row));
inserted_group = Some(new_group);
}
// Delete the old url group if there are no rows in that group
let deleted_group = match _old_cell_data
.and_then(|old_cell_data| self.group_ctx.get_group(&old_cell_data.content))
.and_then(|old_cell_data| self.context.get_group(&old_cell_data.content))
{
None => None,
Some((_, group)) => {
@ -80,7 +77,7 @@ impl GroupCustomize for URLGroupController {
let deleted_group = match deleted_group {
None => None,
Some(group) => {
self.group_ctx.delete_group(&group.id)?;
self.context.delete_group(&group.id)?;
Some(GroupPB::from(group.clone()))
},
};
@ -94,7 +91,7 @@ impl GroupCustomize for URLGroupController {
cell_data: &Self::CellData,
) -> Vec<GroupRowsNotificationPB> {
let mut changesets = vec![];
self.group_ctx.iter_mut_status_groups(|group| {
self.context.iter_mut_status_groups(|group| {
let mut changeset = GroupRowsNotificationPB::new(group.id.clone());
if group.id == cell_data.content {
if !group.contains_row(&row.id) {
@ -117,7 +114,7 @@ impl GroupCustomize for URLGroupController {
fn delete_row(&mut self, row: &Row, _cell_data: &Self::CellData) -> Vec<GroupRowsNotificationPB> {
let mut changesets = vec![];
self.group_ctx.iter_mut_groups(|group| {
self.context.iter_mut_groups(|group| {
let mut changeset = GroupRowsNotificationPB::new(group.id.clone());
if group.contains_row(&row.id) {
group.remove_row(&row.id);
@ -137,7 +134,7 @@ impl GroupCustomize for URLGroupController {
mut context: MoveGroupRowContext,
) -> Vec<GroupRowsNotificationPB> {
let mut group_changeset = vec![];
self.group_ctx.iter_mut_groups(|group| {
self.context.iter_mut_groups(|group| {
if let Some(changeset) = move_group_row(group, &mut context) {
group_changeset.push(changeset);
}
@ -151,14 +148,14 @@ impl GroupCustomize for URLGroupController {
_cell_data: &Self::CellData,
) -> Option<GroupPB> {
let mut deleted_group = None;
if let Some((_, group)) = self.group_ctx.get_group(&_cell_data.content) {
if let Some((_, group)) = self.context.get_group(&_cell_data.content) {
if group.rows.len() == 1 {
deleted_group = Some(GroupPB::from(group.clone()));
}
}
if deleted_group.is_some() {
let _ = self
.group_ctx
.context
.delete_group(&deleted_group.as_ref().unwrap().group_id);
}
deleted_group
@ -166,8 +163,10 @@ impl GroupCustomize for URLGroupController {
}
impl GroupController for URLGroupController {
fn did_update_field_type_option(&mut self, _field: &Arc<Field>) {}
fn will_create_row(&mut self, cells: &mut Cells, field: &Field, group_id: &str) {
match self.group_ctx.get_group(group_id) {
match self.context.get_group(group_id) {
None => tracing::warn!("Can not find the group: {}", group_id),
Some((_, group)) => {
let cell = insert_url_cell(group.id.clone(), field);
@ -177,24 +176,24 @@ impl GroupController for URLGroupController {
}
fn did_create_row(&mut self, row: &Row, group_id: &str) {
if let Some(group) = self.group_ctx.get_mut_group(group_id) {
if let Some(group) = self.context.get_mut_group(group_id) {
group.add_row(row.clone())
}
}
}
pub struct URLGroupGenerator();
impl GroupGenerator for URLGroupGenerator {
impl GroupsBuilder for URLGroupGenerator {
type Context = URLGroupContext;
type TypeOptionType = URLTypeOption;
fn generate_groups(
fn build(
field: &Field,
group_ctx: &Self::Context,
context: &Self::Context,
_type_option: &Option<Self::TypeOptionType>,
) -> GeneratedGroupContext {
) -> GeneratedGroups {
// Read all the cells for the grouping field
let cells = futures::executor::block_on(group_ctx.get_all_cells());
let cells = futures::executor::block_on(context.get_all_cells());
// Generate the groups
let group_configs = cells
@ -208,7 +207,7 @@ impl GroupGenerator for URLGroupGenerator {
.collect();
let no_status_group = Some(make_no_status_group(field));
GeneratedGroupContext {
GeneratedGroups {
no_status_group,
group_configs,
}

View File

@ -14,6 +14,16 @@ pub struct GroupSetting {
pub content: String,
}
pub struct GroupSettingChangeset {
pub update_groups: Vec<GroupChangeset>,
}
pub struct GroupChangeset {
pub group_id: String,
pub name: Option<String>,
pub visible: Option<bool>,
}
impl GroupSetting {
pub fn new(field_id: String, field_type: i64, content: String) -> Self {
Self {
@ -75,7 +85,7 @@ impl From<GroupSetting> for GroupSettingMap {
pub struct Group {
pub id: String,
pub name: String,
#[serde(default = "GROUP_REV_VISIBILITY")]
#[serde(default = "GROUP_VISIBILITY")]
pub visible: bool,
}
@ -104,7 +114,7 @@ impl From<Group> for GroupMap {
}
}
const GROUP_REV_VISIBILITY: fn() -> bool = || true;
const GROUP_VISIBILITY: fn() -> bool = || true;
impl Group {
pub fn new(id: String, name: String) -> Self {

View File

@ -42,7 +42,7 @@ where
W: GroupSettingWriter,
{
let grouping_field_type = FieldType::from(grouping_field.field_type);
tracing::Span::current().record("grouping_field_type", &grouping_field_type.default_name());
tracing::Span::current().record("grouping_field", &grouping_field_type.default_name());
let mut group_controller: Box<dyn GroupController>;
let configuration_reader = Arc::new(setting_reader);

View File

@ -82,7 +82,9 @@ impl SortController {
pub async fn did_receive_row_changed(&self, row_id: RowId) {
let task_type = SortEvent::RowDidChanged(row_id);
self.gen_task(task_type, QualityOfService::Background).await;
if !self.sorts.is_empty() {
self.gen_task(task_type, QualityOfService::Background).await;
}
}
// #[tracing::instrument(name = "process_sort_task", level = "trace", skip_all, err)]
@ -169,7 +171,7 @@ impl SortController {
.await;
}
pub async fn did_update_view_field_type_option(&self, _field_rev: &Field) {
pub async fn did_update_field_type_option(&self, _field: &Field) {
//
}

View File

@ -10,7 +10,7 @@ use collab_database::rows::{Row, RowId};
use futures::TryFutureExt;
use tokio::sync::broadcast::Receiver;
use flowy_database2::entities::{AlterFilterParams, AlterFilterPayloadPB, CheckboxFilterConditionPB, CheckboxFilterPB, ChecklistFilterConditionPB, ChecklistFilterPB, DatabaseViewSettingPB, DateFilterConditionPB, DateFilterPB, DeleteFilterParams, FieldType, FilterPB, NumberFilterConditionPB, NumberFilterPB, SelectOptionConditionPB, SelectOptionFilterPB, TextFilterConditionPB, TextFilterPB};
use flowy_database2::entities::{UpdateFilterParams, UpdateFilterPayloadPB, CheckboxFilterConditionPB, CheckboxFilterPB, ChecklistFilterConditionPB, ChecklistFilterPB, DatabaseViewSettingPB, DateFilterConditionPB, DateFilterPB, DeleteFilterParams, FieldType, FilterPB, NumberFilterConditionPB, NumberFilterPB, SelectOptionConditionPB, SelectOptionFilterPB, TextFilterConditionPB, TextFilterPB};
use flowy_database2::services::database_view::DatabaseViewChanged;
use flowy_database2::services::filter::FilterType;
@ -33,7 +33,7 @@ pub enum FilterScript {
changed: Option<FilterRowChanged>,
},
InsertFilter {
payload: AlterFilterPayloadPB,
payload: UpdateFilterPayloadPB,
},
CreateTextFilter {
condition: TextFilterConditionPB,
@ -151,7 +151,7 @@ impl DatabaseFilterTest {
content
};
let payload =
AlterFilterPayloadPB::new(
UpdateFilterPayloadPB::new(
& self.view_id(),
&field, text_filter);
self.insert_filter(payload).await;
@ -159,7 +159,7 @@ impl DatabaseFilterTest {
FilterScript::UpdateTextFilter { filter, condition, content, changed} => {
self.recv = Some(self.editor.subscribe_view_changed(&self.view_id()).await.unwrap());
self.assert_future_changed(changed).await;
let params = AlterFilterParams {
let params = UpdateFilterParams {
view_id: self.view_id(),
field_id: filter.field_id,
filter_id: Some(filter.id),
@ -178,7 +178,7 @@ impl DatabaseFilterTest {
content
};
let payload =
AlterFilterPayloadPB::new(
UpdateFilterPayloadPB::new(
&self.view_id(),
&field, number_filter);
self.insert_filter(payload).await;
@ -191,7 +191,7 @@ impl DatabaseFilterTest {
condition
};
let payload =
AlterFilterPayloadPB::new(& self.view_id(), &field, checkbox_filter);
UpdateFilterPayloadPB::new(& self.view_id(), &field, checkbox_filter);
self.insert_filter(payload).await;
}
FilterScript::CreateDateFilter { condition, start, end, timestamp, changed} => {
@ -206,7 +206,7 @@ impl DatabaseFilterTest {
};
let payload =
AlterFilterPayloadPB::new(&self.view_id(), &field, date_filter);
UpdateFilterPayloadPB::new(&self.view_id(), &field, date_filter);
self.insert_filter(payload).await;
}
FilterScript::CreateMultiSelectFilter { condition, option_ids} => {
@ -214,7 +214,7 @@ impl DatabaseFilterTest {
let field = self.get_first_field(FieldType::MultiSelect);
let filter = SelectOptionFilterPB { condition, option_ids };
let payload =
AlterFilterPayloadPB::new(&self.view_id(), &field, filter);
UpdateFilterPayloadPB::new(&self.view_id(), &field, filter);
self.insert_filter(payload).await;
}
FilterScript::CreateSingleSelectFilter { condition, option_ids, changed} => {
@ -223,7 +223,7 @@ impl DatabaseFilterTest {
let field = self.get_first_field(FieldType::SingleSelect);
let filter = SelectOptionFilterPB { condition, option_ids };
let payload =
AlterFilterPayloadPB::new(& self.view_id(), &field, filter);
UpdateFilterPayloadPB::new(& self.view_id(), &field, filter);
self.insert_filter(payload).await;
}
FilterScript::CreateChecklistFilter { condition,changed} => {
@ -233,7 +233,7 @@ impl DatabaseFilterTest {
// let type_option = self.get_checklist_type_option(&field_rev.id);
let filter = ChecklistFilterPB { condition };
let payload =
AlterFilterPayloadPB::new(& self.view_id(), &field, filter);
UpdateFilterPayloadPB::new(& self.view_id(), &field, filter);
self.insert_filter(payload).await;
}
FilterScript::AssertFilterCount { count } => {
@ -289,8 +289,8 @@ impl DatabaseFilterTest {
}
async fn insert_filter(&self, payload: AlterFilterPayloadPB) {
let params: AlterFilterParams = payload.try_into().unwrap();
async fn insert_filter(&self, payload: UpdateFilterPayloadPB) {
let params: UpdateFilterParams = payload.try_into().unwrap();
let _ = self.editor.create_or_update_filter(params).await.unwrap();
}

View File

@ -1,7 +1,7 @@
use crate::database::filter_test::script::FilterScript::*;
use crate::database::filter_test::script::*;
use flowy_database2::entities::{
AlterFilterPayloadPB, FieldType, TextFilterConditionPB, TextFilterPB,
FieldType, TextFilterConditionPB, TextFilterPB, UpdateFilterPayloadPB,
};
use flowy_database2::services::filter::FilterType;
@ -195,7 +195,7 @@ async fn grid_filter_delete_test() {
condition: TextFilterConditionPB::TextIsEmpty,
content: "".to_string(),
};
let payload = AlterFilterPayloadPB::new(&test.view_id(), &field, text_filter);
let payload = UpdateFilterPayloadPB::new(&test.view_id(), &field, text_filter);
let scripts = vec![
InsertFilter { payload },
AssertFilterCount { count: 1 },

View File

@ -8,7 +8,7 @@ use collab_database::rows::RowId;
use futures::stream::StreamExt;
use tokio::sync::broadcast::Receiver;
use flowy_database2::entities::{AlterSortParams, DeleteSortParams, FieldType};
use flowy_database2::entities::{DeleteSortParams, FieldType, UpdateSortParams};
use flowy_database2::services::cell::stringify_cell_data;
use flowy_database2::services::database_view::DatabaseViewChanged;
use flowy_database2::services::sort::{Sort, SortCondition, SortType};
@ -72,7 +72,7 @@ impl DatabaseSortTest {
.await
.unwrap(),
);
let params = AlterSortParams {
let params = UpdateSortParams {
view_id: self.view_id.clone(),
field_id: field.id.clone(),
sort_id: None,

View File

@ -13,7 +13,7 @@ const MESSAGE: &str = "msg";
const LOG_MODULE_PATH: &str = "log.module_path";
const LOG_TARGET_PATH: &str = "log.target";
const FLOWY_RESERVED_FIELDS: [&str; 3] = [LEVEL, TIME, MESSAGE];
const RESERVED_FIELDS: [&str; 3] = [LEVEL, TIME, MESSAGE];
const IGNORE_FIELDS: [&str; 2] = [LOG_MODULE_PATH, LOG_TARGET_PATH];
pub struct FlowyFormattingLayer<W: MakeWriter + 'static> {
@ -29,7 +29,7 @@ impl<W: MakeWriter + 'static> FlowyFormattingLayer<W> {
}
}
fn serialize_flowy_folder_fields(
fn serialize_fields(
&self,
map_serializer: &mut impl SerializeMap<Error = serde_json::Error>,
message: &str,
@ -45,12 +45,13 @@ impl<W: MakeWriter + 'static> FlowyFormattingLayer<W> {
&self,
span: &SpanRef<S>,
ty: Type,
ctx: &Context<'_, S>,
) -> Result<Vec<u8>, std::io::Error> {
let mut buffer = Vec::new();
let mut serializer = serde_json::Serializer::new(&mut buffer);
let mut map_serializer = serializer.serialize_map(None)?;
let message = format_span_context(span, ty);
self.serialize_flowy_folder_fields(&mut map_serializer, &message, span.metadata().level())?;
let message = format_span_context(span, ty, ctx);
self.serialize_fields(&mut map_serializer, &message, span.metadata().level())?;
if self.with_target {
map_serializer.serialize_entry("target", &span.metadata().target())?;
}
@ -61,7 +62,7 @@ impl<W: MakeWriter + 'static> FlowyFormattingLayer<W> {
let extensions = span.extensions();
if let Some(visitor) = extensions.get::<JsonStorage>() {
for (key, value) in visitor.values() {
if !FLOWY_RESERVED_FIELDS.contains(key) && !IGNORE_FIELDS.contains(key) {
if !RESERVED_FIELDS.contains(key) && !IGNORE_FIELDS.contains(key) {
map_serializer.serialize_entry(key, value)?;
} else {
tracing::debug!(
@ -93,9 +94,9 @@ pub enum Type {
impl fmt::Display for Type {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let repr = match self {
Type::EnterSpan => "START",
Type::ExitSpan => "END",
Type::Event => "EVENT",
Type::EnterSpan => "Start",
Type::ExitSpan => "End",
Type::Event => "Event",
};
write!(f, "{}", repr)
}
@ -104,14 +105,27 @@ impl fmt::Display for Type {
fn format_span_context<S: Subscriber + for<'a> tracing_subscriber::registry::LookupSpan<'a>>(
span: &SpanRef<S>,
ty: Type,
context: &Context<'_, S>,
) -> String {
format!("[⛳ {} - {}]", span.metadata().name().to_uppercase(), ty)
match context.lookup_current() {
None => {
if matches!(ty, Type::EnterSpan) {
format!("[🟢 {} - {}]", span.metadata().name().to_uppercase(), ty)
} else {
format!("[🔵 {} - {}]", span.metadata().name().to_uppercase(), ty)
}
},
Some(_) => {
format!("[{} - {}]", span.metadata().name().to_uppercase(), ty)
},
}
}
fn format_event_message<S: Subscriber + for<'a> tracing_subscriber::registry::LookupSpan<'a>>(
current_span: &Option<SpanRef<S>>,
event: &Event,
event_visitor: &JsonStorage<'_>,
context: &Context<'_, S>,
) -> String {
// Extract the "message" field, if provided. Fallback to the target, if missing.
let mut message = event_visitor
@ -127,7 +141,11 @@ fn format_event_message<S: Subscriber + for<'a> tracing_subscriber::registry::Lo
// If the event is in the context of a span, prepend the span name to the
// message.
if let Some(span) = &current_span {
message = format!("{} {}", format_span_context(span, Type::Event), message);
message = format!(
"{} {}",
format_span_context(span, Type::Event, context),
message
);
}
message
@ -154,12 +172,8 @@ where
let mut serializer = serde_json::Serializer::new(&mut buffer);
let mut map_serializer = serializer.serialize_map(None)?;
let message = format_event_message(&current_span, event, &event_visitor);
self.serialize_flowy_folder_fields(
&mut map_serializer,
&message,
event.metadata().level(),
)?;
let message = format_event_message(&current_span, event, &event_visitor, &ctx);
self.serialize_fields(&mut map_serializer, &message, event.metadata().level())?;
// Additional metadata useful for debugging
// They should be nested under `src` (see https://github.com/trentm/node-bunyan#src )
// but `tracing` does not support nested values yet
@ -174,7 +188,7 @@ where
// Add all the other fields associated with the event, expect the message we
// already used.
for (key, value) in event_visitor.values().iter().filter(|(&key, _)| {
key != "message" && !FLOWY_RESERVED_FIELDS.contains(&key) && !IGNORE_FIELDS.contains(&key)
key != "message" && !RESERVED_FIELDS.contains(&key) && !IGNORE_FIELDS.contains(&key)
}) {
map_serializer.serialize_entry(key, value)?;
}
@ -184,7 +198,7 @@ where
let extensions = span.extensions();
if let Some(visitor) = extensions.get::<JsonStorage>() {
for (key, value) in visitor.values() {
if !FLOWY_RESERVED_FIELDS.contains(key) && !IGNORE_FIELDS.contains(key) {
if !RESERVED_FIELDS.contains(key) && !IGNORE_FIELDS.contains(key) {
map_serializer.serialize_entry(key, value)?;
} else {
tracing::debug!(
@ -207,14 +221,14 @@ where
fn new_span(&self, _attrs: &Attributes, id: &Id, ctx: Context<'_, S>) {
let span = ctx.span(id).expect("Span not found, this is a bug");
if let Ok(serialized) = self.serialize_span(&span, Type::EnterSpan) {
if let Ok(serialized) = self.serialize_span(&span, Type::EnterSpan, &ctx) {
let _ = self.emit(serialized);
}
}
fn on_close(&self, id: Id, ctx: Context<'_, S>) {
let span = ctx.span(&id).expect("Span not found, this is a bug");
if let Ok(serialized) = self.serialize_span(&span, Type::ExitSpan) {
if let Ok(serialized) = self.serialize_span(&span, Type::ExitSpan, &ctx) {
let _ = self.emit(serialized);
}
}

View File

@ -42,30 +42,20 @@ impl Builder {
let (non_blocking, guard) = tracing_appender::non_blocking(self.file_appender);
let subscriber = tracing_subscriber::fmt()
// .with_span_events(FmtSpan::NEW | FmtSpan::CLOSE)
.with_ansi(false)
.with_target(false)
.with_max_level(tracing::Level::TRACE)
.with_writer(std::io::stderr)
.with_thread_ids(true)
// .with_writer(non_blocking)
.json()
.with_current_span(true)
.with_span_list(true)
.compact()
.finish()
.with(env_filter)
.with(JsonStorageLayer)
.with(FlowyFormattingLayer::new(std::io::stdout))
.with(FlowyFormattingLayer::new(non_blocking));
// if cfg!(feature = "use_bunyan") {
// let formatting_layer = BunyanFormattingLayer::new(self.name.clone(),
// std::io::stdout); let _ =
// set_global_default(subscriber.with(JsonStorageLayer).with(formatting_layer)).
// map_err(|e| format!("{:?}", e))?; } else {
// let _ = set_global_default(subscriber).map_err(|e| format!("{:?}", e))?;
// }
.with_ansi(true)
.with_target(false)
.with_max_level(tracing::Level::TRACE)
.with_writer(std::io::stderr)
.with_thread_ids(true)
.json()
// .with_current_span(true)
// .with_span_list(true)
.compact()
.finish()
.with(env_filter)
.with(JsonStorageLayer)
.with(FlowyFormattingLayer::new(std::io::stdout))
.with(FlowyFormattingLayer::new(non_blocking));
set_global_default(subscriber).map_err(|e| format!("{:?}", e))?;
LogTracer::builder()