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 FieldType fieldType,
|
||||||
required List<int> data,
|
required List<int> data,
|
||||||
}) {
|
}) {
|
||||||
var insertFilterPayload = AlterFilterPayloadPB.create()
|
var insertFilterPayload = UpdateFilterPayloadPB.create()
|
||||||
..fieldId = fieldId
|
..fieldId = fieldId
|
||||||
..fieldType = fieldType
|
..fieldType = fieldType
|
||||||
..viewId = viewId
|
..viewId = viewId
|
||||||
@ -190,7 +190,7 @@ class FilterBackendService {
|
|||||||
|
|
||||||
final payload = DatabaseSettingChangesetPB.create()
|
final payload = DatabaseSettingChangesetPB.create()
|
||||||
..viewId = viewId
|
..viewId = viewId
|
||||||
..alterFilter = insertFilterPayload;
|
..updateFilter = insertFilterPayload;
|
||||||
return DatabaseEventUpdateDatabaseSetting(payload).send().then((result) {
|
return DatabaseEventUpdateDatabaseSetting(payload).send().then((result) {
|
||||||
return result.fold(
|
return result.fold(
|
||||||
(l) => left(l),
|
(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.pb.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-database2/group_changeset.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>;
|
typedef GroupByNewFieldValue = Either<List<GroupPB>, FlowyError>;
|
||||||
|
|
||||||
class DatabaseGroupListener {
|
class DatabaseGroupListener {
|
||||||
@ -36,17 +36,17 @@ class DatabaseGroupListener {
|
|||||||
Either<Uint8List, FlowyError> result,
|
Either<Uint8List, FlowyError> result,
|
||||||
) {
|
) {
|
||||||
switch (ty) {
|
switch (ty) {
|
||||||
case DatabaseNotification.DidUpdateGroups:
|
case DatabaseNotification.DidUpdateNumOfGroups:
|
||||||
result.fold(
|
result.fold(
|
||||||
(payload) => _numOfGroupsNotifier?.value =
|
(payload) => _numOfGroupsNotifier?.value =
|
||||||
left(GroupChangesetPB.fromBuffer(payload)),
|
left(GroupChangesPB.fromBuffer(payload)),
|
||||||
(error) => _numOfGroupsNotifier?.value = right(error),
|
(error) => _numOfGroupsNotifier?.value = right(error),
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case DatabaseNotification.DidGroupByField:
|
case DatabaseNotification.DidGroupByField:
|
||||||
result.fold(
|
result.fold(
|
||||||
(payload) => _groupByFieldNotifier?.value =
|
(payload) => _groupByFieldNotifier?.value =
|
||||||
left(GroupChangesetPB.fromBuffer(payload).initialGroups),
|
left(GroupChangesPB.fromBuffer(payload).initialGroups),
|
||||||
(error) => _groupByFieldNotifier?.value = right(error),
|
(error) => _groupByFieldNotifier?.value = right(error),
|
||||||
);
|
);
|
||||||
break;
|
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/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/log.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pb.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
import '../group/group_service.dart';
|
||||||
|
|
||||||
part 'group_bloc.freezed.dart';
|
part 'group_bloc.freezed.dart';
|
||||||
|
|
||||||
class DatabaseGroupBloc extends Bloc<DatabaseGroupEvent, DatabaseGroupState> {
|
class DatabaseGroupBloc extends Bloc<DatabaseGroupEvent, DatabaseGroupState> {
|
||||||
final FieldController _fieldController;
|
final FieldController _fieldController;
|
||||||
final SettingBackendService _settingBackendSvc;
|
final GroupBackendService _groupBackendSvc;
|
||||||
Function(List<FieldInfo>)? _onFieldsFn;
|
Function(List<FieldInfo>)? _onFieldsFn;
|
||||||
|
|
||||||
DatabaseGroupBloc({
|
DatabaseGroupBloc({
|
||||||
required String viewId,
|
required String viewId,
|
||||||
required FieldController fieldController,
|
required FieldController fieldController,
|
||||||
}) : _fieldController = fieldController,
|
}) : _fieldController = fieldController,
|
||||||
_settingBackendSvc = SettingBackendService(viewId: viewId),
|
_groupBackendSvc = GroupBackendService(viewId),
|
||||||
super(DatabaseGroupState.initial(viewId, fieldController.fieldInfos)) {
|
super(DatabaseGroupState.initial(viewId, fieldController.fieldInfos)) {
|
||||||
on<DatabaseGroupEvent>(
|
on<DatabaseGroupEvent>(
|
||||||
(event, emit) async {
|
(event, emit) async {
|
||||||
@ -29,7 +30,7 @@ class DatabaseGroupBloc extends Bloc<DatabaseGroupEvent, DatabaseGroupState> {
|
|||||||
emit(state.copyWith(fieldContexts: fieldContexts));
|
emit(state.copyWith(fieldContexts: fieldContexts));
|
||||||
},
|
},
|
||||||
setGroupByField: (String fieldId, FieldType fieldType) async {
|
setGroupByField: (String fieldId, FieldType fieldType) async {
|
||||||
final result = await _settingBackendSvc.groupByField(
|
final result = await _groupBackendSvc.groupByField(
|
||||||
fieldId: fieldId,
|
fieldId: fieldId,
|
||||||
fieldType: fieldType,
|
fieldType: fieldType,
|
||||||
);
|
);
|
||||||
|
@ -2,8 +2,6 @@ import 'package:appflowy_backend/protobuf/flowy-database2/database_entities.pb.d
|
|||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.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';
|
import 'package:appflowy_backend/protobuf/flowy-database2/setting_entities.pb.dart';
|
||||||
|
|
||||||
class SettingBackendService {
|
class SettingBackendService {
|
||||||
@ -15,19 +13,4 @@ class SettingBackendService {
|
|||||||
final payload = DatabaseViewIdPB.create()..value = viewId;
|
final payload = DatabaseViewIdPB.create()..value = viewId;
|
||||||
return DatabaseEventGetDatabaseSetting(payload).send();
|
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 FieldType fieldType,
|
||||||
required SortConditionPB condition,
|
required SortConditionPB condition,
|
||||||
}) {
|
}) {
|
||||||
var insertSortPayload = AlterSortPayloadPB.create()
|
var insertSortPayload = UpdateSortPayloadPB.create()
|
||||||
..fieldId = fieldId
|
..fieldId = fieldId
|
||||||
..fieldType = fieldType
|
..fieldType = fieldType
|
||||||
..viewId = viewId
|
..viewId = viewId
|
||||||
@ -38,7 +38,7 @@ class SortBackendService {
|
|||||||
|
|
||||||
final payload = DatabaseSettingChangesetPB.create()
|
final payload = DatabaseSettingChangesetPB.create()
|
||||||
..viewId = viewId
|
..viewId = viewId
|
||||||
..alterSort = insertSortPayload;
|
..updateSort = insertSortPayload;
|
||||||
return DatabaseEventUpdateDatabaseSetting(payload).send().then((result) {
|
return DatabaseEventUpdateDatabaseSetting(payload).send().then((result) {
|
||||||
return result.fold(
|
return result.fold(
|
||||||
(l) => left(l),
|
(l) => left(l),
|
||||||
@ -55,7 +55,7 @@ class SortBackendService {
|
|||||||
required FieldType fieldType,
|
required FieldType fieldType,
|
||||||
required SortConditionPB condition,
|
required SortConditionPB condition,
|
||||||
}) {
|
}) {
|
||||||
var insertSortPayload = AlterSortPayloadPB.create()
|
var insertSortPayload = UpdateSortPayloadPB.create()
|
||||||
..fieldId = fieldId
|
..fieldId = fieldId
|
||||||
..fieldType = fieldType
|
..fieldType = fieldType
|
||||||
..viewId = viewId
|
..viewId = viewId
|
||||||
@ -63,7 +63,7 @@ class SortBackendService {
|
|||||||
|
|
||||||
final payload = DatabaseSettingChangesetPB.create()
|
final payload = DatabaseSettingChangesetPB.create()
|
||||||
..viewId = viewId
|
..viewId = viewId
|
||||||
..alterSort = insertSortPayload;
|
..updateSort = insertSortPayload;
|
||||||
return DatabaseEventUpdateDatabaseSetting(payload).send().then((result) {
|
return DatabaseEventUpdateDatabaseSetting(payload).send().then((result) {
|
||||||
return result.fold(
|
return result.fold(
|
||||||
(l) => left(l),
|
(l) => left(l),
|
||||||
|
@ -1,18 +1,17 @@
|
|||||||
import { ChangeNotifier } from "$app/utils/change_notifier";
|
import { ChangeNotifier } from '$app/utils/change_notifier';
|
||||||
import { Ok, Result } from "ts-results";
|
import { Ok, Result } from 'ts-results';
|
||||||
import { DatabaseNotification, FlowyError, GroupChangesetPB, GroupPB } from "@/services/backend";
|
import { DatabaseNotification, FlowyError, GroupChangesPB, GroupPB } from '@/services/backend';
|
||||||
import { DatabaseNotificationObserver } from "../notifications/observer";
|
import { DatabaseNotificationObserver } from '../notifications/observer';
|
||||||
|
|
||||||
export type GroupByFieldCallback = (value: Result<GroupPB[], FlowyError>) => void;
|
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 {
|
export class DatabaseGroupObserver {
|
||||||
private groupByNotifier?: ChangeNotifier<Result<GroupPB[], FlowyError>>;
|
private groupByNotifier?: ChangeNotifier<Result<GroupPB[], FlowyError>>;
|
||||||
private groupChangesetNotifier?: ChangeNotifier<Result<GroupChangesetPB, FlowyError>>;
|
private groupChangesetNotifier?: ChangeNotifier<Result<GroupChangesPB, FlowyError>>;
|
||||||
private listener?: DatabaseNotificationObserver;
|
private listener?: DatabaseNotificationObserver;
|
||||||
|
|
||||||
constructor(public readonly viewId: string) {
|
constructor(public readonly viewId: string) {}
|
||||||
}
|
|
||||||
|
|
||||||
subscribe = async (callbacks: {
|
subscribe = async (callbacks: {
|
||||||
onGroupBy: GroupByFieldCallback;
|
onGroupBy: GroupByFieldCallback;
|
||||||
@ -30,14 +29,14 @@ export class DatabaseGroupObserver {
|
|||||||
switch (notification) {
|
switch (notification) {
|
||||||
case DatabaseNotification.DidGroupByField:
|
case DatabaseNotification.DidGroupByField:
|
||||||
if (result.ok) {
|
if (result.ok) {
|
||||||
this.groupByNotifier?.notify(Ok(GroupChangesetPB.deserializeBinary(result.val).initial_groups));
|
this.groupByNotifier?.notify(Ok(GroupChangesPB.deserializeBinary(result.val).initial_groups));
|
||||||
} else {
|
} else {
|
||||||
this.groupByNotifier?.notify(result);
|
this.groupByNotifier?.notify(result);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DatabaseNotification.DidUpdateGroups:
|
case DatabaseNotification.DidUpdateNumOfGroups:
|
||||||
if (result.ok) {
|
if (result.ok) {
|
||||||
this.groupChangesetNotifier?.notify(Ok(GroupChangesetPB.deserializeBinary(result.val)));
|
this.groupChangesetNotifier?.notify(Ok(GroupChangesPB.deserializeBinary(result.val)));
|
||||||
} else {
|
} else {
|
||||||
this.groupChangesetNotifier?.notify(result);
|
this.groupChangesetNotifier?.notify(result);
|
||||||
}
|
}
|
||||||
@ -45,7 +44,7 @@ export class DatabaseGroupObserver {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.listener.start();
|
await this.listener.start();
|
||||||
|
@ -125,7 +125,7 @@ pub struct DeleteFilterParams {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(ProtoBuf, Debug, Default, Clone)]
|
#[derive(ProtoBuf, Debug, Default, Clone)]
|
||||||
pub struct AlterFilterPayloadPB {
|
pub struct UpdateFilterPayloadPB {
|
||||||
#[pb(index = 1)]
|
#[pb(index = 1)]
|
||||||
pub field_id: String,
|
pub field_id: String,
|
||||||
|
|
||||||
@ -143,7 +143,7 @@ pub struct AlterFilterPayloadPB {
|
|||||||
pub view_id: String,
|
pub view_id: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AlterFilterPayloadPB {
|
impl UpdateFilterPayloadPB {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn new<T: TryInto<Bytes, Error = ::protobuf::ProtobufError>>(
|
pub fn new<T: TryInto<Bytes, Error = ::protobuf::ProtobufError>>(
|
||||||
view_id: &str,
|
view_id: &str,
|
||||||
@ -162,10 +162,10 @@ impl AlterFilterPayloadPB {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryInto<AlterFilterParams> for AlterFilterPayloadPB {
|
impl TryInto<UpdateFilterParams> for UpdateFilterPayloadPB {
|
||||||
type Error = ErrorCode;
|
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)
|
let view_id = NotEmptyStr::parse(self.view_id)
|
||||||
.map_err(|_| ErrorCode::DatabaseViewIdIsEmpty)?
|
.map_err(|_| ErrorCode::DatabaseViewIdIsEmpty)?
|
||||||
.0;
|
.0;
|
||||||
@ -217,7 +217,7 @@ impl TryInto<AlterFilterParams> for AlterFilterPayloadPB {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(AlterFilterParams {
|
Ok(UpdateFilterParams {
|
||||||
view_id,
|
view_id,
|
||||||
field_id,
|
field_id,
|
||||||
filter_id,
|
filter_id,
|
||||||
@ -229,7 +229,7 @@ impl TryInto<AlterFilterParams> for AlterFilterPayloadPB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct AlterFilterParams {
|
pub struct UpdateFilterParams {
|
||||||
pub view_id: String,
|
pub view_id: String,
|
||||||
pub field_id: String,
|
pub field_id: String,
|
||||||
/// Create a new filter if the filter_id is None
|
/// 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::parser::NotEmptyStr;
|
||||||
use crate::entities::{FieldType, RowPB};
|
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)]
|
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
|
||||||
pub struct GroupSettingPB {
|
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)]
|
#[derive(ProtoBuf, Debug, Default, Clone)]
|
||||||
pub struct RepeatedGroupPB {
|
pub struct RepeatedGroupPB {
|
||||||
#[pb(index = 1)]
|
#[pb(index = 1)]
|
||||||
@ -79,107 +102,97 @@ impl std::convert::From<GroupData> for GroupPB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
|
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
|
||||||
pub struct RepeatedGroupSettingPB {
|
pub struct GroupByFieldPayloadPB {
|
||||||
#[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 {
|
|
||||||
#[pb(index = 1)]
|
#[pb(index = 1)]
|
||||||
pub field_id: String,
|
pub field_id: String,
|
||||||
|
|
||||||
#[pb(index = 2)]
|
#[pb(index = 2)]
|
||||||
pub field_type: FieldType,
|
|
||||||
|
|
||||||
#[pb(index = 3)]
|
|
||||||
pub view_id: String,
|
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)]
|
#[pb(index = 3)]
|
||||||
pub field_type: FieldType,
|
pub field_type: FieldType,
|
||||||
|
|
||||||
#[pb(index = 4)]
|
|
||||||
pub view_id: String,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryInto<DeleteGroupParams> for DeleteGroupPayloadPB {
|
impl TryInto<GroupByFieldParams> for GroupByFieldPayloadPB {
|
||||||
type Error = ErrorCode;
|
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)
|
let field_id = NotEmptyStr::parse(self.field_id)
|
||||||
.map_err(|_| ErrorCode::FieldIdIsEmpty)?
|
.map_err(|_| ErrorCode::FieldIdIsEmpty)?
|
||||||
.0;
|
.0;
|
||||||
let group_id = NotEmptyStr::parse(self.group_id)
|
|
||||||
.map_err(|_| ErrorCode::FieldIdIsEmpty)?
|
|
||||||
.0;
|
|
||||||
let view_id = NotEmptyStr::parse(self.view_id)
|
let view_id = NotEmptyStr::parse(self.view_id)
|
||||||
.map_err(|_| ErrorCode::ViewIdIsInvalid)?
|
.map_err(|_| ErrorCode::ViewIdIsInvalid)?
|
||||||
.0;
|
.0;
|
||||||
|
|
||||||
Ok(DeleteGroupParams {
|
Ok(GroupByFieldParams {
|
||||||
field_id,
|
field_id,
|
||||||
field_type: self.field_type,
|
|
||||||
group_id,
|
|
||||||
view_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 struct DeleteGroupParams {
|
||||||
pub view_id: String,
|
pub view_id: String,
|
||||||
pub field_id: String,
|
pub field_id: String,
|
||||||
pub group_id: String,
|
pub group_id: String,
|
||||||
pub field_type: FieldType,
|
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)]
|
#[derive(Debug, Default, ProtoBuf)]
|
||||||
pub struct GroupChangesetPB {
|
pub struct GroupChangesPB {
|
||||||
#[pb(index = 1)]
|
#[pb(index = 1)]
|
||||||
pub view_id: String,
|
pub view_id: String,
|
||||||
|
|
||||||
@ -146,7 +146,7 @@ pub struct GroupChangesetPB {
|
|||||||
pub update_groups: Vec<GroupPB>,
|
pub update_groups: Vec<GroupPB>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GroupChangesetPB {
|
impl GroupChangesPB {
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
self.initial_groups.is_empty()
|
self.initial_groups.is_empty()
|
||||||
&& self.inserted_groups.is_empty()
|
&& self.inserted_groups.is_empty()
|
||||||
|
@ -8,10 +8,9 @@ use flowy_error::ErrorCode;
|
|||||||
|
|
||||||
use crate::entities::parser::NotEmptyStr;
|
use crate::entities::parser::NotEmptyStr;
|
||||||
use crate::entities::{
|
use crate::entities::{
|
||||||
AlterFilterParams, AlterFilterPayloadPB, AlterSortParams, AlterSortPayloadPB,
|
CalendarLayoutSettingPB, DeleteFilterParams, DeleteFilterPayloadPB, DeleteSortParams,
|
||||||
CalendarLayoutSettingPB, DeleteFilterParams, DeleteFilterPayloadPB, DeleteGroupParams,
|
DeleteSortPayloadPB, RepeatedFilterPB, RepeatedGroupSettingPB, RepeatedSortPB,
|
||||||
DeleteGroupPayloadPB, DeleteSortParams, DeleteSortPayloadPB, InsertGroupParams,
|
UpdateFilterParams, UpdateFilterPayloadPB, UpdateGroupPB, UpdateSortParams, UpdateSortPayloadPB,
|
||||||
InsertGroupPayloadPB, RepeatedFilterPB, RepeatedGroupSettingPB, RepeatedSortPB,
|
|
||||||
};
|
};
|
||||||
use crate::services::setting::CalendarLayoutSetting;
|
use crate::services::setting::CalendarLayoutSetting;
|
||||||
|
|
||||||
@ -77,21 +76,18 @@ pub struct DatabaseSettingChangesetPB {
|
|||||||
pub layout_type: DatabaseLayoutPB,
|
pub layout_type: DatabaseLayoutPB,
|
||||||
|
|
||||||
#[pb(index = 3, one_of)]
|
#[pb(index = 3, one_of)]
|
||||||
pub alter_filter: Option<AlterFilterPayloadPB>,
|
pub update_filter: Option<UpdateFilterPayloadPB>,
|
||||||
|
|
||||||
#[pb(index = 4, one_of)]
|
#[pb(index = 4, one_of)]
|
||||||
pub delete_filter: Option<DeleteFilterPayloadPB>,
|
pub delete_filter: Option<DeleteFilterPayloadPB>,
|
||||||
|
|
||||||
#[pb(index = 5, one_of)]
|
#[pb(index = 5, one_of)]
|
||||||
pub insert_group: Option<InsertGroupPayloadPB>,
|
pub update_group: Option<UpdateGroupPB>,
|
||||||
|
|
||||||
#[pb(index = 6, one_of)]
|
#[pb(index = 6, one_of)]
|
||||||
pub delete_group: Option<DeleteGroupPayloadPB>,
|
pub update_sort: Option<UpdateSortPayloadPB>,
|
||||||
|
|
||||||
#[pb(index = 7, one_of)]
|
#[pb(index = 7, one_of)]
|
||||||
pub alter_sort: Option<AlterSortPayloadPB>,
|
|
||||||
|
|
||||||
#[pb(index = 8, one_of)]
|
|
||||||
pub delete_sort: Option<DeleteSortPayloadPB>,
|
pub delete_sort: Option<DeleteSortPayloadPB>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,7 +99,7 @@ impl TryInto<DatabaseSettingChangesetParams> for DatabaseSettingChangesetPB {
|
|||||||
.map_err(|_| ErrorCode::ViewIdIsInvalid)?
|
.map_err(|_| ErrorCode::ViewIdIsInvalid)?
|
||||||
.0;
|
.0;
|
||||||
|
|
||||||
let insert_filter = match self.alter_filter {
|
let insert_filter = match self.update_filter {
|
||||||
None => None,
|
None => None,
|
||||||
Some(payload) => Some(payload.try_into()?),
|
Some(payload) => Some(payload.try_into()?),
|
||||||
};
|
};
|
||||||
@ -113,17 +109,7 @@ impl TryInto<DatabaseSettingChangesetParams> for DatabaseSettingChangesetPB {
|
|||||||
Some(payload) => Some(payload.try_into()?),
|
Some(payload) => Some(payload.try_into()?),
|
||||||
};
|
};
|
||||||
|
|
||||||
let insert_group = match self.insert_group {
|
let alert_sort = match self.update_sort {
|
||||||
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 {
|
|
||||||
None => None,
|
None => None,
|
||||||
Some(payload) => Some(payload.try_into()?),
|
Some(payload) => Some(payload.try_into()?),
|
||||||
};
|
};
|
||||||
@ -138,8 +124,6 @@ impl TryInto<DatabaseSettingChangesetParams> for DatabaseSettingChangesetPB {
|
|||||||
layout_type: self.layout_type.into(),
|
layout_type: self.layout_type.into(),
|
||||||
insert_filter,
|
insert_filter,
|
||||||
delete_filter,
|
delete_filter,
|
||||||
insert_group,
|
|
||||||
delete_group,
|
|
||||||
alert_sort,
|
alert_sort,
|
||||||
delete_sort,
|
delete_sort,
|
||||||
})
|
})
|
||||||
@ -149,11 +133,9 @@ impl TryInto<DatabaseSettingChangesetParams> for DatabaseSettingChangesetPB {
|
|||||||
pub struct DatabaseSettingChangesetParams {
|
pub struct DatabaseSettingChangesetParams {
|
||||||
pub view_id: String,
|
pub view_id: String,
|
||||||
pub layout_type: DatabaseLayout,
|
pub layout_type: DatabaseLayout,
|
||||||
pub insert_filter: Option<AlterFilterParams>,
|
pub insert_filter: Option<UpdateFilterParams>,
|
||||||
pub delete_filter: Option<DeleteFilterParams>,
|
pub delete_filter: Option<DeleteFilterParams>,
|
||||||
pub insert_group: Option<InsertGroupParams>,
|
pub alert_sort: Option<UpdateSortParams>,
|
||||||
pub delete_group: Option<DeleteGroupParams>,
|
|
||||||
pub alert_sort: Option<AlterSortParams>,
|
|
||||||
pub delete_sort: Option<DeleteSortParams>,
|
pub delete_sort: Option<DeleteSortParams>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ impl std::convert::From<SortConditionPB> for SortCondition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(ProtoBuf, Debug, Default, Clone)]
|
#[derive(ProtoBuf, Debug, Default, Clone)]
|
||||||
pub struct AlterSortPayloadPB {
|
pub struct UpdateSortPayloadPB {
|
||||||
#[pb(index = 1)]
|
#[pb(index = 1)]
|
||||||
pub view_id: String,
|
pub view_id: String,
|
||||||
|
|
||||||
@ -110,10 +110,10 @@ pub struct AlterSortPayloadPB {
|
|||||||
pub condition: SortConditionPB,
|
pub condition: SortConditionPB,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryInto<AlterSortParams> for AlterSortPayloadPB {
|
impl TryInto<UpdateSortParams> for UpdateSortPayloadPB {
|
||||||
type Error = ErrorCode;
|
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)
|
let view_id = NotEmptyStr::parse(self.view_id)
|
||||||
.map_err(|_| ErrorCode::DatabaseViewIdIsEmpty)?
|
.map_err(|_| ErrorCode::DatabaseViewIdIsEmpty)?
|
||||||
.0;
|
.0;
|
||||||
@ -131,7 +131,7 @@ impl TryInto<AlterSortParams> for AlterSortPayloadPB {
|
|||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(AlterSortParams {
|
Ok(UpdateSortParams {
|
||||||
view_id,
|
view_id,
|
||||||
field_id,
|
field_id,
|
||||||
sort_id,
|
sort_id,
|
||||||
@ -142,7 +142,7 @@ impl TryInto<AlterSortParams> for AlterSortPayloadPB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct AlterSortParams {
|
pub struct UpdateSortParams {
|
||||||
pub view_id: String,
|
pub view_id: String,
|
||||||
pub field_id: String,
|
pub field_id: String,
|
||||||
/// Create a new sort if the sort is None
|
/// Create a new sort if the sort is None
|
||||||
|
@ -15,9 +15,10 @@ use crate::services::cell::CellBuilder;
|
|||||||
use crate::services::field::{
|
use crate::services::field::{
|
||||||
type_option_data_from_pb_or_default, DateCellChangeset, SelectOptionCellChangeset,
|
type_option_data_from_pb_or_default, DateCellChangeset, SelectOptionCellChangeset,
|
||||||
};
|
};
|
||||||
|
use crate::services::group::{GroupChangeset, GroupSettingChangeset};
|
||||||
use crate::services::share::csv::CSVFormat;
|
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(
|
pub(crate) async fn get_database_data_handler(
|
||||||
data: AFPluginData<DatabaseViewIdPB>,
|
data: AFPluginData<DatabaseViewIdPB>,
|
||||||
manager: AFPluginState<Arc<DatabaseManager2>>,
|
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 params: DatabaseSettingChangesetParams = data.into_inner().try_into()?;
|
||||||
let editor = manager.get_database_with_view_id(¶ms.view_id).await?;
|
let editor = manager.get_database_with_view_id(¶ms.view_id).await?;
|
||||||
|
|
||||||
if let Some(insert_params) = params.insert_group {
|
if let Some(update_filter) = params.insert_filter {
|
||||||
editor.insert_group(insert_params).await?;
|
editor.create_or_update_filter(update_filter).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(delete_filter) = params.delete_filter {
|
if let Some(delete_filter) = params.delete_filter {
|
||||||
editor.delete_filter(delete_filter).await?;
|
editor.delete_filter(delete_filter).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(alter_sort) = params.alert_sort {
|
if let Some(update_sort) = params.alert_sort {
|
||||||
let _ = editor.create_or_update_sort(alter_sort).await?;
|
let _ = editor.create_or_update_sort(update_sort).await?;
|
||||||
}
|
}
|
||||||
if let Some(delete_sort) = params.delete_sort {
|
if let Some(delete_sort) = params.delete_sort {
|
||||||
editor.delete_sort(delete_sort).await?;
|
editor.delete_sort(delete_sort).await?;
|
||||||
@ -525,6 +518,36 @@ pub(crate) async fn get_group_handler(
|
|||||||
data_result_ok(group)
|
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)]
|
#[tracing::instrument(level = "debug", skip(data, manager), err)]
|
||||||
pub(crate) async fn move_group_handler(
|
pub(crate) async fn move_group_handler(
|
||||||
data: AFPluginData<MoveGroupPayloadPB>,
|
data: AFPluginData<MoveGroupPayloadPB>,
|
||||||
|
@ -51,6 +51,8 @@ pub fn init(database_manager: Arc<DatabaseManager2>) -> AFPlugin {
|
|||||||
.event(DatabaseEvent::MoveGroupRow, move_group_row_handler)
|
.event(DatabaseEvent::MoveGroupRow, move_group_row_handler)
|
||||||
.event(DatabaseEvent::GetGroups, get_groups_handler)
|
.event(DatabaseEvent::GetGroups, get_groups_handler)
|
||||||
.event(DatabaseEvent::GetGroup, get_group_handler)
|
.event(DatabaseEvent::GetGroup, get_group_handler)
|
||||||
|
.event(DatabaseEvent::SetGroupByField, set_group_by_field_handler)
|
||||||
|
.event(DatabaseEvent::UpdateGroup, update_group_handler)
|
||||||
// Database
|
// Database
|
||||||
.event(DatabaseEvent::GetDatabases, get_databases_handler)
|
.event(DatabaseEvent::GetDatabases, get_databases_handler)
|
||||||
// Calendar
|
// Calendar
|
||||||
@ -243,25 +245,31 @@ pub enum DatabaseEvent {
|
|||||||
#[event(input = "MoveGroupRowPayloadPB")]
|
#[event(input = "MoveGroupRowPayloadPB")]
|
||||||
MoveGroupRow = 112,
|
MoveGroupRow = 112,
|
||||||
|
|
||||||
|
#[event(input = "GroupByFieldPayloadPB")]
|
||||||
|
SetGroupByField = 113,
|
||||||
|
|
||||||
|
#[event(input = "UpdateGroupPB")]
|
||||||
|
UpdateGroup = 114,
|
||||||
|
|
||||||
/// Returns all the databases
|
/// Returns all the databases
|
||||||
#[event(output = "RepeatedDatabaseDescriptionPB")]
|
#[event(output = "RepeatedDatabaseDescriptionPB")]
|
||||||
GetDatabases = 114,
|
GetDatabases = 120,
|
||||||
|
|
||||||
#[event(input = "LayoutSettingChangesetPB")]
|
#[event(input = "LayoutSettingChangesetPB")]
|
||||||
SetLayoutSetting = 115,
|
SetLayoutSetting = 121,
|
||||||
|
|
||||||
#[event(input = "DatabaseLayoutIdPB", output = "LayoutSettingPB")]
|
#[event(input = "DatabaseLayoutIdPB", output = "LayoutSettingPB")]
|
||||||
GetLayoutSetting = 116,
|
GetLayoutSetting = 122,
|
||||||
|
|
||||||
#[event(input = "CalendarEventRequestPB", output = "RepeatedCalendarEventPB")]
|
#[event(input = "CalendarEventRequestPB", output = "RepeatedCalendarEventPB")]
|
||||||
GetAllCalendarEvents = 117,
|
GetAllCalendarEvents = 123,
|
||||||
|
|
||||||
#[event(input = "RowIdPB", output = "CalendarEventPB")]
|
#[event(input = "RowIdPB", output = "CalendarEventPB")]
|
||||||
GetCalendarEvent = 118,
|
GetCalendarEvent = 124,
|
||||||
|
|
||||||
#[event(input = "MoveCalendarEventPB")]
|
#[event(input = "MoveCalendarEventPB")]
|
||||||
MoveCalendarEvent = 119,
|
MoveCalendarEvent = 125,
|
||||||
|
|
||||||
#[event(input = "DatabaseImportPB")]
|
#[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
|
/// Trigger after editing a field properties including rename,update type option, etc
|
||||||
DidUpdateField = 50,
|
DidUpdateField = 50,
|
||||||
/// Trigger after the number of groups is changed
|
/// Trigger after the number of groups is changed
|
||||||
DidUpdateGroups = 60,
|
DidUpdateNumOfGroups = 60,
|
||||||
/// Trigger after inserting/deleting/updating/moving a row
|
/// Trigger after inserting/deleting/updating/moving a row
|
||||||
DidUpdateGroupRow = 61,
|
DidUpdateGroupRow = 61,
|
||||||
/// Trigger when setting a new grouping field
|
/// Trigger when setting a new grouping field
|
||||||
|
@ -15,11 +15,11 @@ use flowy_task::TaskDispatcher;
|
|||||||
use lib_infra::future::{to_fut, Fut};
|
use lib_infra::future::{to_fut, Fut};
|
||||||
|
|
||||||
use crate::entities::{
|
use crate::entities::{
|
||||||
AlterFilterParams, AlterSortParams, CalendarEventPB, CellChangesetNotifyPB, CellPB,
|
CalendarEventPB, CellChangesetNotifyPB, CellPB, DatabaseFieldChangesetPB, DatabasePB,
|
||||||
DatabaseFieldChangesetPB, DatabasePB, DatabaseViewSettingPB, DeleteFilterParams,
|
DatabaseViewSettingPB, DeleteFilterParams, DeleteGroupParams, DeleteSortParams,
|
||||||
DeleteGroupParams, DeleteSortParams, FieldChangesetParams, FieldIdPB, FieldPB, FieldType,
|
FieldChangesetParams, FieldIdPB, FieldPB, FieldType, GroupPB, IndexFieldPB, InsertedRowPB,
|
||||||
GroupPB, IndexFieldPB, InsertGroupParams, InsertedRowPB, LayoutSettingParams, RepeatedFilterPB,
|
LayoutSettingParams, RepeatedFilterPB, RepeatedGroupPB, RepeatedSortPB, RowPB, RowsChangePB,
|
||||||
RepeatedGroupPB, RepeatedSortPB, RowPB, RowsChangePB, SelectOptionCellDataPB, SelectOptionPB,
|
SelectOptionCellDataPB, SelectOptionPB, UpdateFilterParams, UpdateSortParams,
|
||||||
};
|
};
|
||||||
use crate::notification::{send_notification, DatabaseNotification};
|
use crate::notification::{send_notification, DatabaseNotification};
|
||||||
use crate::services::cell::{
|
use crate::services::cell::{
|
||||||
@ -34,7 +34,9 @@ use crate::services::field::{
|
|||||||
SelectOptionIds, TypeOptionCellDataHandler, TypeOptionCellExt,
|
SelectOptionIds, TypeOptionCellDataHandler, TypeOptionCellExt,
|
||||||
};
|
};
|
||||||
use crate::services::filter::Filter;
|
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::share::csv::{CSVExport, CSVFormat};
|
||||||
use crate::services::sort::Sort;
|
use crate::services::sort::Sort;
|
||||||
|
|
||||||
@ -85,18 +87,18 @@ impl DatabaseEditor {
|
|||||||
self.database.lock().fields.get_field(field_id)
|
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 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 {
|
if let Some(field) = field {
|
||||||
let group_setting = default_group_setting(&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?;
|
let view_editor = self.database_views.get_view_editor(view_id).await?;
|
||||||
view_editor.v_initialize_new_group(params).await?;
|
view_editor.v_initialize_new_group(field_id).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,8 +113,20 @@ impl DatabaseEditor {
|
|||||||
Ok(())
|
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)]
|
#[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?;
|
let view_editor = self.database_views.get_view_editor(¶ms.view_id).await?;
|
||||||
view_editor.v_insert_filter(params).await?;
|
view_editor.v_insert_filter(params).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -124,7 +138,7 @@ impl DatabaseEditor {
|
|||||||
Ok(())
|
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 view_editor = self.database_views.get_view_editor(¶ms.view_id).await?;
|
||||||
let sort = view_editor.v_insert_sort(params).await?;
|
let sort = view_editor.v_insert_sort(params).await?;
|
||||||
Ok(sort)
|
Ok(sort)
|
||||||
@ -549,6 +563,8 @@ impl DatabaseEditor {
|
|||||||
Some(SelectOptionPB::from(select_option))
|
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(
|
pub async fn insert_select_options(
|
||||||
&self,
|
&self,
|
||||||
view_id: &str,
|
view_id: &str,
|
||||||
@ -556,30 +572,25 @@ impl DatabaseEditor {
|
|||||||
row_id: RowId,
|
row_id: RowId,
|
||||||
options: Vec<SelectOptionPB>,
|
options: Vec<SelectOptionPB>,
|
||||||
) -> FlowyResult<()> {
|
) -> FlowyResult<()> {
|
||||||
let field = match self.database.lock().fields.get_field(field_id) {
|
let field = self.database.lock().fields.get_field(field_id).ok_or(
|
||||||
Some(field) => Ok(field),
|
FlowyError::record_not_found().context(format!("Field with id:{} not found", &field_id)),
|
||||||
None => {
|
)?;
|
||||||
let msg = format!("Field with id:{} not found", &field_id);
|
debug_assert!(FieldType::from(field.field_type).is_select_option());
|
||||||
Err(FlowyError::internal().context(msg))
|
|
||||||
},
|
|
||||||
}?;
|
|
||||||
let mut type_option = select_type_option_from_field(&field)?;
|
let mut type_option = select_type_option_from_field(&field)?;
|
||||||
let cell_changeset = SelectOptionCellChangeset {
|
let cell_changeset = SelectOptionCellChangeset {
|
||||||
insert_option_ids: options.iter().map(|option| option.id.clone()).collect(),
|
insert_option_ids: options.iter().map(|option| option.id.clone()).collect(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
options
|
||||||
|
.into_iter()
|
||||||
|
.for_each(|option| type_option.insert_option(option.into()));
|
||||||
|
|
||||||
for option in options {
|
// Update the field's type option
|
||||||
type_option.insert_option(option.into());
|
|
||||||
}
|
|
||||||
self
|
self
|
||||||
.database
|
.update_field_type_option(view_id, field_id, type_option.to_type_option_data(), field)
|
||||||
.lock()
|
.await?;
|
||||||
.fields
|
// Insert the options into the cell
|
||||||
.update_field(field_id, |update| {
|
|
||||||
update.set_type_option(field.field_type, Some(type_option.to_type_option_data()));
|
|
||||||
});
|
|
||||||
|
|
||||||
self
|
self
|
||||||
.update_cell_with_changeset(view_id, row_id, field_id, cell_changeset)
|
.update_cell_with_changeset(view_id, row_id, field_id, cell_changeset)
|
||||||
.await?;
|
.await?;
|
||||||
@ -709,7 +720,7 @@ impl DatabaseEditor {
|
|||||||
|
|
||||||
pub async fn group_by_field(&self, view_id: &str, field_id: &str) -> FlowyResult<()> {
|
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?;
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#![allow(clippy::while_let_loop)]
|
#![allow(clippy::while_let_loop)]
|
||||||
use crate::entities::{
|
use crate::entities::{
|
||||||
DatabaseViewSettingPB, FilterChangesetNotificationPB, GroupChangesetPB, GroupRowsNotificationPB,
|
DatabaseViewSettingPB, FilterChangesetNotificationPB, GroupChangesPB, GroupRowsNotificationPB,
|
||||||
ReorderAllRowsPB, ReorderSingleRowPB, RowsVisibilityChangePB, SortChangesetNotificationPB,
|
ReorderAllRowsPB, ReorderSingleRowPB, RowsVisibilityChangePB, SortChangesetNotificationPB,
|
||||||
};
|
};
|
||||||
use crate::notification::{send_notification, DatabaseNotification};
|
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) {
|
pub(crate) async fn notify_did_update_num_of_groups(view_id: &str, changeset: GroupChangesPB) {
|
||||||
send_notification(view_id, DatabaseNotification::DidUpdateGroups)
|
send_notification(view_id, DatabaseNotification::DidUpdateNumOfGroups)
|
||||||
.payload(changeset)
|
.payload(changeset)
|
||||||
.send();
|
.send();
|
||||||
}
|
}
|
||||||
|
@ -13,10 +13,10 @@ use flowy_task::TaskDispatcher;
|
|||||||
use lib_infra::future::Fut;
|
use lib_infra::future::Fut;
|
||||||
|
|
||||||
use crate::entities::{
|
use crate::entities::{
|
||||||
AlterFilterParams, AlterSortParams, CalendarEventPB, DeleteFilterParams, DeleteGroupParams,
|
CalendarEventPB, DeleteFilterParams, DeleteGroupParams, DeleteSortParams, FieldType,
|
||||||
DeleteSortParams, FieldType, GroupChangesetPB, GroupPB, GroupRowsNotificationPB,
|
GroupChangesPB, GroupPB, GroupRowsNotificationPB, InsertedRowPB, LayoutSettingPB,
|
||||||
InsertGroupParams, InsertedGroupPB, InsertedRowPB, LayoutSettingPB, LayoutSettingParams, RowPB,
|
LayoutSettingParams, RowPB, RowsChangePB, SortChangesetNotificationPB, SortPB,
|
||||||
RowsChangePB, SortChangesetNotificationPB, SortPB,
|
UpdateFilterParams, UpdateSortParams,
|
||||||
};
|
};
|
||||||
use crate::notification::{send_notification, DatabaseNotification};
|
use crate::notification::{send_notification, DatabaseNotification};
|
||||||
use crate::services::cell::CellCache;
|
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::view_sort::make_sort_controller;
|
||||||
use crate::services::database_view::{
|
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,
|
notify_did_update_setting, notify_did_update_sort, DatabaseViewChangedNotifier,
|
||||||
DatabaseViewChangedReceiverRunner,
|
DatabaseViewChangedReceiverRunner,
|
||||||
};
|
};
|
||||||
@ -35,7 +35,9 @@ use crate::services::field::TypeOptionCellDataHandler;
|
|||||||
use crate::services::filter::{
|
use crate::services::filter::{
|
||||||
Filter, FilterChangeset, FilterController, FilterType, UpdatedFilterType,
|
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::setting::CalendarLayoutSetting;
|
||||||
use crate::services::sort::{DeletedSortType, Sort, SortChangeset, SortController, SortType};
|
use crate::services::sort::{DeletedSortType, Sort, SortChangeset, SortController, SortType};
|
||||||
|
|
||||||
@ -237,27 +239,29 @@ impl DatabaseViewEditor {
|
|||||||
.await;
|
.await;
|
||||||
|
|
||||||
if let Some(Ok(result)) = result {
|
if let Some(Ok(result)) = result {
|
||||||
let mut changeset = GroupChangesetPB {
|
let mut group_changes = GroupChangesPB {
|
||||||
view_id: self.view_id.clone(),
|
view_id: self.view_id.clone(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
if let Some(inserted_group) = result.inserted_group {
|
if let Some(inserted_group) = result.inserted_group {
|
||||||
tracing::trace!("Create group after editing the row: {:?}", 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 {
|
if let Some(delete_group) = result.deleted_group {
|
||||||
tracing::trace!("Delete group after editing the row: {:?}", delete_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 {
|
for changeset in result.row_changesets {
|
||||||
|
if !changeset.is_empty() {
|
||||||
|
tracing::trace!("Group change after editing the row: {:?}", changeset);
|
||||||
notify_did_update_group_rows(changeset).await;
|
notify_did_update_group_rows(changeset).await;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
let update_row = UpdatedRow {
|
let update_row = UpdatedRow {
|
||||||
row: RowOrder::from(row),
|
row: RowOrder::from(row),
|
||||||
@ -326,15 +330,15 @@ impl DatabaseViewEditor {
|
|||||||
.await;
|
.await;
|
||||||
|
|
||||||
if let Some(result) = result {
|
if let Some(result) = result {
|
||||||
let mut changeset = GroupChangesetPB {
|
if let Some(delete_group) = result.deleted_group {
|
||||||
|
tracing::trace!("Delete group after moving the row: {:?}", delete_group);
|
||||||
|
let mut changes = GroupChangesPB {
|
||||||
view_id: self.view_id.clone(),
|
view_id: self.view_id.clone(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
if let Some(delete_group) = result.deleted_group {
|
changes.deleted_groups.push(delete_group.group_id);
|
||||||
tracing::info!("Delete group after moving the row: {:?}", delete_group);
|
notify_did_update_num_of_groups(&self.view_id, changes).await;
|
||||||
changeset.deleted_groups.push(delete_group.group_id);
|
|
||||||
}
|
}
|
||||||
notify_did_update_groups(&self.view_id, changeset).await;
|
|
||||||
|
|
||||||
for changeset in result.row_changesets {
|
for changeset in result.row_changesets {
|
||||||
notify_did_update_group_rows(changeset).await;
|
notify_did_update_group_rows(changeset).await;
|
||||||
@ -371,25 +375,6 @@ impl DatabaseViewEditor {
|
|||||||
.write()
|
.write()
|
||||||
.await
|
.await
|
||||||
.move_group(from_group, to_group)?;
|
.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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -397,9 +382,9 @@ impl DatabaseViewEditor {
|
|||||||
self.group_controller.read().await.field_id().to_string()
|
self.group_controller.read().await.field_id().to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn v_initialize_new_group(&self, params: InsertGroupParams) -> FlowyResult<()> {
|
pub async fn v_initialize_new_group(&self, field_id: &str) -> FlowyResult<()> {
|
||||||
if self.group_controller.read().await.field_id() != params.field_id {
|
if self.group_controller.read().await.field_id() != field_id {
|
||||||
self.v_update_group_setting(¶ms.field_id).await?;
|
self.v_update_grouping_field(field_id).await?;
|
||||||
|
|
||||||
if let Some(view) = self.delegate.get_view_setting(&self.view_id).await {
|
if let Some(view) = self.delegate.get_view_setting(&self.view_id).await {
|
||||||
let setting = database_view_setting_pb_from_view(view);
|
let setting = database_view_setting_pb_from_view(view);
|
||||||
@ -413,12 +398,20 @@ impl DatabaseViewEditor {
|
|||||||
Ok(())
|
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> {
|
pub async fn v_get_all_sorts(&self) -> Vec<Sort> {
|
||||||
self.delegate.get_all_sorts(&self.view_id)
|
self.delegate.get_all_sorts(&self.view_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "trace", skip(self), err)]
|
#[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 is_exist = params.sort_id.is_some();
|
||||||
let sort_id = match params.sort_id {
|
let sort_id = match params.sort_id {
|
||||||
None => gen_database_sort_id(),
|
None => gen_database_sort_id(),
|
||||||
@ -479,7 +472,7 @@ impl DatabaseViewEditor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "trace", skip(self), err)]
|
#[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 is_exist = params.filter_id.is_some();
|
||||||
let filter_id = match params.filter_id {
|
let filter_id = match params.filter_id {
|
||||||
None => gen_database_filter_id(),
|
None => gen_database_filter_id(),
|
||||||
@ -634,9 +627,15 @@ impl DatabaseViewEditor {
|
|||||||
.sort_controller
|
.sort_controller
|
||||||
.read()
|
.read()
|
||||||
.await
|
.await
|
||||||
.did_update_view_field_type_option(&field)
|
.did_update_field_type_option(&field)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
|
self
|
||||||
|
.group_controller
|
||||||
|
.write()
|
||||||
|
.await
|
||||||
|
.did_update_field_type_option(&field);
|
||||||
|
|
||||||
if let Some(filter) = self
|
if let Some(filter) = self
|
||||||
.delegate
|
.delegate
|
||||||
.get_filter_by_field_id(&self.view_id, field_id)
|
.get_filter_by_field_id(&self.view_id, field_id)
|
||||||
@ -660,14 +659,9 @@ impl DatabaseViewEditor {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
/// Called when a grouping field is updated.
|
||||||
///
|
|
||||||
/// # Arguments
|
|
||||||
///
|
|
||||||
/// * `field_id`:
|
|
||||||
///
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, err)]
|
#[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 {
|
if let Some(field) = self.delegate.get_field(field_id).await {
|
||||||
let new_group_controller =
|
let new_group_controller =
|
||||||
new_group_controller_with_field(self.view_id.clone(), self.delegate.clone(), field).await?;
|
new_group_controller_with_field(self.view_id.clone(), self.delegate.clone(), field).await?;
|
||||||
@ -679,7 +673,7 @@ impl DatabaseViewEditor {
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
*self.group_controller.write().await = new_group_controller;
|
*self.group_controller.write().await = new_group_controller;
|
||||||
let changeset = GroupChangesetPB {
|
let changeset = GroupChangesPB {
|
||||||
view_id: self.view_id.clone(),
|
view_id: self.view_id.clone(),
|
||||||
initial_groups: new_groups,
|
initial_groups: new_groups,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
@ -5,7 +5,6 @@ use collab_database::rows::RowId;
|
|||||||
|
|
||||||
use flowy_error::{FlowyError, FlowyResult};
|
use flowy_error::{FlowyError, FlowyResult};
|
||||||
use lib_infra::future::{to_fut, Fut};
|
use lib_infra::future::{to_fut, Fut};
|
||||||
use tracing::trace;
|
|
||||||
|
|
||||||
use crate::entities::FieldType;
|
use crate::entities::FieldType;
|
||||||
use crate::services::database_view::DatabaseViewData;
|
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 fields = delegate.get_fields(&view_id, None).await;
|
||||||
let rows = delegate.get_rows(&view_id).await;
|
let rows = delegate.get_rows(&view_id).await;
|
||||||
let layout = delegate.get_layout_for_view(&view_id);
|
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
|
// Read the grouping field or find a new grouping field
|
||||||
let mut grouping_field = setting_reader
|
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
|
// If the id of the grouping field is equal to the updated field's id, then we need to
|
||||||
// update the group setting
|
// update the group setting
|
||||||
if view_editor.group_id().await == field_id {
|
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
|
view_editor
|
||||||
.v_did_update_field_type_option(field_id, old_field)
|
.v_did_update_field_type_option(field_id, old_field)
|
||||||
@ -108,7 +108,6 @@ impl DatabaseViews {
|
|||||||
return Ok(editor.clone());
|
return Ok(editor.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
tracing::trace!("{:p} create view:{} editor", self, view_id);
|
|
||||||
let mut editor_map = self.editor_map.write().await;
|
let mut editor_map = self.editor_map.write().await;
|
||||||
let editor = Arc::new(
|
let editor = Arc::new(
|
||||||
DatabaseViewEditor::new(
|
DatabaseViewEditor::new(
|
||||||
|
@ -22,6 +22,8 @@ pub trait SelectTypeOptionSharedAction: Send + Sync {
|
|||||||
fn number_of_max_options(&self) -> Option<usize>;
|
fn number_of_max_options(&self) -> Option<usize>;
|
||||||
|
|
||||||
/// Insert the `SelectOption` into corresponding type option.
|
/// 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) {
|
fn insert_option(&mut self, new_option: SelectOption) {
|
||||||
let options = self.mut_options();
|
let options = self.mut_options();
|
||||||
if let Some(index) = options
|
if let Some(index) = options
|
||||||
|
@ -131,12 +131,12 @@ where
|
|||||||
if let Some(cell_data_cache) = self.cell_data_cache.as_ref() {
|
if let Some(cell_data_cache) = self.cell_data_cache.as_ref() {
|
||||||
let read_guard = cell_data_cache.read();
|
let read_guard = cell_data_cache.read();
|
||||||
if let Some(cell_data) = read_guard.get(key.as_ref()).cloned() {
|
if let Some(cell_data) = read_guard.get(key.as_ref()).cloned() {
|
||||||
tracing::trace!(
|
// tracing::trace!(
|
||||||
"Cell cache hit: field_type:{}, cell: {:?}, cell_data: {:?}",
|
// "Cell cache hit: field_type:{}, cell: {:?}, cell_data: {:?}",
|
||||||
decoded_field_type,
|
// decoded_field_type,
|
||||||
cell,
|
// cell,
|
||||||
cell_data
|
// cell_data
|
||||||
);
|
// );
|
||||||
return Ok(cell_data);
|
return Ok(cell_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -219,6 +219,7 @@ impl FilterController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn did_receive_row_changed(&self, row_id: RowId) {
|
pub async fn did_receive_row_changed(&self, row_id: RowId) {
|
||||||
|
if !self.cell_filter_cache.read().is_empty() {
|
||||||
self
|
self
|
||||||
.gen_task(
|
.gen_task(
|
||||||
FilterEvent::RowDidChanged(row_id),
|
FilterEvent::RowDidChanged(row_id),
|
||||||
@ -226,6 +227,7 @@ impl FilterController {
|
|||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "trace", skip(self))]
|
#[tracing::instrument(level = "trace", skip(self))]
|
||||||
pub async fn did_receive_changes(
|
pub async fn did_receive_changes(
|
||||||
|
@ -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::cell::DecodedCellData;
|
||||||
use crate::services::group::controller::MoveGroupRowContext;
|
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::fields::Field;
|
||||||
use collab_database::rows::{Cell, Row};
|
use collab_database::rows::{Cell, Row};
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ pub trait GroupCustomize: Send + Sync {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Defines the shared actions any group controller can perform.
|
/// 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
|
/// The field that is used for grouping the rows
|
||||||
fn field_id(&self) -> &str;
|
fn field_id(&self) -> &str;
|
||||||
|
|
||||||
@ -100,7 +100,9 @@ pub trait GroupControllerActions: Send + Sync {
|
|||||||
fn move_group_row(&mut self, context: MoveGroupRowContext) -> FlowyResult<DidMoveGroupRowResult>;
|
fn move_group_row(&mut self, context: MoveGroupRowContext) -> FlowyResult<DidMoveGroupRowResult>;
|
||||||
|
|
||||||
/// Update the group if the corresponding field is changed
|
/// 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)]
|
#[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::field::RowSingleCellData;
|
||||||
use crate::services::group::{
|
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 collab_database::fields::Field;
|
||||||
use flowy_error::{FlowyError, FlowyResult};
|
use flowy_error::{FlowyError, FlowyResult};
|
||||||
@ -25,7 +25,7 @@ pub trait GroupSettingWriter: Send + Sync + 'static {
|
|||||||
|
|
||||||
impl<T> std::fmt::Display for GroupContext<T> {
|
impl<T> std::fmt::Display for GroupContext<T> {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
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!(
|
let _ = f.write_fmt(format_args!(
|
||||||
"Group:{} has {} rows \n",
|
"Group:{} has {} rows \n",
|
||||||
group.id,
|
group.id,
|
||||||
@ -54,8 +54,9 @@ pub struct GroupContext<C> {
|
|||||||
/// The grouping field
|
/// The grouping field
|
||||||
field: Arc<Field>,
|
field: Arc<Field>,
|
||||||
|
|
||||||
/// Cache all the groups
|
/// Cache all the groups. Cache the group by its id.
|
||||||
groups_map: IndexMap<String, GroupData>,
|
/// 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
|
/// A reader that implement the [GroupSettingReader] trait
|
||||||
///
|
///
|
||||||
@ -93,7 +94,7 @@ where
|
|||||||
Ok(Self {
|
Ok(Self {
|
||||||
view_id,
|
view_id,
|
||||||
field,
|
field,
|
||||||
groups_map: IndexMap::new(),
|
group_by_id: IndexMap::new(),
|
||||||
reader,
|
reader,
|
||||||
writer,
|
writer,
|
||||||
setting,
|
setting,
|
||||||
@ -105,26 +106,26 @@ where
|
|||||||
///
|
///
|
||||||
/// We take the `id` of the `field` as the no status group id
|
/// We take the `id` of the `field` as the no status group id
|
||||||
pub(crate) fn get_no_status_group(&self) -> Option<&GroupData> {
|
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> {
|
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> {
|
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> {
|
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
|
// Returns the index and group specified by the group_id
|
||||||
pub(crate) fn get_group(&self, group_id: &str) -> Option<(usize, &GroupData)> {
|
pub(crate) fn get_group(&self, group_id: &str) -> Option<(usize, &GroupData)> {
|
||||||
match (
|
match (
|
||||||
self.groups_map.get_index_of(group_id),
|
self.group_by_id.get_index_of(group_id),
|
||||||
self.groups_map.get(group_id),
|
self.group_by_id.get(group_id),
|
||||||
) {
|
) {
|
||||||
(Some(index), Some(group)) => Some((index, group)),
|
(Some(index), Some(group)) => Some((index, group)),
|
||||||
_ => None,
|
_ => None,
|
||||||
@ -133,7 +134,7 @@ where
|
|||||||
|
|
||||||
/// Iterate mut the groups without `No status` group
|
/// Iterate mut the groups without `No status` group
|
||||||
pub(crate) fn iter_mut_status_groups(&mut self, mut each: impl FnMut(&mut GroupData)) {
|
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 {
|
if group.id != self.field.id {
|
||||||
each(group);
|
each(group);
|
||||||
}
|
}
|
||||||
@ -141,7 +142,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn iter_mut_groups(&mut self, mut each: impl FnMut(&mut GroupData)) {
|
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);
|
each(group);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -153,7 +154,7 @@ where
|
|||||||
group.name.clone(),
|
group.name.clone(),
|
||||||
group.id.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 (index, group_data) = self.get_group(&group.id).unwrap();
|
||||||
let insert_group = InsertedGroupPB {
|
let insert_group = InsertedGroupPB {
|
||||||
group: GroupPB::from(group_data.clone()),
|
group: GroupPB::from(group_data.clone()),
|
||||||
@ -170,7 +171,7 @@ where
|
|||||||
|
|
||||||
#[tracing::instrument(level = "trace", skip(self))]
|
#[tracing::instrument(level = "trace", skip(self))]
|
||||||
pub(crate) fn delete_group(&mut self, deleted_group_id: &str) -> FlowyResult<()> {
|
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| {
|
self.mut_configuration(|configuration| {
|
||||||
configuration
|
configuration
|
||||||
.groups
|
.groups
|
||||||
@ -181,11 +182,11 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn move_group(&mut self, from_id: &str, to_id: &str) -> FlowyResult<()> {
|
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 from_index = self.group_by_id.get_index_of(from_id);
|
||||||
let to_index = self.groups_map.get_index_of(to_id);
|
let to_index = self.group_by_id.get_index_of(to_id);
|
||||||
match (from_index, to_index) {
|
match (from_index, to_index) {
|
||||||
(Some(from_index), Some(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| {
|
self.mut_configuration(|configuration| {
|
||||||
let from_index = configuration
|
let from_index = configuration
|
||||||
@ -205,7 +206,7 @@ where
|
|||||||
let group = configuration.groups.remove(*from);
|
let group = configuration.groups.remove(*from);
|
||||||
configuration.groups.insert(*to, group);
|
configuration.groups.insert(*to, group);
|
||||||
}
|
}
|
||||||
tracing::debug!(
|
tracing::trace!(
|
||||||
"Group order: {:?} ",
|
"Group order: {:?} ",
|
||||||
configuration
|
configuration
|
||||||
.groups
|
.groups
|
||||||
@ -237,15 +238,15 @@ where
|
|||||||
/// [GroupConfigurationRevision] as old groups. The old groups and the new groups will be merged
|
/// [GroupConfigurationRevision] as old groups. The old groups and the new groups will be merged
|
||||||
/// while keeping the order of the old groups.
|
/// 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(
|
pub(crate) fn init_groups(
|
||||||
&mut self,
|
&mut self,
|
||||||
generated_group_context: GeneratedGroupContext,
|
generated_groups: GeneratedGroups,
|
||||||
) -> FlowyResult<Option<GroupChangesetPB>> {
|
) -> FlowyResult<Option<GroupChangesPB>> {
|
||||||
let GeneratedGroupContext {
|
let GeneratedGroups {
|
||||||
no_status_group,
|
no_status_group,
|
||||||
group_configs,
|
group_configs,
|
||||||
} = generated_group_context;
|
} = generated_groups;
|
||||||
|
|
||||||
let mut new_groups = vec![];
|
let mut new_groups = vec![];
|
||||||
let mut filter_content_map = HashMap::new();
|
let mut filter_content_map = HashMap::new();
|
||||||
@ -310,18 +311,13 @@ where
|
|||||||
})?;
|
})?;
|
||||||
|
|
||||||
// Update the memory cache of the groups
|
// 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
|
let filter_content = filter_content_map
|
||||||
.get(&group_rev.id)
|
.get(&group.id)
|
||||||
.cloned()
|
.cloned()
|
||||||
.unwrap_or_else(|| "".to_owned());
|
.unwrap_or_else(|| "".to_owned());
|
||||||
let group = GroupData::new(
|
let group = GroupData::new(group.id, self.field.id.clone(), group.name, filter_content);
|
||||||
group_rev.id,
|
self.group_by_id.insert(group.id.clone(), group);
|
||||||
self.field.id.clone(),
|
|
||||||
group_rev.name,
|
|
||||||
filter_content,
|
|
||||||
);
|
|
||||||
self.groups_map.insert(group.id.clone(), group);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let initial_groups = new_groups
|
let initial_groups = new_groups
|
||||||
@ -338,13 +334,14 @@ where
|
|||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let changeset = GroupChangesetPB {
|
let changeset = GroupChangesPB {
|
||||||
view_id: self.view_id.clone(),
|
view_id: self.view_id.clone(),
|
||||||
initial_groups,
|
initial_groups,
|
||||||
deleted_groups: deleted_group_ids,
|
deleted_groups: deleted_group_ids,
|
||||||
update_groups: vec![],
|
update_groups: vec![],
|
||||||
inserted_groups: vec![],
|
inserted_groups: vec![],
|
||||||
};
|
};
|
||||||
|
|
||||||
tracing::trace!("Group changeset: {:?}", changeset);
|
tracing::trace!("Group changeset: {:?}", changeset);
|
||||||
if changeset.is_empty() {
|
if changeset.is_empty() {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
@ -353,18 +350,15 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
pub(crate) fn update_group(&mut self, group_changeset: GroupChangeset) -> FlowyResult<()> {
|
||||||
pub(crate) async fn hide_group(&mut self, group_id: &str) -> FlowyResult<()> {
|
self.mut_group(&group_changeset.group_id, |group| {
|
||||||
self.mut_group_rev(group_id, |group_rev| {
|
if let Some(visible) = group_changeset.visible {
|
||||||
group_rev.visible = false;
|
group.visible = visible;
|
||||||
})?;
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
if let Some(name) = &group_changeset.name {
|
||||||
pub(crate) async fn show_group(&mut self, group_id: &str) -> FlowyResult<()> {
|
group.name = name.clone();
|
||||||
self.mut_group_rev(group_id, |group_rev| {
|
}
|
||||||
group_rev.visible = true;
|
|
||||||
})?;
|
})?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -398,11 +392,7 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mut_group_rev(
|
fn mut_group(&mut self, group_id: &str, mut_groups_fn: impl Fn(&mut Group)) -> FlowyResult<()> {
|
||||||
&mut self,
|
|
||||||
group_id: &str,
|
|
||||||
mut_groups_fn: impl Fn(&mut Group),
|
|
||||||
) -> FlowyResult<()> {
|
|
||||||
self.mut_configuration(|configuration| {
|
self.mut_configuration(|configuration| {
|
||||||
match configuration
|
match configuration
|
||||||
.groups
|
.groups
|
||||||
|
@ -9,14 +9,14 @@ use serde::Serialize;
|
|||||||
|
|
||||||
use flowy_error::FlowyResult;
|
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::cell::{get_cell_protobuf, CellProtobufBlobParser, DecodedCellData};
|
||||||
use crate::services::group::action::{
|
use crate::services::group::action::{
|
||||||
DidMoveGroupRowResult, DidUpdateGroupRowResult, GroupControllerActions, GroupCustomize,
|
DidMoveGroupRowResult, DidUpdateGroupRowResult, GroupControllerOperation, GroupCustomize,
|
||||||
};
|
};
|
||||||
use crate::services::group::configuration::GroupContext;
|
use crate::services::group::configuration::GroupContext;
|
||||||
use crate::services::group::entities::GroupData;
|
use crate::services::group::entities::GroupData;
|
||||||
use crate::services::group::Group;
|
use crate::services::group::{Group, GroupSettingChangeset};
|
||||||
|
|
||||||
// use collab_database::views::Group;
|
// 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
|
/// If the [FieldType] doesn't implement its group controller, then the [DefaultGroupController] will
|
||||||
/// be used.
|
/// 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);
|
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);
|
fn did_create_row(&mut self, row: &Row, group_id: &str);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The [GroupGenerator] trait is used to generate the groups for different [FieldType]
|
/// The [GroupsBuilder] trait is used to generate the groups for different [FieldType]
|
||||||
pub trait GroupGenerator {
|
pub trait GroupsBuilder {
|
||||||
type Context;
|
type Context;
|
||||||
type TypeOptionType;
|
type TypeOptionType;
|
||||||
|
|
||||||
fn generate_groups(
|
fn build(
|
||||||
field: &Field,
|
field: &Field,
|
||||||
group_ctx: &Self::Context,
|
context: &Self::Context,
|
||||||
type_option: &Option<Self::TypeOptionType>,
|
type_option: &Option<Self::TypeOptionType>,
|
||||||
) -> GeneratedGroupContext;
|
) -> GeneratedGroups;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct GeneratedGroupContext {
|
pub struct GeneratedGroups {
|
||||||
pub no_status_group: Option<Group>,
|
pub no_status_group: Option<Group>,
|
||||||
pub group_configs: Vec<GeneratedGroupConfig>,
|
pub group_configs: Vec<GeneratedGroupConfig>,
|
||||||
}
|
}
|
||||||
@ -90,21 +96,21 @@ impl RowChangeset {
|
|||||||
|
|
||||||
/// C: represents the group configuration that impl [GroupConfigurationSerde]
|
/// C: represents the group configuration that impl [GroupConfigurationSerde]
|
||||||
/// T: the type-option data deserializer that impl [TypeOptionDataDeserializer]
|
/// 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
|
/// 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 grouping_field_id: String,
|
||||||
pub type_option: Option<T>,
|
pub type_option: Option<T>,
|
||||||
pub group_ctx: GroupContext<C>,
|
pub context: GroupContext<C>,
|
||||||
group_action_phantom: PhantomData<G>,
|
group_action_phantom: PhantomData<G>,
|
||||||
cell_parser_phantom: PhantomData<P>,
|
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
|
where
|
||||||
C: Serialize + DeserializeOwned,
|
C: Serialize + DeserializeOwned,
|
||||||
T: From<TypeOptionData>,
|
T: From<TypeOptionData>,
|
||||||
G: GroupGenerator<Context = GroupContext<C>, TypeOptionType = T>,
|
G: GroupsBuilder<Context = GroupContext<C>, TypeOptionType = T>,
|
||||||
{
|
{
|
||||||
pub async fn new(
|
pub async fn new(
|
||||||
grouping_field: &Arc<Field>,
|
grouping_field: &Arc<Field>,
|
||||||
@ -112,13 +118,13 @@ where
|
|||||||
) -> FlowyResult<Self> {
|
) -> FlowyResult<Self> {
|
||||||
let field_type = FieldType::from(grouping_field.field_type);
|
let field_type = FieldType::from(grouping_field.field_type);
|
||||||
let type_option = grouping_field.get_type_option::<T>(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 generated_groups = G::build(grouping_field, &configuration, &type_option);
|
||||||
let _ = configuration.init_groups(generated_group_context)?;
|
let _ = configuration.init_groups(generated_groups)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
grouping_field_id: grouping_field.id.clone(),
|
grouping_field_id: grouping_field.id.clone(),
|
||||||
type_option,
|
type_option,
|
||||||
group_ctx: configuration,
|
context: configuration,
|
||||||
group_action_phantom: PhantomData,
|
group_action_phantom: PhantomData,
|
||||||
cell_parser_phantom: PhantomData,
|
cell_parser_phantom: PhantomData,
|
||||||
})
|
})
|
||||||
@ -131,7 +137,7 @@ where
|
|||||||
row: &Row,
|
row: &Row,
|
||||||
other_group_changesets: &[GroupRowsNotificationPB],
|
other_group_changesets: &[GroupRowsNotificationPB],
|
||||||
) -> Option<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.
|
// [other_group_inserted_row] contains all the inserted rows except the default group.
|
||||||
let other_group_inserted_row = other_group_changesets
|
let other_group_inserted_row = other_group_changesets
|
||||||
@ -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
|
where
|
||||||
P: CellProtobufBlobParser,
|
P: CellProtobufBlobParser,
|
||||||
C: Serialize + DeserializeOwned,
|
C: Serialize + DeserializeOwned,
|
||||||
T: From<TypeOptionData>,
|
T: From<TypeOptionData>,
|
||||||
G: GroupGenerator<Context = GroupContext<C>, TypeOptionType = T>,
|
G: GroupsBuilder<Context = GroupContext<C>, TypeOptionType = T>,
|
||||||
|
|
||||||
Self: GroupCustomize<CellData = P::Object>,
|
Self: GroupCustomize<CellData = P::Object>,
|
||||||
{
|
{
|
||||||
@ -210,11 +216,11 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn groups(&self) -> Vec<&GroupData> {
|
fn groups(&self) -> Vec<&GroupData> {
|
||||||
self.group_ctx.groups()
|
self.context.groups()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_group(&self, group_id: &str) -> Option<(usize, GroupData)> {
|
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()))
|
Some((group.0, group.1.clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,7 +236,7 @@ where
|
|||||||
let mut grouped_rows: Vec<GroupedRow> = vec![];
|
let mut grouped_rows: Vec<GroupedRow> = vec![];
|
||||||
let cell_bytes = get_cell_protobuf(&cell, field, None);
|
let cell_bytes = get_cell_protobuf(&cell, field, None);
|
||||||
let cell_data = cell_bytes.parser::<P>()?;
|
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) {
|
if self.can_group(&group.filter_content, &cell_data) {
|
||||||
grouped_rows.push(GroupedRow {
|
grouped_rows.push(GroupedRow {
|
||||||
row: (*row).clone(),
|
row: (*row).clone(),
|
||||||
@ -241,25 +247,25 @@ where
|
|||||||
|
|
||||||
if !grouped_rows.is_empty() {
|
if !grouped_rows.is_empty() {
|
||||||
for group_row in grouped_rows {
|
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);
|
group.add_row(group_row.row);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
match self.group_ctx.get_mut_no_status_group() {
|
match self.context.get_mut_no_status_group() {
|
||||||
None => {},
|
None => {},
|
||||||
Some(no_status_group) => no_status_group.add_row((*row).clone()),
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_group(&mut self, from_group_id: &str, to_group_id: &str) -> FlowyResult<()> {
|
fn move_group(&mut self, from_group_id: &str, to_group_id: &str) -> FlowyResult<()> {
|
||||||
self.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(
|
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 => {
|
None => {
|
||||||
tracing::error!("Unexpected None value. It should have the no status group");
|
tracing::error!("Unexpected None value. It should have the no status group");
|
||||||
},
|
},
|
||||||
@ -359,9 +365,18 @@ where
|
|||||||
Ok(result)
|
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)
|
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 {
|
struct GroupedRow {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use collab_database::fields::Field;
|
use collab_database::fields::Field;
|
||||||
use collab_database::rows::{new_cell_builder, Cell, Cells, Row};
|
use collab_database::rows::{new_cell_builder, Cell, Cells, Row};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::entities::{FieldType, GroupRowsNotificationPB, InsertedRowPB, RowPB};
|
use crate::entities::{FieldType, GroupRowsNotificationPB, InsertedRowPB, RowPB};
|
||||||
use crate::services::cell::insert_checkbox_cell;
|
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::action::GroupCustomize;
|
||||||
use crate::services::group::configuration::GroupContext;
|
use crate::services::group::configuration::GroupContext;
|
||||||
use crate::services::group::controller::{
|
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)]
|
#[derive(Default, Serialize, Deserialize)]
|
||||||
pub struct CheckboxGroupConfiguration {
|
pub struct CheckboxGroupConfiguration {
|
||||||
pub hide_empty: bool,
|
pub hide_empty: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type CheckboxGroupController = GenericGroupController<
|
pub type CheckboxGroupController = BaseGroupController<
|
||||||
CheckboxGroupConfiguration,
|
CheckboxGroupConfiguration,
|
||||||
CheckboxTypeOption,
|
CheckboxTypeOption,
|
||||||
CheckboxGroupGenerator,
|
CheckboxGroupGenerator,
|
||||||
@ -52,7 +53,7 @@ impl GroupCustomize for CheckboxGroupController {
|
|||||||
cell_data: &Self::CellData,
|
cell_data: &Self::CellData,
|
||||||
) -> Vec<GroupRowsNotificationPB> {
|
) -> Vec<GroupRowsNotificationPB> {
|
||||||
let mut changesets = vec![];
|
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 mut changeset = GroupRowsNotificationPB::new(group.id.clone());
|
||||||
let is_not_contained = !group.contains_row(&row.id);
|
let is_not_contained = !group.contains_row(&row.id);
|
||||||
if group.id == CHECK {
|
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> {
|
fn delete_row(&mut self, row: &Row, _cell_data: &Self::CellData) -> Vec<GroupRowsNotificationPB> {
|
||||||
let mut changesets = vec![];
|
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());
|
let mut changeset = GroupRowsNotificationPB::new(group.id.clone());
|
||||||
if group.contains_row(&row.id) {
|
if group.contains_row(&row.id) {
|
||||||
changeset.deleted_rows.push(row.id.clone().into_inner());
|
changeset.deleted_rows.push(row.id.clone().into_inner());
|
||||||
@ -116,7 +117,7 @@ impl GroupCustomize for CheckboxGroupController {
|
|||||||
mut context: MoveGroupRowContext,
|
mut context: MoveGroupRowContext,
|
||||||
) -> Vec<GroupRowsNotificationPB> {
|
) -> Vec<GroupRowsNotificationPB> {
|
||||||
let mut group_changeset = vec![];
|
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) {
|
if let Some(changeset) = move_group_row(group, &mut context) {
|
||||||
group_changeset.push(changeset);
|
group_changeset.push(changeset);
|
||||||
}
|
}
|
||||||
@ -126,8 +127,12 @@ impl GroupCustomize for CheckboxGroupController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl GroupController 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) {
|
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),
|
None => tracing::warn!("Can not find the group: {}", group_id),
|
||||||
Some((_, group)) => {
|
Some((_, group)) => {
|
||||||
let is_check = group.id == CHECK;
|
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) {
|
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())
|
group.add_row(row.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CheckboxGroupGenerator();
|
pub struct CheckboxGroupGenerator();
|
||||||
impl GroupGenerator for CheckboxGroupGenerator {
|
impl GroupsBuilder for CheckboxGroupGenerator {
|
||||||
type Context = CheckboxGroupContext;
|
type Context = CheckboxGroupContext;
|
||||||
type TypeOptionType = CheckboxTypeOption;
|
type TypeOptionType = CheckboxTypeOption;
|
||||||
|
|
||||||
fn generate_groups(
|
fn build(
|
||||||
_field: &Field,
|
_field: &Field,
|
||||||
_group_ctx: &Self::Context,
|
_context: &Self::Context,
|
||||||
_type_option: &Option<Self::TypeOptionType>,
|
_type_option: &Option<Self::TypeOptionType>,
|
||||||
) -> GeneratedGroupContext {
|
) -> GeneratedGroups {
|
||||||
let check_group = GeneratedGroupConfig {
|
let check_group = GeneratedGroupConfig {
|
||||||
group: Group::new(CHECK.to_string(), "".to_string()),
|
group: Group::new(CHECK.to_string(), "".to_string()),
|
||||||
filter_content: CHECK.to_string(),
|
filter_content: CHECK.to_string(),
|
||||||
@ -164,7 +169,7 @@ impl GroupGenerator for CheckboxGroupGenerator {
|
|||||||
filter_content: UNCHECK.to_string(),
|
filter_content: UNCHECK.to_string(),
|
||||||
};
|
};
|
||||||
|
|
||||||
GeneratedGroupContext {
|
GeneratedGroups {
|
||||||
no_status_group: None,
|
no_status_group: None,
|
||||||
group_configs: vec![check_group, uncheck_group],
|
group_configs: vec![check_group, uncheck_group],
|
||||||
}
|
}
|
||||||
|
@ -5,11 +5,13 @@ use collab_database::rows::{Cells, Row};
|
|||||||
|
|
||||||
use flowy_error::FlowyResult;
|
use flowy_error::FlowyResult;
|
||||||
|
|
||||||
use crate::entities::GroupChangesetPB;
|
use crate::entities::GroupChangesPB;
|
||||||
use crate::services::group::action::{
|
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
|
/// 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
|
/// 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 {
|
fn field_id(&self) -> &str {
|
||||||
&self.field_id
|
&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)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn apply_group_setting_changeset(
|
||||||
|
&mut self,
|
||||||
|
_changeset: GroupSettingChangeset,
|
||||||
|
) -> FlowyResult<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GroupController for DefaultGroupController {
|
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 will_create_row(&mut self, _cells: &mut Cells, _field: &Field, _group_id: &str) {}
|
||||||
|
|
||||||
fn did_create_row(&mut self, _row: &Row, _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::field::{MultiSelectTypeOption, SelectOptionCellDataParser};
|
||||||
use crate::services::group::action::GroupCustomize;
|
use crate::services::group::action::GroupCustomize;
|
||||||
use crate::services::group::controller::{
|
use crate::services::group::controller::{
|
||||||
GenericGroupController, GroupController, GroupGenerator, MoveGroupRowContext,
|
BaseGroupController, GroupController, GroupsBuilder, MoveGroupRowContext,
|
||||||
};
|
};
|
||||||
use crate::services::group::{
|
use crate::services::group::{
|
||||||
add_or_remove_select_option_row, generate_select_option_groups, make_no_status_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::fields::Field;
|
||||||
use collab_database::rows::{Cells, Row};
|
use collab_database::rows::{Cells, Row};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
@ -21,7 +22,7 @@ pub struct MultiSelectGroupConfiguration {
|
|||||||
|
|
||||||
pub type MultiSelectOptionGroupContext = GroupContext<MultiSelectGroupConfiguration>;
|
pub type MultiSelectOptionGroupContext = GroupContext<MultiSelectGroupConfiguration>;
|
||||||
// MultiSelect
|
// MultiSelect
|
||||||
pub type MultiSelectGroupController = GenericGroupController<
|
pub type MultiSelectGroupController = BaseGroupController<
|
||||||
MultiSelectGroupConfiguration,
|
MultiSelectGroupConfiguration,
|
||||||
MultiSelectTypeOption,
|
MultiSelectTypeOption,
|
||||||
MultiSelectGroupGenerator,
|
MultiSelectGroupGenerator,
|
||||||
@ -44,7 +45,7 @@ impl GroupCustomize for MultiSelectGroupController {
|
|||||||
cell_data: &Self::CellData,
|
cell_data: &Self::CellData,
|
||||||
) -> Vec<GroupRowsNotificationPB> {
|
) -> Vec<GroupRowsNotificationPB> {
|
||||||
let mut changesets = vec![];
|
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) {
|
if let Some(changeset) = add_or_remove_select_option_row(group, cell_data, row) {
|
||||||
changesets.push(changeset);
|
changesets.push(changeset);
|
||||||
}
|
}
|
||||||
@ -54,7 +55,7 @@ impl GroupCustomize for MultiSelectGroupController {
|
|||||||
|
|
||||||
fn delete_row(&mut self, row: &Row, cell_data: &Self::CellData) -> Vec<GroupRowsNotificationPB> {
|
fn delete_row(&mut self, row: &Row, cell_data: &Self::CellData) -> Vec<GroupRowsNotificationPB> {
|
||||||
let mut changesets = vec![];
|
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) {
|
if let Some(changeset) = remove_select_option_row(group, cell_data, row) {
|
||||||
changesets.push(changeset);
|
changesets.push(changeset);
|
||||||
}
|
}
|
||||||
@ -68,7 +69,7 @@ impl GroupCustomize for MultiSelectGroupController {
|
|||||||
mut context: MoveGroupRowContext,
|
mut context: MoveGroupRowContext,
|
||||||
) -> Vec<GroupRowsNotificationPB> {
|
) -> Vec<GroupRowsNotificationPB> {
|
||||||
let mut group_changeset = vec![];
|
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) {
|
if let Some(changeset) = move_group_row(group, &mut context) {
|
||||||
group_changeset.push(changeset);
|
group_changeset.push(changeset);
|
||||||
}
|
}
|
||||||
@ -78,8 +79,10 @@ impl GroupCustomize for MultiSelectGroupController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl GroupController 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) {
|
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),
|
None => tracing::warn!("Can not find the group: {}", group_id),
|
||||||
Some((_, group)) => {
|
Some((_, group)) => {
|
||||||
let cell = insert_select_option_cell(vec![group.id.clone()], field);
|
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) {
|
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())
|
group.add_row(row.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MultiSelectGroupGenerator();
|
pub struct MultiSelectGroupGenerator;
|
||||||
impl GroupGenerator for MultiSelectGroupGenerator {
|
impl GroupsBuilder for MultiSelectGroupGenerator {
|
||||||
type Context = MultiSelectOptionGroupContext;
|
type Context = MultiSelectOptionGroupContext;
|
||||||
type TypeOptionType = MultiSelectTypeOption;
|
type TypeOptionType = MultiSelectTypeOption;
|
||||||
|
|
||||||
fn generate_groups(
|
fn build(
|
||||||
field: &Field,
|
field: &Field,
|
||||||
_group_ctx: &Self::Context,
|
_context: &Self::Context,
|
||||||
type_option: &Option<Self::TypeOptionType>,
|
type_option: &Option<Self::TypeOptionType>,
|
||||||
) -> GeneratedGroupContext {
|
) -> GeneratedGroups {
|
||||||
let group_configs = match type_option {
|
let group_configs = match type_option {
|
||||||
None => vec![],
|
None => vec![],
|
||||||
Some(type_option) => generate_select_option_groups(&field.id, &type_option.options),
|
Some(type_option) => generate_select_option_groups(&field.id, &type_option.options),
|
||||||
};
|
};
|
||||||
|
|
||||||
GeneratedGroupContext {
|
GeneratedGroups {
|
||||||
no_status_group: Some(make_no_status_group(field)),
|
no_status_group: Some(make_no_status_group(field)),
|
||||||
group_configs,
|
group_configs,
|
||||||
}
|
}
|
||||||
|
@ -4,13 +4,14 @@ use crate::services::field::{SelectOptionCellDataParser, SingleSelectTypeOption}
|
|||||||
use crate::services::group::action::GroupCustomize;
|
use crate::services::group::action::GroupCustomize;
|
||||||
use collab_database::fields::Field;
|
use collab_database::fields::Field;
|
||||||
use collab_database::rows::{Cells, Row};
|
use collab_database::rows::{Cells, Row};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::services::group::controller::{
|
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::controller_impls::select_option_controller::util::*;
|
||||||
use crate::services::group::entities::GroupData;
|
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};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
@ -22,7 +23,7 @@ pub struct SingleSelectGroupConfiguration {
|
|||||||
pub type SingleSelectOptionGroupContext = GroupContext<SingleSelectGroupConfiguration>;
|
pub type SingleSelectOptionGroupContext = GroupContext<SingleSelectGroupConfiguration>;
|
||||||
|
|
||||||
// SingleSelect
|
// SingleSelect
|
||||||
pub type SingleSelectGroupController = GenericGroupController<
|
pub type SingleSelectGroupController = BaseGroupController<
|
||||||
SingleSelectGroupConfiguration,
|
SingleSelectGroupConfiguration,
|
||||||
SingleSelectTypeOption,
|
SingleSelectTypeOption,
|
||||||
SingleSelectGroupGenerator,
|
SingleSelectGroupGenerator,
|
||||||
@ -44,7 +45,7 @@ impl GroupCustomize for SingleSelectGroupController {
|
|||||||
cell_data: &Self::CellData,
|
cell_data: &Self::CellData,
|
||||||
) -> Vec<GroupRowsNotificationPB> {
|
) -> Vec<GroupRowsNotificationPB> {
|
||||||
let mut changesets = vec![];
|
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) {
|
if let Some(changeset) = add_or_remove_select_option_row(group, cell_data, row) {
|
||||||
changesets.push(changeset);
|
changesets.push(changeset);
|
||||||
}
|
}
|
||||||
@ -54,7 +55,7 @@ impl GroupCustomize for SingleSelectGroupController {
|
|||||||
|
|
||||||
fn delete_row(&mut self, row: &Row, cell_data: &Self::CellData) -> Vec<GroupRowsNotificationPB> {
|
fn delete_row(&mut self, row: &Row, cell_data: &Self::CellData) -> Vec<GroupRowsNotificationPB> {
|
||||||
let mut changesets = vec![];
|
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) {
|
if let Some(changeset) = remove_select_option_row(group, cell_data, row) {
|
||||||
changesets.push(changeset);
|
changesets.push(changeset);
|
||||||
}
|
}
|
||||||
@ -68,7 +69,7 @@ impl GroupCustomize for SingleSelectGroupController {
|
|||||||
mut context: MoveGroupRowContext,
|
mut context: MoveGroupRowContext,
|
||||||
) -> Vec<GroupRowsNotificationPB> {
|
) -> Vec<GroupRowsNotificationPB> {
|
||||||
let mut group_changeset = vec![];
|
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) {
|
if let Some(changeset) = move_group_row(group, &mut context) {
|
||||||
group_changeset.push(changeset);
|
group_changeset.push(changeset);
|
||||||
}
|
}
|
||||||
@ -78,8 +79,10 @@ impl GroupCustomize for SingleSelectGroupController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl GroupController 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) {
|
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 {
|
match group {
|
||||||
None => {},
|
None => {},
|
||||||
Some(group) => {
|
Some(group) => {
|
||||||
@ -89,27 +92,27 @@ impl GroupController for SingleSelectGroupController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn did_create_row(&mut self, row: &Row, group_id: &str) {
|
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())
|
group.add_row(row.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SingleSelectGroupGenerator();
|
pub struct SingleSelectGroupGenerator();
|
||||||
impl GroupGenerator for SingleSelectGroupGenerator {
|
impl GroupsBuilder for SingleSelectGroupGenerator {
|
||||||
type Context = SingleSelectOptionGroupContext;
|
type Context = SingleSelectOptionGroupContext;
|
||||||
type TypeOptionType = SingleSelectTypeOption;
|
type TypeOptionType = SingleSelectTypeOption;
|
||||||
fn generate_groups(
|
fn build(
|
||||||
field: &Field,
|
field: &Field,
|
||||||
_group_ctx: &Self::Context,
|
_context: &Self::Context,
|
||||||
type_option: &Option<Self::TypeOptionType>,
|
type_option: &Option<Self::TypeOptionType>,
|
||||||
) -> GeneratedGroupContext {
|
) -> GeneratedGroups {
|
||||||
let group_configs = match type_option {
|
let group_configs = match type_option {
|
||||||
None => vec![],
|
None => vec![],
|
||||||
Some(type_option) => generate_select_option_groups(&field.id, &type_option.options),
|
Some(type_option) => generate_select_option_groups(&field.id, &type_option.options),
|
||||||
};
|
};
|
||||||
|
|
||||||
GeneratedGroupContext {
|
GeneratedGroups {
|
||||||
no_status_group: Some(make_no_status_group(field)),
|
no_status_group: Some(make_no_status_group(field)),
|
||||||
group_configs,
|
group_configs,
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use collab_database::fields::Field;
|
use collab_database::fields::Field;
|
||||||
use collab_database::rows::{new_cell_builder, Cell, Cells, Row};
|
use collab_database::rows::{new_cell_builder, Cell, Cells, Row};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use flowy_error::FlowyResult;
|
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::action::GroupCustomize;
|
||||||
use crate::services::group::configuration::GroupContext;
|
use crate::services::group::configuration::GroupContext;
|
||||||
use crate::services::group::controller::{
|
use crate::services::group::controller::{
|
||||||
GenericGroupController, GroupController, GroupGenerator, MoveGroupRowContext,
|
BaseGroupController, GroupController, GroupsBuilder, MoveGroupRowContext,
|
||||||
};
|
};
|
||||||
use crate::services::group::{
|
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)]
|
#[derive(Default, Serialize, Deserialize)]
|
||||||
@ -23,12 +24,8 @@ pub struct URLGroupConfiguration {
|
|||||||
pub hide_empty: bool,
|
pub hide_empty: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type URLGroupController = GenericGroupController<
|
pub type URLGroupController =
|
||||||
URLGroupConfiguration,
|
BaseGroupController<URLGroupConfiguration, URLTypeOption, URLGroupGenerator, URLCellDataParser>;
|
||||||
URLTypeOption,
|
|
||||||
URLGroupGenerator,
|
|
||||||
URLCellDataParser,
|
|
||||||
>;
|
|
||||||
|
|
||||||
pub type URLGroupContext = GroupContext<URLGroupConfiguration>;
|
pub type URLGroupContext = GroupContext<URLGroupConfiguration>;
|
||||||
|
|
||||||
@ -55,17 +52,17 @@ impl GroupCustomize for URLGroupController {
|
|||||||
) -> FlowyResult<(Option<InsertedGroupPB>, Option<GroupPB>)> {
|
) -> FlowyResult<(Option<InsertedGroupPB>, Option<GroupPB>)> {
|
||||||
// Just return if the group with this url already exists
|
// Just return if the group with this url already exists
|
||||||
let mut inserted_group = None;
|
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 cell_data: URLCellData = _cell_data.clone().into();
|
||||||
let group = make_group_from_url_cell(&cell_data);
|
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));
|
new_group.group.rows.push(RowPB::from(row));
|
||||||
inserted_group = Some(new_group);
|
inserted_group = Some(new_group);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete the old url group if there are no rows in that group
|
// Delete the old url group if there are no rows in that group
|
||||||
let deleted_group = match _old_cell_data
|
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,
|
None => None,
|
||||||
Some((_, group)) => {
|
Some((_, group)) => {
|
||||||
@ -80,7 +77,7 @@ impl GroupCustomize for URLGroupController {
|
|||||||
let deleted_group = match deleted_group {
|
let deleted_group = match deleted_group {
|
||||||
None => None,
|
None => None,
|
||||||
Some(group) => {
|
Some(group) => {
|
||||||
self.group_ctx.delete_group(&group.id)?;
|
self.context.delete_group(&group.id)?;
|
||||||
Some(GroupPB::from(group.clone()))
|
Some(GroupPB::from(group.clone()))
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -94,7 +91,7 @@ impl GroupCustomize for URLGroupController {
|
|||||||
cell_data: &Self::CellData,
|
cell_data: &Self::CellData,
|
||||||
) -> Vec<GroupRowsNotificationPB> {
|
) -> Vec<GroupRowsNotificationPB> {
|
||||||
let mut changesets = vec![];
|
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 mut changeset = GroupRowsNotificationPB::new(group.id.clone());
|
||||||
if group.id == cell_data.content {
|
if group.id == cell_data.content {
|
||||||
if !group.contains_row(&row.id) {
|
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> {
|
fn delete_row(&mut self, row: &Row, _cell_data: &Self::CellData) -> Vec<GroupRowsNotificationPB> {
|
||||||
let mut changesets = vec![];
|
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());
|
let mut changeset = GroupRowsNotificationPB::new(group.id.clone());
|
||||||
if group.contains_row(&row.id) {
|
if group.contains_row(&row.id) {
|
||||||
group.remove_row(&row.id);
|
group.remove_row(&row.id);
|
||||||
@ -137,7 +134,7 @@ impl GroupCustomize for URLGroupController {
|
|||||||
mut context: MoveGroupRowContext,
|
mut context: MoveGroupRowContext,
|
||||||
) -> Vec<GroupRowsNotificationPB> {
|
) -> Vec<GroupRowsNotificationPB> {
|
||||||
let mut group_changeset = vec![];
|
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) {
|
if let Some(changeset) = move_group_row(group, &mut context) {
|
||||||
group_changeset.push(changeset);
|
group_changeset.push(changeset);
|
||||||
}
|
}
|
||||||
@ -151,14 +148,14 @@ impl GroupCustomize for URLGroupController {
|
|||||||
_cell_data: &Self::CellData,
|
_cell_data: &Self::CellData,
|
||||||
) -> Option<GroupPB> {
|
) -> Option<GroupPB> {
|
||||||
let mut deleted_group = None;
|
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 {
|
if group.rows.len() == 1 {
|
||||||
deleted_group = Some(GroupPB::from(group.clone()));
|
deleted_group = Some(GroupPB::from(group.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if deleted_group.is_some() {
|
if deleted_group.is_some() {
|
||||||
let _ = self
|
let _ = self
|
||||||
.group_ctx
|
.context
|
||||||
.delete_group(&deleted_group.as_ref().unwrap().group_id);
|
.delete_group(&deleted_group.as_ref().unwrap().group_id);
|
||||||
}
|
}
|
||||||
deleted_group
|
deleted_group
|
||||||
@ -166,8 +163,10 @@ impl GroupCustomize for URLGroupController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl GroupController 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) {
|
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),
|
None => tracing::warn!("Can not find the group: {}", group_id),
|
||||||
Some((_, group)) => {
|
Some((_, group)) => {
|
||||||
let cell = insert_url_cell(group.id.clone(), field);
|
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) {
|
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())
|
group.add_row(row.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct URLGroupGenerator();
|
pub struct URLGroupGenerator();
|
||||||
impl GroupGenerator for URLGroupGenerator {
|
impl GroupsBuilder for URLGroupGenerator {
|
||||||
type Context = URLGroupContext;
|
type Context = URLGroupContext;
|
||||||
type TypeOptionType = URLTypeOption;
|
type TypeOptionType = URLTypeOption;
|
||||||
|
|
||||||
fn generate_groups(
|
fn build(
|
||||||
field: &Field,
|
field: &Field,
|
||||||
group_ctx: &Self::Context,
|
context: &Self::Context,
|
||||||
_type_option: &Option<Self::TypeOptionType>,
|
_type_option: &Option<Self::TypeOptionType>,
|
||||||
) -> GeneratedGroupContext {
|
) -> GeneratedGroups {
|
||||||
// Read all the cells for the grouping field
|
// 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
|
// Generate the groups
|
||||||
let group_configs = cells
|
let group_configs = cells
|
||||||
@ -208,7 +207,7 @@ impl GroupGenerator for URLGroupGenerator {
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let no_status_group = Some(make_no_status_group(field));
|
let no_status_group = Some(make_no_status_group(field));
|
||||||
GeneratedGroupContext {
|
GeneratedGroups {
|
||||||
no_status_group,
|
no_status_group,
|
||||||
group_configs,
|
group_configs,
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,16 @@ pub struct GroupSetting {
|
|||||||
pub content: String,
|
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 {
|
impl GroupSetting {
|
||||||
pub fn new(field_id: String, field_type: i64, content: String) -> Self {
|
pub fn new(field_id: String, field_type: i64, content: String) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -75,7 +85,7 @@ impl From<GroupSetting> for GroupSettingMap {
|
|||||||
pub struct Group {
|
pub struct Group {
|
||||||
pub id: String,
|
pub id: String,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
#[serde(default = "GROUP_REV_VISIBILITY")]
|
#[serde(default = "GROUP_VISIBILITY")]
|
||||||
pub visible: bool,
|
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 {
|
impl Group {
|
||||||
pub fn new(id: String, name: String) -> Self {
|
pub fn new(id: String, name: String) -> Self {
|
||||||
|
@ -42,7 +42,7 @@ where
|
|||||||
W: GroupSettingWriter,
|
W: GroupSettingWriter,
|
||||||
{
|
{
|
||||||
let grouping_field_type = FieldType::from(grouping_field.field_type);
|
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 mut group_controller: Box<dyn GroupController>;
|
||||||
let configuration_reader = Arc::new(setting_reader);
|
let configuration_reader = Arc::new(setting_reader);
|
||||||
|
@ -82,8 +82,10 @@ impl SortController {
|
|||||||
|
|
||||||
pub async fn did_receive_row_changed(&self, row_id: RowId) {
|
pub async fn did_receive_row_changed(&self, row_id: RowId) {
|
||||||
let task_type = SortEvent::RowDidChanged(row_id);
|
let task_type = SortEvent::RowDidChanged(row_id);
|
||||||
|
if !self.sorts.is_empty() {
|
||||||
self.gen_task(task_type, QualityOfService::Background).await;
|
self.gen_task(task_type, QualityOfService::Background).await;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// #[tracing::instrument(name = "process_sort_task", level = "trace", skip_all, err)]
|
// #[tracing::instrument(name = "process_sort_task", level = "trace", skip_all, err)]
|
||||||
pub async fn process(&mut self, predicate: &str) -> FlowyResult<()> {
|
pub async fn process(&mut self, predicate: &str) -> FlowyResult<()> {
|
||||||
@ -169,7 +171,7 @@ impl SortController {
|
|||||||
.await;
|
.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 futures::TryFutureExt;
|
||||||
use tokio::sync::broadcast::Receiver;
|
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::database_view::DatabaseViewChanged;
|
||||||
use flowy_database2::services::filter::FilterType;
|
use flowy_database2::services::filter::FilterType;
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ pub enum FilterScript {
|
|||||||
changed: Option<FilterRowChanged>,
|
changed: Option<FilterRowChanged>,
|
||||||
},
|
},
|
||||||
InsertFilter {
|
InsertFilter {
|
||||||
payload: AlterFilterPayloadPB,
|
payload: UpdateFilterPayloadPB,
|
||||||
},
|
},
|
||||||
CreateTextFilter {
|
CreateTextFilter {
|
||||||
condition: TextFilterConditionPB,
|
condition: TextFilterConditionPB,
|
||||||
@ -151,7 +151,7 @@ impl DatabaseFilterTest {
|
|||||||
content
|
content
|
||||||
};
|
};
|
||||||
let payload =
|
let payload =
|
||||||
AlterFilterPayloadPB::new(
|
UpdateFilterPayloadPB::new(
|
||||||
& self.view_id(),
|
& self.view_id(),
|
||||||
&field, text_filter);
|
&field, text_filter);
|
||||||
self.insert_filter(payload).await;
|
self.insert_filter(payload).await;
|
||||||
@ -159,7 +159,7 @@ impl DatabaseFilterTest {
|
|||||||
FilterScript::UpdateTextFilter { filter, condition, content, changed} => {
|
FilterScript::UpdateTextFilter { filter, condition, content, changed} => {
|
||||||
self.recv = Some(self.editor.subscribe_view_changed(&self.view_id()).await.unwrap());
|
self.recv = Some(self.editor.subscribe_view_changed(&self.view_id()).await.unwrap());
|
||||||
self.assert_future_changed(changed).await;
|
self.assert_future_changed(changed).await;
|
||||||
let params = AlterFilterParams {
|
let params = UpdateFilterParams {
|
||||||
view_id: self.view_id(),
|
view_id: self.view_id(),
|
||||||
field_id: filter.field_id,
|
field_id: filter.field_id,
|
||||||
filter_id: Some(filter.id),
|
filter_id: Some(filter.id),
|
||||||
@ -178,7 +178,7 @@ impl DatabaseFilterTest {
|
|||||||
content
|
content
|
||||||
};
|
};
|
||||||
let payload =
|
let payload =
|
||||||
AlterFilterPayloadPB::new(
|
UpdateFilterPayloadPB::new(
|
||||||
&self.view_id(),
|
&self.view_id(),
|
||||||
&field, number_filter);
|
&field, number_filter);
|
||||||
self.insert_filter(payload).await;
|
self.insert_filter(payload).await;
|
||||||
@ -191,7 +191,7 @@ impl DatabaseFilterTest {
|
|||||||
condition
|
condition
|
||||||
};
|
};
|
||||||
let payload =
|
let payload =
|
||||||
AlterFilterPayloadPB::new(& self.view_id(), &field, checkbox_filter);
|
UpdateFilterPayloadPB::new(& self.view_id(), &field, checkbox_filter);
|
||||||
self.insert_filter(payload).await;
|
self.insert_filter(payload).await;
|
||||||
}
|
}
|
||||||
FilterScript::CreateDateFilter { condition, start, end, timestamp, changed} => {
|
FilterScript::CreateDateFilter { condition, start, end, timestamp, changed} => {
|
||||||
@ -206,7 +206,7 @@ impl DatabaseFilterTest {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let payload =
|
let payload =
|
||||||
AlterFilterPayloadPB::new(&self.view_id(), &field, date_filter);
|
UpdateFilterPayloadPB::new(&self.view_id(), &field, date_filter);
|
||||||
self.insert_filter(payload).await;
|
self.insert_filter(payload).await;
|
||||||
}
|
}
|
||||||
FilterScript::CreateMultiSelectFilter { condition, option_ids} => {
|
FilterScript::CreateMultiSelectFilter { condition, option_ids} => {
|
||||||
@ -214,7 +214,7 @@ impl DatabaseFilterTest {
|
|||||||
let field = self.get_first_field(FieldType::MultiSelect);
|
let field = self.get_first_field(FieldType::MultiSelect);
|
||||||
let filter = SelectOptionFilterPB { condition, option_ids };
|
let filter = SelectOptionFilterPB { condition, option_ids };
|
||||||
let payload =
|
let payload =
|
||||||
AlterFilterPayloadPB::new(&self.view_id(), &field, filter);
|
UpdateFilterPayloadPB::new(&self.view_id(), &field, filter);
|
||||||
self.insert_filter(payload).await;
|
self.insert_filter(payload).await;
|
||||||
}
|
}
|
||||||
FilterScript::CreateSingleSelectFilter { condition, option_ids, changed} => {
|
FilterScript::CreateSingleSelectFilter { condition, option_ids, changed} => {
|
||||||
@ -223,7 +223,7 @@ impl DatabaseFilterTest {
|
|||||||
let field = self.get_first_field(FieldType::SingleSelect);
|
let field = self.get_first_field(FieldType::SingleSelect);
|
||||||
let filter = SelectOptionFilterPB { condition, option_ids };
|
let filter = SelectOptionFilterPB { condition, option_ids };
|
||||||
let payload =
|
let payload =
|
||||||
AlterFilterPayloadPB::new(& self.view_id(), &field, filter);
|
UpdateFilterPayloadPB::new(& self.view_id(), &field, filter);
|
||||||
self.insert_filter(payload).await;
|
self.insert_filter(payload).await;
|
||||||
}
|
}
|
||||||
FilterScript::CreateChecklistFilter { condition,changed} => {
|
FilterScript::CreateChecklistFilter { condition,changed} => {
|
||||||
@ -233,7 +233,7 @@ impl DatabaseFilterTest {
|
|||||||
// let type_option = self.get_checklist_type_option(&field_rev.id);
|
// let type_option = self.get_checklist_type_option(&field_rev.id);
|
||||||
let filter = ChecklistFilterPB { condition };
|
let filter = ChecklistFilterPB { condition };
|
||||||
let payload =
|
let payload =
|
||||||
AlterFilterPayloadPB::new(& self.view_id(), &field, filter);
|
UpdateFilterPayloadPB::new(& self.view_id(), &field, filter);
|
||||||
self.insert_filter(payload).await;
|
self.insert_filter(payload).await;
|
||||||
}
|
}
|
||||||
FilterScript::AssertFilterCount { count } => {
|
FilterScript::AssertFilterCount { count } => {
|
||||||
@ -289,8 +289,8 @@ impl DatabaseFilterTest {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn insert_filter(&self, payload: AlterFilterPayloadPB) {
|
async fn insert_filter(&self, payload: UpdateFilterPayloadPB) {
|
||||||
let params: AlterFilterParams = payload.try_into().unwrap();
|
let params: UpdateFilterParams = payload.try_into().unwrap();
|
||||||
let _ = self.editor.create_or_update_filter(params).await.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::FilterScript::*;
|
||||||
use crate::database::filter_test::script::*;
|
use crate::database::filter_test::script::*;
|
||||||
use flowy_database2::entities::{
|
use flowy_database2::entities::{
|
||||||
AlterFilterPayloadPB, FieldType, TextFilterConditionPB, TextFilterPB,
|
FieldType, TextFilterConditionPB, TextFilterPB, UpdateFilterPayloadPB,
|
||||||
};
|
};
|
||||||
use flowy_database2::services::filter::FilterType;
|
use flowy_database2::services::filter::FilterType;
|
||||||
|
|
||||||
@ -195,7 +195,7 @@ async fn grid_filter_delete_test() {
|
|||||||
condition: TextFilterConditionPB::TextIsEmpty,
|
condition: TextFilterConditionPB::TextIsEmpty,
|
||||||
content: "".to_string(),
|
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![
|
let scripts = vec![
|
||||||
InsertFilter { payload },
|
InsertFilter { payload },
|
||||||
AssertFilterCount { count: 1 },
|
AssertFilterCount { count: 1 },
|
||||||
|
@ -8,7 +8,7 @@ use collab_database::rows::RowId;
|
|||||||
use futures::stream::StreamExt;
|
use futures::stream::StreamExt;
|
||||||
use tokio::sync::broadcast::Receiver;
|
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::cell::stringify_cell_data;
|
||||||
use flowy_database2::services::database_view::DatabaseViewChanged;
|
use flowy_database2::services::database_view::DatabaseViewChanged;
|
||||||
use flowy_database2::services::sort::{Sort, SortCondition, SortType};
|
use flowy_database2::services::sort::{Sort, SortCondition, SortType};
|
||||||
@ -72,7 +72,7 @@ impl DatabaseSortTest {
|
|||||||
.await
|
.await
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
);
|
);
|
||||||
let params = AlterSortParams {
|
let params = UpdateSortParams {
|
||||||
view_id: self.view_id.clone(),
|
view_id: self.view_id.clone(),
|
||||||
field_id: field.id.clone(),
|
field_id: field.id.clone(),
|
||||||
sort_id: None,
|
sort_id: None,
|
||||||
|
@ -13,7 +13,7 @@ const MESSAGE: &str = "msg";
|
|||||||
const LOG_MODULE_PATH: &str = "log.module_path";
|
const LOG_MODULE_PATH: &str = "log.module_path";
|
||||||
const LOG_TARGET_PATH: &str = "log.target";
|
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];
|
const IGNORE_FIELDS: [&str; 2] = [LOG_MODULE_PATH, LOG_TARGET_PATH];
|
||||||
|
|
||||||
pub struct FlowyFormattingLayer<W: MakeWriter + 'static> {
|
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,
|
&self,
|
||||||
map_serializer: &mut impl SerializeMap<Error = serde_json::Error>,
|
map_serializer: &mut impl SerializeMap<Error = serde_json::Error>,
|
||||||
message: &str,
|
message: &str,
|
||||||
@ -45,12 +45,13 @@ impl<W: MakeWriter + 'static> FlowyFormattingLayer<W> {
|
|||||||
&self,
|
&self,
|
||||||
span: &SpanRef<S>,
|
span: &SpanRef<S>,
|
||||||
ty: Type,
|
ty: Type,
|
||||||
|
ctx: &Context<'_, S>,
|
||||||
) -> Result<Vec<u8>, std::io::Error> {
|
) -> Result<Vec<u8>, std::io::Error> {
|
||||||
let mut buffer = Vec::new();
|
let mut buffer = Vec::new();
|
||||||
let mut serializer = serde_json::Serializer::new(&mut buffer);
|
let mut serializer = serde_json::Serializer::new(&mut buffer);
|
||||||
let mut map_serializer = serializer.serialize_map(None)?;
|
let mut map_serializer = serializer.serialize_map(None)?;
|
||||||
let message = format_span_context(span, ty);
|
let message = format_span_context(span, ty, ctx);
|
||||||
self.serialize_flowy_folder_fields(&mut map_serializer, &message, span.metadata().level())?;
|
self.serialize_fields(&mut map_serializer, &message, span.metadata().level())?;
|
||||||
if self.with_target {
|
if self.with_target {
|
||||||
map_serializer.serialize_entry("target", &span.metadata().target())?;
|
map_serializer.serialize_entry("target", &span.metadata().target())?;
|
||||||
}
|
}
|
||||||
@ -61,7 +62,7 @@ impl<W: MakeWriter + 'static> FlowyFormattingLayer<W> {
|
|||||||
let extensions = span.extensions();
|
let extensions = span.extensions();
|
||||||
if let Some(visitor) = extensions.get::<JsonStorage>() {
|
if let Some(visitor) = extensions.get::<JsonStorage>() {
|
||||||
for (key, value) in visitor.values() {
|
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)?;
|
map_serializer.serialize_entry(key, value)?;
|
||||||
} else {
|
} else {
|
||||||
tracing::debug!(
|
tracing::debug!(
|
||||||
@ -93,9 +94,9 @@ pub enum Type {
|
|||||||
impl fmt::Display for Type {
|
impl fmt::Display for Type {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
let repr = match self {
|
let repr = match self {
|
||||||
Type::EnterSpan => "START",
|
Type::EnterSpan => "Start",
|
||||||
Type::ExitSpan => "END",
|
Type::ExitSpan => "End",
|
||||||
Type::Event => "EVENT",
|
Type::Event => "Event",
|
||||||
};
|
};
|
||||||
write!(f, "{}", repr)
|
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>>(
|
fn format_span_context<S: Subscriber + for<'a> tracing_subscriber::registry::LookupSpan<'a>>(
|
||||||
span: &SpanRef<S>,
|
span: &SpanRef<S>,
|
||||||
ty: Type,
|
ty: Type,
|
||||||
|
context: &Context<'_, S>,
|
||||||
) -> String {
|
) -> 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>>(
|
fn format_event_message<S: Subscriber + for<'a> tracing_subscriber::registry::LookupSpan<'a>>(
|
||||||
current_span: &Option<SpanRef<S>>,
|
current_span: &Option<SpanRef<S>>,
|
||||||
event: &Event,
|
event: &Event,
|
||||||
event_visitor: &JsonStorage<'_>,
|
event_visitor: &JsonStorage<'_>,
|
||||||
|
context: &Context<'_, S>,
|
||||||
) -> String {
|
) -> String {
|
||||||
// Extract the "message" field, if provided. Fallback to the target, if missing.
|
// Extract the "message" field, if provided. Fallback to the target, if missing.
|
||||||
let mut message = event_visitor
|
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
|
// If the event is in the context of a span, prepend the span name to the
|
||||||
// message.
|
// message.
|
||||||
if let Some(span) = ¤t_span {
|
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
|
message
|
||||||
@ -154,12 +172,8 @@ where
|
|||||||
let mut serializer = serde_json::Serializer::new(&mut buffer);
|
let mut serializer = serde_json::Serializer::new(&mut buffer);
|
||||||
let mut map_serializer = serializer.serialize_map(None)?;
|
let mut map_serializer = serializer.serialize_map(None)?;
|
||||||
|
|
||||||
let message = format_event_message(¤t_span, event, &event_visitor);
|
let message = format_event_message(¤t_span, event, &event_visitor, &ctx);
|
||||||
self.serialize_flowy_folder_fields(
|
self.serialize_fields(&mut map_serializer, &message, event.metadata().level())?;
|
||||||
&mut map_serializer,
|
|
||||||
&message,
|
|
||||||
event.metadata().level(),
|
|
||||||
)?;
|
|
||||||
// Additional metadata useful for debugging
|
// Additional metadata useful for debugging
|
||||||
// They should be nested under `src` (see https://github.com/trentm/node-bunyan#src )
|
// They should be nested under `src` (see https://github.com/trentm/node-bunyan#src )
|
||||||
// but `tracing` does not support nested values yet
|
// 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
|
// Add all the other fields associated with the event, expect the message we
|
||||||
// already used.
|
// already used.
|
||||||
for (key, value) in event_visitor.values().iter().filter(|(&key, _)| {
|
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)?;
|
map_serializer.serialize_entry(key, value)?;
|
||||||
}
|
}
|
||||||
@ -184,7 +198,7 @@ where
|
|||||||
let extensions = span.extensions();
|
let extensions = span.extensions();
|
||||||
if let Some(visitor) = extensions.get::<JsonStorage>() {
|
if let Some(visitor) = extensions.get::<JsonStorage>() {
|
||||||
for (key, value) in visitor.values() {
|
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)?;
|
map_serializer.serialize_entry(key, value)?;
|
||||||
} else {
|
} else {
|
||||||
tracing::debug!(
|
tracing::debug!(
|
||||||
@ -207,14 +221,14 @@ where
|
|||||||
|
|
||||||
fn new_span(&self, _attrs: &Attributes, id: &Id, ctx: Context<'_, S>) {
|
fn new_span(&self, _attrs: &Attributes, id: &Id, ctx: Context<'_, S>) {
|
||||||
let span = ctx.span(id).expect("Span not found, this is a bug");
|
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);
|
let _ = self.emit(serialized);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_close(&self, id: Id, ctx: Context<'_, S>) {
|
fn on_close(&self, id: Id, ctx: Context<'_, S>) {
|
||||||
let span = ctx.span(&id).expect("Span not found, this is a bug");
|
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);
|
let _ = self.emit(serialized);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,16 +42,14 @@ impl Builder {
|
|||||||
|
|
||||||
let (non_blocking, guard) = tracing_appender::non_blocking(self.file_appender);
|
let (non_blocking, guard) = tracing_appender::non_blocking(self.file_appender);
|
||||||
let subscriber = tracing_subscriber::fmt()
|
let subscriber = tracing_subscriber::fmt()
|
||||||
// .with_span_events(FmtSpan::NEW | FmtSpan::CLOSE)
|
.with_ansi(true)
|
||||||
.with_ansi(false)
|
|
||||||
.with_target(false)
|
.with_target(false)
|
||||||
.with_max_level(tracing::Level::TRACE)
|
.with_max_level(tracing::Level::TRACE)
|
||||||
.with_writer(std::io::stderr)
|
.with_writer(std::io::stderr)
|
||||||
.with_thread_ids(true)
|
.with_thread_ids(true)
|
||||||
// .with_writer(non_blocking)
|
|
||||||
.json()
|
.json()
|
||||||
.with_current_span(true)
|
// .with_current_span(true)
|
||||||
.with_span_list(true)
|
// .with_span_list(true)
|
||||||
.compact()
|
.compact()
|
||||||
.finish()
|
.finish()
|
||||||
.with(env_filter)
|
.with(env_filter)
|
||||||
@ -59,14 +57,6 @@ impl Builder {
|
|||||||
.with(FlowyFormattingLayer::new(std::io::stdout))
|
.with(FlowyFormattingLayer::new(std::io::stdout))
|
||||||
.with(FlowyFormattingLayer::new(non_blocking));
|
.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))?;
|
|
||||||
// }
|
|
||||||
|
|
||||||
set_global_default(subscriber).map_err(|e| format!("{:?}", e))?;
|
set_global_default(subscriber).map_err(|e| format!("{:?}", e))?;
|
||||||
LogTracer::builder()
|
LogTracer::builder()
|
||||||
.with_max_level(LevelFilter::Trace)
|
.with_max_level(LevelFilter::Trace)
|
||||||
|
Loading…
Reference in New Issue
Block a user