mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
refactor: group event (#2640)
* refactor: group event * fix: tauri build
This commit is contained in:
parent
75d40b79d0
commit
6bbdc7ceff
@ -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),
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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,
|
||||
);
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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>,
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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(¶ms.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(¶ms.view_id).await?;
|
||||
database_editor
|
||||
.set_group_by_field(¶ms.view_id, ¶ms.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>,
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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(¶ms.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(¶ms.view_id, group_setting);
|
||||
database.insert_group_setting(view_id, group_setting);
|
||||
}
|
||||
}
|
||||
|
||||
let view_editor = self.database_views.get_view_editor(¶ms.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(¶ms.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(¶ms.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(())
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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(¶ms.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()
|
||||
|
@ -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
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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))]
|
||||
|
@ -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)]
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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],
|
||||
}
|
||||
|
@ -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) {}
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
//
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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 },
|
||||
|
@ -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,
|
||||
|
@ -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) = ¤t_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(¤t_span, event, &event_visitor);
|
||||
self.serialize_flowy_folder_fields(
|
||||
&mut map_serializer,
|
||||
&message,
|
||||
event.metadata().level(),
|
||||
)?;
|
||||
let message = format_event_message(¤t_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);
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user