mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
test: add database event tests (#2744)
* chore: add tests * test: add tests * test: add tests
This commit is contained in:
parent
0f9f5251f2
commit
e9be37a961
@ -47,7 +47,7 @@ class DateCellDataPersistence implements CellDataPersistence<DateCellData> {
|
|||||||
@override
|
@override
|
||||||
Future<Option<FlowyError>> save(DateCellData data) {
|
Future<Option<FlowyError>> save(DateCellData data) {
|
||||||
final payload = DateChangesetPB.create()
|
final payload = DateChangesetPB.create()
|
||||||
..cellPath = _makeCellPath(cellContext);
|
..cellId = _makeCellPath(cellContext);
|
||||||
if (data.dateTime != null) {
|
if (data.dateTime != null) {
|
||||||
final date = (data.dateTime!.millisecondsSinceEpoch ~/ 1000).toString();
|
final date = (data.dateTime!.millisecondsSinceEpoch ~/ 1000).toString();
|
||||||
payload.date = date;
|
payload.date = date;
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
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-database2/group.pb.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
@ -10,12 +9,10 @@ class GroupBackendService {
|
|||||||
|
|
||||||
Future<Either<Unit, FlowyError>> groupByField({
|
Future<Either<Unit, FlowyError>> groupByField({
|
||||||
required String fieldId,
|
required String fieldId,
|
||||||
required FieldType fieldType,
|
|
||||||
}) {
|
}) {
|
||||||
final payload = GroupByFieldPayloadPB.create()
|
final payload = GroupByFieldPayloadPB.create()
|
||||||
..viewId = viewId
|
..viewId = viewId
|
||||||
..fieldId = fieldId
|
..fieldId = fieldId;
|
||||||
..fieldType = fieldType;
|
|
||||||
|
|
||||||
return DatabaseEventSetGroupByField(payload).send();
|
return DatabaseEventSetGroupByField(payload).send();
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,6 @@ class DatabaseGroupBloc extends Bloc<DatabaseGroupEvent, DatabaseGroupState> {
|
|||||||
setGroupByField: (String fieldId, FieldType fieldType) async {
|
setGroupByField: (String fieldId, FieldType fieldType) async {
|
||||||
final result = await _groupBackendSvc.groupByField(
|
final result = await _groupBackendSvc.groupByField(
|
||||||
fieldId: fieldId,
|
fieldId: fieldId,
|
||||||
fieldType: fieldType,
|
|
||||||
);
|
);
|
||||||
result.fold((l) => null, (err) => Log.error(err));
|
result.fold((l) => null, (err) => Log.error(err));
|
||||||
},
|
},
|
||||||
|
@ -230,7 +230,7 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
|||||||
for (final group in updatedGroups) {
|
for (final group in updatedGroups) {
|
||||||
final columnController =
|
final columnController =
|
||||||
boardController.getGroupController(group.groupId);
|
boardController.getGroupController(group.groupId);
|
||||||
columnController?.updateGroupName(group.desc);
|
columnController?.updateGroupName(group.groupName);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -285,7 +285,7 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
|||||||
AppFlowyGroupData initializeGroupData(GroupPB group) {
|
AppFlowyGroupData initializeGroupData(GroupPB group) {
|
||||||
return AppFlowyGroupData(
|
return AppFlowyGroupData(
|
||||||
id: group.groupId,
|
id: group.groupId,
|
||||||
name: group.desc,
|
name: group.groupName,
|
||||||
items: _buildGroupItems(group),
|
items: _buildGroupItems(group),
|
||||||
customData: GroupData(
|
customData: GroupData(
|
||||||
group: group,
|
group: group,
|
||||||
|
@ -285,10 +285,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: csslib
|
name: csslib
|
||||||
sha256: "831883fb353c8bdc1d71979e5b342c7d88acfbc643113c14ae51e2442ea0f20f"
|
sha256: "706b5707578e0c1b4b7550f64078f0a0f19dec3f50a178ffae7006b0a9ca58fb"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.17.3"
|
version: "1.0.0"
|
||||||
dart_style:
|
dart_style:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -648,10 +648,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: html
|
name: html
|
||||||
sha256: "58e3491f7bf0b6a4ea5110c0c688877460d1a6366731155c4a4580e7ded773e8"
|
sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.15.3"
|
version: "0.15.4"
|
||||||
http:
|
http:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -48,8 +48,9 @@ void main() {
|
|||||||
);
|
);
|
||||||
final expectedGroupName = "No ${multiSelectField.name}";
|
final expectedGroupName = "No ${multiSelectField.name}";
|
||||||
assert(
|
assert(
|
||||||
boardBloc.groupControllers.values.first.group.desc == expectedGroupName,
|
boardBloc.groupControllers.values.first.group.groupName ==
|
||||||
"Expected $expectedGroupName, but receive ${boardBloc.groupControllers.values.first.group.desc}",
|
expectedGroupName,
|
||||||
|
"Expected $expectedGroupName, but receive ${boardBloc.groupControllers.values.first.group.groupName}",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -101,8 +102,8 @@ void main() {
|
|||||||
|
|
||||||
final groups =
|
final groups =
|
||||||
boardBloc.groupControllers.values.map((e) => e.group).toList();
|
boardBloc.groupControllers.values.map((e) => e.group).toList();
|
||||||
assert(groups[0].desc == "No ${multiSelectField.name}");
|
assert(groups[0].groupName == "No ${multiSelectField.name}");
|
||||||
assert(groups[1].desc == "B");
|
assert(groups[1].groupName == "B");
|
||||||
assert(groups[2].desc == "A");
|
assert(groups[2].groupName == "A");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
20
frontend/appflowy_tauri/src-tauri/Cargo.lock
generated
20
frontend/appflowy_tauri/src-tauri/Cargo.lock
generated
@ -99,7 +99,7 @@ checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "appflowy-integrate"
|
name = "appflowy-integrate"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"collab",
|
"collab",
|
||||||
@ -1024,7 +1024,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "collab"
|
name = "collab"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bytes",
|
"bytes",
|
||||||
@ -1042,7 +1042,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "collab-client-ws"
|
name = "collab-client-ws"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"collab-sync",
|
"collab-sync",
|
||||||
@ -1060,7 +1060,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "collab-database"
|
name = "collab-database"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@ -1086,7 +1086,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "collab-derive"
|
name = "collab-derive"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -1098,7 +1098,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "collab-document"
|
name = "collab-document"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"collab",
|
"collab",
|
||||||
@ -1115,7 +1115,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "collab-folder"
|
name = "collab-folder"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"chrono",
|
"chrono",
|
||||||
@ -1135,7 +1135,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "collab-persistence"
|
name = "collab-persistence"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"chrono",
|
"chrono",
|
||||||
@ -1155,7 +1155,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "collab-plugins"
|
name = "collab-plugins"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@ -1186,7 +1186,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "collab-sync"
|
name = "collab-sync"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"collab",
|
"collab",
|
||||||
|
@ -34,12 +34,12 @@ default = ["custom-protocol"]
|
|||||||
custom-protocol = ["tauri/custom-protocol"]
|
custom-protocol = ["tauri/custom-protocol"]
|
||||||
|
|
||||||
[patch.crates-io]
|
[patch.crates-io]
|
||||||
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "87f534" }
|
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c382b1" }
|
||||||
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "87f534" }
|
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c382b1" }
|
||||||
collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "87f534" }
|
collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c382b1" }
|
||||||
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "87f534" }
|
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c382b1" }
|
||||||
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "87f534" }
|
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c382b1" }
|
||||||
appflowy-integrate = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "87f534" }
|
appflowy-integrate = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c382b1" }
|
||||||
|
|
||||||
#collab = { path = "../../AppFlowy-Collab/collab" }
|
#collab = { path = "../../AppFlowy-Collab/collab" }
|
||||||
#collab-folder = { path = "../../AppFlowy-Collab/collab-folder" }
|
#collab-folder = { path = "../../AppFlowy-Collab/collab-folder" }
|
||||||
|
@ -24,7 +24,7 @@ export class DateCellDataPersistence extends CellDataPersistence<CalendarData> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
save(data: CalendarData): Promise<Result<void, FlowyError>> {
|
save(data: CalendarData): Promise<Result<void, FlowyError>> {
|
||||||
const payload = DateChangesetPB.fromObject({ cell_path: _makeCellPath(this.cellIdentifier) });
|
const payload = DateChangesetPB.fromObject({ cell_id: _makeCellId(this.cellIdentifier) });
|
||||||
payload.date = ((data.date.getTime() / 1000) | 0).toString();
|
payload.date = ((data.date.getTime() / 1000) | 0).toString();
|
||||||
if (data.time !== undefined) {
|
if (data.time !== undefined) {
|
||||||
payload.time = data.time;
|
payload.time = data.time;
|
||||||
@ -34,7 +34,7 @@ export class DateCellDataPersistence extends CellDataPersistence<CalendarData> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function _makeCellPath(cellIdentifier: CellIdentifier): CellIdPB {
|
function _makeCellId(cellIdentifier: CellIdentifier): CellIdPB {
|
||||||
return CellIdPB.fromObject({
|
return CellIdPB.fromObject({
|
||||||
view_id: cellIdentifier.viewId,
|
view_id: cellIdentifier.viewId,
|
||||||
field_id: cellIdentifier.fieldId,
|
field_id: cellIdentifier.fieldId,
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { DatabaseNotification, FlowyError, GroupPB, GroupRowsNotificationPB, RowPB } from "@/services/backend";
|
import { DatabaseNotification, FlowyError, GroupPB, GroupRowsNotificationPB, RowPB } from '@/services/backend';
|
||||||
import { ChangeNotifier } from "$app/utils/change_notifier";
|
import { ChangeNotifier } from '$app/utils/change_notifier';
|
||||||
import { None, Ok, Option, Result, Some } from "ts-results";
|
import { None, Ok, Option, Result, Some } from 'ts-results';
|
||||||
import { DatabaseNotificationObserver } from "../notifications/observer";
|
import { DatabaseNotificationObserver } from '../notifications/observer';
|
||||||
import { Log } from "$app/utils/log";
|
import { Log } from '$app/utils/log';
|
||||||
import { DatabaseBackendService } from "../database_bd_svc";
|
import { DatabaseBackendService } from '../database_bd_svc';
|
||||||
|
|
||||||
export type GroupDataCallbacks = {
|
export type GroupDataCallbacks = {
|
||||||
onRemoveRow: (groupId: string, rowId: string) => void;
|
onRemoveRow: (groupId: string, rowId: string) => void;
|
||||||
@ -30,7 +30,7 @@ export class DatabaseGroupController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get name() {
|
get name() {
|
||||||
return this.group.desc;
|
return this.group.group_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateGroup = (group: GroupPB) => {
|
updateGroup = (group: GroupPB) => {
|
||||||
@ -83,7 +83,7 @@ export class DatabaseGroupController {
|
|||||||
} else {
|
} else {
|
||||||
Log.error(result.val);
|
Log.error(result.val);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -111,8 +111,7 @@ class GroupDataObserver {
|
|||||||
private notifier?: ChangeNotifier<Result<GroupRowsNotificationPB, FlowyError>>;
|
private notifier?: ChangeNotifier<Result<GroupRowsNotificationPB, FlowyError>>;
|
||||||
private listener?: DatabaseNotificationObserver;
|
private listener?: DatabaseNotificationObserver;
|
||||||
|
|
||||||
constructor(public readonly groupId: string) {
|
constructor(public readonly groupId: string) {}
|
||||||
}
|
|
||||||
|
|
||||||
subscribe = async (callbacks: { onRowsChanged: GroupRowsSubscribeCallback }) => {
|
subscribe = async (callbacks: { onRowsChanged: GroupRowsSubscribeCallback }) => {
|
||||||
this.notifier = new ChangeNotifier();
|
this.notifier = new ChangeNotifier();
|
||||||
@ -132,7 +131,7 @@ class GroupDataObserver {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
await this.listener.start();
|
await this.listener.start();
|
||||||
};
|
};
|
||||||
|
20
frontend/rust-lib/Cargo.lock
generated
20
frontend/rust-lib/Cargo.lock
generated
@ -85,7 +85,7 @@ checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "appflowy-integrate"
|
name = "appflowy-integrate"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"collab",
|
"collab",
|
||||||
@ -887,7 +887,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "collab"
|
name = "collab"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bytes",
|
"bytes",
|
||||||
@ -905,7 +905,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "collab-client-ws"
|
name = "collab-client-ws"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"collab-sync",
|
"collab-sync",
|
||||||
@ -923,7 +923,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "collab-database"
|
name = "collab-database"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@ -949,7 +949,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "collab-derive"
|
name = "collab-derive"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -961,7 +961,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "collab-document"
|
name = "collab-document"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"collab",
|
"collab",
|
||||||
@ -978,7 +978,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "collab-folder"
|
name = "collab-folder"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"chrono",
|
"chrono",
|
||||||
@ -998,7 +998,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "collab-persistence"
|
name = "collab-persistence"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"chrono",
|
"chrono",
|
||||||
@ -1018,7 +1018,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "collab-plugins"
|
name = "collab-plugins"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@ -1049,7 +1049,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "collab-sync"
|
name = "collab-sync"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=87f534#87f53452241a65275f5b2878ba57dff2a0e2b838"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=c382b1#c382b1ceb44e5615175e3b01f2bf0d49f6c669e3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"collab",
|
"collab",
|
||||||
|
@ -33,11 +33,11 @@ opt-level = 3
|
|||||||
incremental = false
|
incremental = false
|
||||||
|
|
||||||
[patch.crates-io]
|
[patch.crates-io]
|
||||||
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "87f534" }
|
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c382b1" }
|
||||||
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "87f534" }
|
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c382b1" }
|
||||||
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "87f534" }
|
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c382b1" }
|
||||||
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "87f534" }
|
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c382b1" }
|
||||||
appflowy-integrate = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "87f534" }
|
appflowy-integrate = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "c382b1" }
|
||||||
|
|
||||||
#collab = { path = "../AppFlowy-Collab/collab" }
|
#collab = { path = "../AppFlowy-Collab/collab" }
|
||||||
#collab-folder = { path = "../AppFlowy-Collab/collab-folder" }
|
#collab-folder = { path = "../AppFlowy-Collab/collab-folder" }
|
||||||
|
@ -80,17 +80,11 @@ impl std::convert::From<CalendarLayout> for CalendarLayoutPB {
|
|||||||
pub struct CalendarEventRequestPB {
|
pub struct CalendarEventRequestPB {
|
||||||
#[pb(index = 1)]
|
#[pb(index = 1)]
|
||||||
pub view_id: String,
|
pub view_id: String,
|
||||||
|
|
||||||
// Currently, requesting the events within the specified month
|
|
||||||
// is not supported
|
|
||||||
#[pb(index = 2)]
|
|
||||||
pub month: String,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct CalendarEventRequestParams {
|
pub struct CalendarEventRequestParams {
|
||||||
pub view_id: String,
|
pub view_id: String,
|
||||||
pub month: String,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryInto<CalendarEventRequestParams> for CalendarEventRequestPB {
|
impl TryInto<CalendarEventRequestParams> for CalendarEventRequestPB {
|
||||||
@ -98,10 +92,7 @@ impl TryInto<CalendarEventRequestParams> for CalendarEventRequestPB {
|
|||||||
|
|
||||||
fn try_into(self) -> Result<CalendarEventRequestParams, Self::Error> {
|
fn try_into(self) -> Result<CalendarEventRequestParams, Self::Error> {
|
||||||
let view_id = NotEmptyStr::parse(self.view_id).map_err(|_| ErrorCode::ViewIdIsInvalid)?;
|
let view_id = NotEmptyStr::parse(self.view_id).map_err(|_| ErrorCode::ViewIdIsInvalid)?;
|
||||||
Ok(CalendarEventRequestParams {
|
Ok(CalendarEventRequestParams { view_id: view_id.0 })
|
||||||
view_id: view_id.0,
|
|
||||||
month: self.month,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,11 +135,13 @@ impl TryInto<MoveRowParams> for MoveRowPayloadPB {
|
|||||||
|
|
||||||
fn try_into(self) -> Result<MoveRowParams, Self::Error> {
|
fn try_into(self) -> Result<MoveRowParams, Self::Error> {
|
||||||
let view_id = NotEmptyStr::parse(self.view_id).map_err(|_| ErrorCode::DatabaseViewIdIsEmpty)?;
|
let view_id = NotEmptyStr::parse(self.view_id).map_err(|_| ErrorCode::DatabaseViewIdIsEmpty)?;
|
||||||
|
let from_row_id = NotEmptyStr::parse(self.from_row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?;
|
||||||
|
let to_row_id = NotEmptyStr::parse(self.to_row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?;
|
||||||
|
|
||||||
Ok(MoveRowParams {
|
Ok(MoveRowParams {
|
||||||
view_id: view_id.0,
|
view_id: view_id.0,
|
||||||
from_row_id: RowId::from(self.from_row_id),
|
from_row_id: RowId::from(from_row_id.0),
|
||||||
to_row_id: RowId::from(self.to_row_id),
|
to_row_id: RowId::from(to_row_id.0),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ pub struct GroupPB {
|
|||||||
pub group_id: String,
|
pub group_id: String,
|
||||||
|
|
||||||
#[pb(index = 3)]
|
#[pb(index = 3)]
|
||||||
pub desc: String,
|
pub group_name: String,
|
||||||
|
|
||||||
#[pb(index = 4)]
|
#[pb(index = 4)]
|
||||||
pub rows: Vec<RowPB>,
|
pub rows: Vec<RowPB>,
|
||||||
@ -93,7 +93,7 @@ impl std::convert::From<GroupData> for GroupPB {
|
|||||||
Self {
|
Self {
|
||||||
field_id: group_data.field_id,
|
field_id: group_data.field_id,
|
||||||
group_id: group_data.id,
|
group_id: group_data.id,
|
||||||
desc: group_data.name,
|
group_name: group_data.name,
|
||||||
rows: group_data.rows.into_iter().map(RowPB::from).collect(),
|
rows: group_data.rows.into_iter().map(RowPB::from).collect(),
|
||||||
is_default: group_data.is_default,
|
is_default: group_data.is_default,
|
||||||
is_visible: group_data.is_visible,
|
is_visible: group_data.is_visible,
|
||||||
@ -108,9 +108,6 @@ pub struct GroupByFieldPayloadPB {
|
|||||||
|
|
||||||
#[pb(index = 2)]
|
#[pb(index = 2)]
|
||||||
pub view_id: String,
|
pub view_id: String,
|
||||||
|
|
||||||
#[pb(index = 3)]
|
|
||||||
pub field_type: FieldType,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryInto<GroupByFieldParams> for GroupByFieldPayloadPB {
|
impl TryInto<GroupByFieldParams> for GroupByFieldPayloadPB {
|
||||||
@ -124,18 +121,13 @@ impl TryInto<GroupByFieldParams> for GroupByFieldPayloadPB {
|
|||||||
.map_err(|_| ErrorCode::ViewIdIsInvalid)?
|
.map_err(|_| ErrorCode::ViewIdIsInvalid)?
|
||||||
.0;
|
.0;
|
||||||
|
|
||||||
Ok(GroupByFieldParams {
|
Ok(GroupByFieldParams { field_id, view_id })
|
||||||
field_id,
|
|
||||||
view_id,
|
|
||||||
field_type: self.field_type,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct GroupByFieldParams {
|
pub struct GroupByFieldParams {
|
||||||
pub field_id: String,
|
pub field_id: String,
|
||||||
pub view_id: String,
|
pub view_id: String,
|
||||||
pub field_type: FieldType,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DeleteGroupParams {
|
pub struct DeleteGroupParams {
|
||||||
|
@ -158,6 +158,7 @@ impl TryInto<RowIdParams> for RowIdPB {
|
|||||||
|
|
||||||
fn try_into(self) -> Result<RowIdParams, Self::Error> {
|
fn try_into(self) -> Result<RowIdParams, Self::Error> {
|
||||||
let view_id = NotEmptyStr::parse(self.view_id).map_err(|_| ErrorCode::DatabaseIdIsEmpty)?;
|
let view_id = NotEmptyStr::parse(self.view_id).map_err(|_| ErrorCode::DatabaseIdIsEmpty)?;
|
||||||
|
let row_id = NotEmptyStr::parse(self.row_id).map_err(|_| ErrorCode::RowIdIsEmpty)?;
|
||||||
let group_id = match self.group_id {
|
let group_id = match self.group_id {
|
||||||
Some(group_id) => Some(
|
Some(group_id) => Some(
|
||||||
NotEmptyStr::parse(group_id)
|
NotEmptyStr::parse(group_id)
|
||||||
@ -169,7 +170,7 @@ impl TryInto<RowIdParams> for RowIdPB {
|
|||||||
|
|
||||||
Ok(RowIdParams {
|
Ok(RowIdParams {
|
||||||
view_id: view_id.0,
|
view_id: view_id.0,
|
||||||
row_id: RowId::from(self.row_id),
|
row_id: RowId::from(row_id.0),
|
||||||
group_id,
|
group_id,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
|
use collab_database::rows::RowId;
|
||||||
|
|
||||||
|
use flowy_derive::ProtoBuf;
|
||||||
|
use flowy_error::{ErrorCode, FlowyError};
|
||||||
|
|
||||||
use crate::entities::parser::NotEmptyStr;
|
use crate::entities::parser::NotEmptyStr;
|
||||||
use crate::entities::SelectOptionPB;
|
use crate::entities::SelectOptionPB;
|
||||||
use crate::services::field::checklist_type_option::ChecklistCellData;
|
use crate::services::field::checklist_type_option::ChecklistCellData;
|
||||||
|
|
||||||
use crate::services::field::SelectOption;
|
use crate::services::field::SelectOption;
|
||||||
use collab_database::rows::RowId;
|
|
||||||
use flowy_derive::ProtoBuf;
|
|
||||||
use flowy_error::{ErrorCode, FlowyError};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, ProtoBuf)]
|
#[derive(Debug, Clone, Default, ProtoBuf)]
|
||||||
pub struct ChecklistCellDataPB {
|
pub struct ChecklistCellDataPB {
|
||||||
@ -16,7 +17,7 @@ pub struct ChecklistCellDataPB {
|
|||||||
pub selected_options: Vec<SelectOptionPB>,
|
pub selected_options: Vec<SelectOptionPB>,
|
||||||
|
|
||||||
#[pb(index = 3)]
|
#[pb(index = 3)]
|
||||||
pub(crate) percentage: f64,
|
pub percentage: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ChecklistCellData> for ChecklistCellDataPB {
|
impl From<ChecklistCellData> for ChecklistCellDataPB {
|
||||||
|
@ -25,7 +25,7 @@ pub struct DateCellDataPB {
|
|||||||
#[derive(Clone, Debug, Default, ProtoBuf)]
|
#[derive(Clone, Debug, Default, ProtoBuf)]
|
||||||
pub struct DateChangesetPB {
|
pub struct DateChangesetPB {
|
||||||
#[pb(index = 1)]
|
#[pb(index = 1)]
|
||||||
pub cell_path: CellIdPB,
|
pub cell_id: CellIdPB,
|
||||||
|
|
||||||
#[pb(index = 2, one_of)]
|
#[pb(index = 2, one_of)]
|
||||||
pub date: Option<String>,
|
pub date: Option<String>,
|
||||||
|
@ -294,7 +294,9 @@ pub(crate) async fn get_row_handler(
|
|||||||
) -> DataResult<OptionalRowPB, FlowyError> {
|
) -> DataResult<OptionalRowPB, FlowyError> {
|
||||||
let params: RowIdParams = data.into_inner().try_into()?;
|
let params: RowIdParams = data.into_inner().try_into()?;
|
||||||
let database_editor = manager.get_database_with_view_id(¶ms.view_id).await?;
|
let database_editor = manager.get_database_with_view_id(¶ms.view_id).await?;
|
||||||
let row = database_editor.get_row(¶ms.row_id).map(RowPB::from);
|
let row = database_editor
|
||||||
|
.get_row(¶ms.view_id, ¶ms.row_id)
|
||||||
|
.map(RowPB::from);
|
||||||
data_result_ok(OptionalRowPB { row })
|
data_result_ok(OptionalRowPB { row })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -525,7 +527,7 @@ pub(crate) async fn update_date_cell_handler(
|
|||||||
manager: AFPluginState<Arc<DatabaseManager2>>,
|
manager: AFPluginState<Arc<DatabaseManager2>>,
|
||||||
) -> Result<(), FlowyError> {
|
) -> Result<(), FlowyError> {
|
||||||
let data = data.into_inner();
|
let data = data.into_inner();
|
||||||
let cell_id: CellIdParams = data.cell_path.try_into()?;
|
let cell_id: CellIdParams = data.cell_id.try_into()?;
|
||||||
let cell_changeset = DateCellChangeset {
|
let cell_changeset = DateCellChangeset {
|
||||||
date: data.date,
|
date: data.date,
|
||||||
time: data.time,
|
time: data.time,
|
||||||
|
@ -496,8 +496,12 @@ impl DatabaseEditor {
|
|||||||
Ok(view_editor.v_get_rows().await)
|
Ok(view_editor.v_get_rows().await)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_row(&self, row_id: &RowId) -> Option<Row> {
|
pub fn get_row(&self, view_id: &str, row_id: &RowId) -> Option<Row> {
|
||||||
self.database.lock().get_row(row_id)
|
if self.database.lock().views.is_row_exist(view_id, row_id) {
|
||||||
|
return None;
|
||||||
|
} else {
|
||||||
|
self.database.lock().get_row(row_id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_row(&self, row_id: &RowId) {
|
pub async fn delete_row(&self, row_id: &RowId) {
|
||||||
@ -832,6 +836,11 @@ impl DatabaseEditor {
|
|||||||
from_group: &str,
|
from_group: &str,
|
||||||
to_group: &str,
|
to_group: &str,
|
||||||
) -> FlowyResult<()> {
|
) -> FlowyResult<()> {
|
||||||
|
// Do nothing if the group is the same
|
||||||
|
if from_group == to_group {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
let view = self.database_views.get_view_editor(view_id).await?;
|
let view = self.database_views.get_view_editor(view_id).await?;
|
||||||
view.v_move_group(from_group, to_group).await?;
|
view.v_move_group(from_group, to_group).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -375,6 +375,7 @@ impl DatabaseViewEditor {
|
|||||||
.as_ref()?
|
.as_ref()?
|
||||||
.groups()
|
.groups()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
.filter(|group| group.is_visible)
|
||||||
.map(|group_data| GroupPB::from(group_data.clone()))
|
.map(|group_data| GroupPB::from(group_data.clone()))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
tracing::trace!("Number of groups: {}", groups.len());
|
tracing::trace!("Number of groups: {}", groups.len());
|
||||||
|
@ -351,15 +351,21 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn update_group(&mut self, group_changeset: GroupChangeset) -> FlowyResult<()> {
|
pub(crate) fn update_group(&mut self, group_changeset: GroupChangeset) -> FlowyResult<()> {
|
||||||
self.mut_group(&group_changeset.group_id, |group| {
|
let update_group = self.mut_group(&group_changeset.group_id, |group| {
|
||||||
if let Some(visible) = group_changeset.visible {
|
if let Some(visible) = group_changeset.visible {
|
||||||
group.visible = visible;
|
group.visible = visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(name) = &group_changeset.name {
|
if let Some(name) = &group_changeset.name {
|
||||||
group.name = name.clone();
|
group.name = name.clone();
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
if let Some(group) = update_group {
|
||||||
|
self.group_by_id.get_mut(&group.id).map(|group_data| {
|
||||||
|
group_data.name = group.name.clone();
|
||||||
|
group_data.is_visible = group.visible;
|
||||||
|
});
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -370,6 +376,11 @@ where
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `mut_configuration_fn`: mutate the [GroupSetting] and return whether the [GroupSetting] is
|
||||||
|
/// changed. If the [GroupSetting] is changed, the [GroupSetting] will be saved to the storage.
|
||||||
|
///
|
||||||
fn mut_configuration(
|
fn mut_configuration(
|
||||||
&mut self,
|
&mut self,
|
||||||
mut_configuration_fn: impl FnOnce(&mut GroupSetting) -> bool,
|
mut_configuration_fn: impl FnOnce(&mut GroupSetting) -> bool,
|
||||||
@ -392,7 +403,12 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mut_group(&mut self, group_id: &str, mut_groups_fn: impl Fn(&mut Group)) -> FlowyResult<()> {
|
fn mut_group(
|
||||||
|
&mut self,
|
||||||
|
group_id: &str,
|
||||||
|
mut_groups_fn: impl Fn(&mut Group),
|
||||||
|
) -> FlowyResult<Option<Group>> {
|
||||||
|
let mut updated_group = None;
|
||||||
self.mut_configuration(|configuration| {
|
self.mut_configuration(|configuration| {
|
||||||
match configuration
|
match configuration
|
||||||
.groups
|
.groups
|
||||||
@ -402,10 +418,12 @@ where
|
|||||||
None => false,
|
None => false,
|
||||||
Some(group) => {
|
Some(group) => {
|
||||||
mut_groups_fn(group);
|
mut_groups_fn(group);
|
||||||
|
updated_group = Some(group.clone());
|
||||||
true
|
true
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
})
|
})?;
|
||||||
|
Ok(updated_group)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use collab_database::database::gen_row_id;
|
use collab_database::database::gen_row_id;
|
||||||
use collab_database::fields::Field;
|
use collab_database::fields::Field;
|
||||||
use collab_database::rows::{CreateRowParams, RowId};
|
use collab_database::rows::{CreateRowParams, RowId};
|
||||||
|
|
||||||
use flowy_database2::entities::{FieldType, GroupPB, RowPB};
|
use flowy_database2::entities::{FieldType, GroupPB, RowPB};
|
||||||
use flowy_database2::services::cell::{
|
use flowy_database2::services::cell::{
|
||||||
delete_select_option_cell, insert_select_option_cell, insert_url_cell,
|
delete_select_option_cell, insert_select_option_cell, insert_url_cell,
|
||||||
@ -233,7 +234,7 @@ impl DatabaseGroupTest {
|
|||||||
} => {
|
} => {
|
||||||
let group = self.group_at_index(group_index).await;
|
let group = self.group_at_index(group_index).await;
|
||||||
assert_eq!(group.group_id, group_pb.group_id);
|
assert_eq!(group.group_id, group_pb.group_id);
|
||||||
assert_eq!(group.desc, group_pb.desc);
|
assert_eq!(group.group_name, group_pb.group_name);
|
||||||
},
|
},
|
||||||
GroupScript::UpdateSingleSelectSelectOption { inserted_options } => {
|
GroupScript::UpdateSingleSelectSelectOption { inserted_options } => {
|
||||||
self
|
self
|
||||||
|
@ -463,7 +463,7 @@ async fn group_insert_single_select_option_test() {
|
|||||||
];
|
];
|
||||||
test.run_scripts(scripts).await;
|
test.run_scripts(scripts).await;
|
||||||
let new_group = test.group_at_index(1).await;
|
let new_group = test.group_at_index(1).await;
|
||||||
assert_eq!(new_group.desc, new_option_name);
|
assert_eq!(new_group.group_name, new_option_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use bytes::Bytes;
|
||||||
|
use std::convert::TryFrom;
|
||||||
use std::env::temp_dir;
|
use std::env::temp_dir;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
@ -132,6 +134,49 @@ impl FlowyCoreTest {
|
|||||||
.parse::<flowy_folder2::entities::ViewPB>()
|
.parse::<flowy_folder2::entities::ViewPB>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn create_board(&self, parent_id: &str, name: String, initial_data: Vec<u8>) -> ViewPB {
|
||||||
|
let payload = CreateViewPayloadPB {
|
||||||
|
parent_view_id: parent_id.to_string(),
|
||||||
|
name,
|
||||||
|
desc: "".to_string(),
|
||||||
|
thumbnail: None,
|
||||||
|
layout: ViewLayoutPB::Board,
|
||||||
|
initial_data,
|
||||||
|
meta: Default::default(),
|
||||||
|
set_as_current: true,
|
||||||
|
};
|
||||||
|
EventBuilder::new(self.clone())
|
||||||
|
.event(flowy_folder2::event_map::FolderEvent::CreateView)
|
||||||
|
.payload(payload)
|
||||||
|
.async_send()
|
||||||
|
.await
|
||||||
|
.parse::<flowy_folder2::entities::ViewPB>()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn create_calendar(
|
||||||
|
&self,
|
||||||
|
parent_id: &str,
|
||||||
|
name: String,
|
||||||
|
initial_data: Vec<u8>,
|
||||||
|
) -> ViewPB {
|
||||||
|
let payload = CreateViewPayloadPB {
|
||||||
|
parent_view_id: parent_id.to_string(),
|
||||||
|
name,
|
||||||
|
desc: "".to_string(),
|
||||||
|
thumbnail: None,
|
||||||
|
layout: ViewLayoutPB::Calendar,
|
||||||
|
initial_data,
|
||||||
|
meta: Default::default(),
|
||||||
|
set_as_current: true,
|
||||||
|
};
|
||||||
|
EventBuilder::new(self.clone())
|
||||||
|
.event(flowy_folder2::event_map::FolderEvent::CreateView)
|
||||||
|
.payload(payload)
|
||||||
|
.async_send()
|
||||||
|
.await
|
||||||
|
.parse::<flowy_folder2::entities::ViewPB>()
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn get_database(&self, view_id: &str) -> DatabasePB {
|
pub async fn get_database(&self, view_id: &str) -> DatabasePB {
|
||||||
EventBuilder::new(self.clone())
|
EventBuilder::new(self.clone())
|
||||||
.event(flowy_database2::event_map::DatabaseEvent::GetDatabase)
|
.event(flowy_database2::event_map::DatabaseEvent::GetDatabase)
|
||||||
@ -238,7 +283,20 @@ impl FlowyCoreTest {
|
|||||||
.parse::<RowPB>()
|
.parse::<RowPB>()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_row(&self, view_id: &str, row_id: &str) -> RowPB {
|
pub async fn delete_row(&self, view_id: &str, row_id: &str) -> Option<FlowyError> {
|
||||||
|
EventBuilder::new(self.clone())
|
||||||
|
.event(flowy_database2::event_map::DatabaseEvent::DeleteRow)
|
||||||
|
.payload(RowIdPB {
|
||||||
|
view_id: view_id.to_string(),
|
||||||
|
row_id: row_id.to_string(),
|
||||||
|
group_id: None,
|
||||||
|
})
|
||||||
|
.async_send()
|
||||||
|
.await
|
||||||
|
.error()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_row(&self, view_id: &str, row_id: &str) -> OptionalRowPB {
|
||||||
EventBuilder::new(self.clone())
|
EventBuilder::new(self.clone())
|
||||||
.event(flowy_database2::event_map::DatabaseEvent::GetRow)
|
.event(flowy_database2::event_map::DatabaseEvent::GetRow)
|
||||||
.payload(RowIdPB {
|
.payload(RowIdPB {
|
||||||
@ -248,7 +306,7 @@ impl FlowyCoreTest {
|
|||||||
})
|
})
|
||||||
.async_send()
|
.async_send()
|
||||||
.await
|
.await
|
||||||
.parse::<RowPB>()
|
.parse::<OptionalRowPB>()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn duplicate_row(&self, view_id: &str, row_id: &str) -> Option<FlowyError> {
|
pub async fn duplicate_row(&self, view_id: &str, row_id: &str) -> Option<FlowyError> {
|
||||||
@ -264,6 +322,19 @@ impl FlowyCoreTest {
|
|||||||
.error()
|
.error()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn move_row(&self, view_id: &str, row_id: &str, to_row_id: &str) -> Option<FlowyError> {
|
||||||
|
EventBuilder::new(self.clone())
|
||||||
|
.event(flowy_database2::event_map::DatabaseEvent::MoveRow)
|
||||||
|
.payload(MoveRowPayloadPB {
|
||||||
|
view_id: view_id.to_string(),
|
||||||
|
from_row_id: row_id.to_string(),
|
||||||
|
to_row_id: to_row_id.to_string(),
|
||||||
|
})
|
||||||
|
.async_send()
|
||||||
|
.await
|
||||||
|
.error()
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn update_cell(&self, changeset: CellChangesetPB) -> Option<FlowyError> {
|
pub async fn update_cell(&self, changeset: CellChangesetPB) -> Option<FlowyError> {
|
||||||
EventBuilder::new(self.clone())
|
EventBuilder::new(self.clone())
|
||||||
.event(flowy_database2::event_map::DatabaseEvent::UpdateCell)
|
.event(flowy_database2::event_map::DatabaseEvent::UpdateCell)
|
||||||
@ -273,6 +344,15 @@ impl FlowyCoreTest {
|
|||||||
.error()
|
.error()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn update_date_cell(&self, changeset: DateChangesetPB) -> Option<FlowyError> {
|
||||||
|
EventBuilder::new(self.clone())
|
||||||
|
.event(flowy_database2::event_map::DatabaseEvent::UpdateDateCell)
|
||||||
|
.payload(changeset)
|
||||||
|
.async_send()
|
||||||
|
.await
|
||||||
|
.error()
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn get_cell(&self, view_id: &str, row_id: &str, field_id: &str) -> CellPB {
|
pub async fn get_cell(&self, view_id: &str, row_id: &str, field_id: &str) -> CellPB {
|
||||||
EventBuilder::new(self.clone())
|
EventBuilder::new(self.clone())
|
||||||
.event(flowy_database2::event_map::DatabaseEvent::GetCell)
|
.event(flowy_database2::event_map::DatabaseEvent::GetCell)
|
||||||
@ -286,6 +366,41 @@ impl FlowyCoreTest {
|
|||||||
.parse::<CellPB>()
|
.parse::<CellPB>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_date_cell(&self, view_id: &str, row_id: &str, field_id: &str) -> DateCellDataPB {
|
||||||
|
let cell = self.get_cell(view_id, row_id, field_id).await;
|
||||||
|
DateCellDataPB::try_from(Bytes::from(cell.data)).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_checklist_cell(
|
||||||
|
&self,
|
||||||
|
view_id: &str,
|
||||||
|
field_id: &str,
|
||||||
|
row_id: &str,
|
||||||
|
) -> ChecklistCellDataPB {
|
||||||
|
EventBuilder::new(self.clone())
|
||||||
|
.event(flowy_database2::event_map::DatabaseEvent::GetChecklistCellData)
|
||||||
|
.payload(CellIdPB {
|
||||||
|
view_id: view_id.to_string(),
|
||||||
|
row_id: row_id.to_string(),
|
||||||
|
field_id: field_id.to_string(),
|
||||||
|
})
|
||||||
|
.async_send()
|
||||||
|
.await
|
||||||
|
.parse::<ChecklistCellDataPB>()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn update_checklist_cell(
|
||||||
|
&self,
|
||||||
|
changeset: ChecklistCellDataChangesetPB,
|
||||||
|
) -> Option<FlowyError> {
|
||||||
|
EventBuilder::new(self.clone())
|
||||||
|
.event(flowy_database2::event_map::DatabaseEvent::UpdateChecklistCell)
|
||||||
|
.payload(changeset)
|
||||||
|
.async_send()
|
||||||
|
.await
|
||||||
|
.error()
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn insert_option(
|
pub async fn insert_option(
|
||||||
&self,
|
&self,
|
||||||
view_id: &str,
|
view_id: &str,
|
||||||
@ -317,6 +432,84 @@ impl FlowyCoreTest {
|
|||||||
.error()
|
.error()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_groups(&self, view_id: &str) -> Vec<GroupPB> {
|
||||||
|
EventBuilder::new(self.clone())
|
||||||
|
.event(flowy_database2::event_map::DatabaseEvent::GetGroups)
|
||||||
|
.payload(DatabaseViewIdPB {
|
||||||
|
value: view_id.to_string(),
|
||||||
|
})
|
||||||
|
.async_send()
|
||||||
|
.await
|
||||||
|
.parse::<RepeatedGroupPB>()
|
||||||
|
.items
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn move_group(&self, view_id: &str, from_id: &str, to_id: &str) -> Option<FlowyError> {
|
||||||
|
EventBuilder::new(self.clone())
|
||||||
|
.event(flowy_database2::event_map::DatabaseEvent::MoveGroup)
|
||||||
|
.payload(MoveGroupPayloadPB {
|
||||||
|
view_id: view_id.to_string(),
|
||||||
|
from_group_id: from_id.to_string(),
|
||||||
|
to_group_id: to_id.to_string(),
|
||||||
|
})
|
||||||
|
.async_send()
|
||||||
|
.await
|
||||||
|
.error()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn set_group_by_field(&self, view_id: &str, field_id: &str) -> Option<FlowyError> {
|
||||||
|
EventBuilder::new(self.clone())
|
||||||
|
.event(flowy_database2::event_map::DatabaseEvent::SetGroupByField)
|
||||||
|
.payload(GroupByFieldPayloadPB {
|
||||||
|
field_id: field_id.to_string(),
|
||||||
|
view_id: view_id.to_string(),
|
||||||
|
})
|
||||||
|
.async_send()
|
||||||
|
.await
|
||||||
|
.error()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn update_group(
|
||||||
|
&self,
|
||||||
|
view_id: &str,
|
||||||
|
group_id: &str,
|
||||||
|
name: Option<String>,
|
||||||
|
visible: Option<bool>,
|
||||||
|
) -> Option<FlowyError> {
|
||||||
|
EventBuilder::new(self.clone())
|
||||||
|
.event(flowy_database2::event_map::DatabaseEvent::UpdateGroup)
|
||||||
|
.payload(UpdateGroupPB {
|
||||||
|
view_id: view_id.to_string(),
|
||||||
|
group_id: group_id.to_string(),
|
||||||
|
name,
|
||||||
|
visible,
|
||||||
|
})
|
||||||
|
.async_send()
|
||||||
|
.await
|
||||||
|
.error()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn update_setting(&self, changeset: DatabaseSettingChangesetPB) -> Option<FlowyError> {
|
||||||
|
EventBuilder::new(self.clone())
|
||||||
|
.event(flowy_database2::event_map::DatabaseEvent::UpdateDatabaseSetting)
|
||||||
|
.payload(changeset)
|
||||||
|
.async_send()
|
||||||
|
.await
|
||||||
|
.error()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_all_calendar_events(&self, view_id: &str) -> Vec<CalendarEventPB> {
|
||||||
|
EventBuilder::new(self.clone())
|
||||||
|
.event(flowy_database2::event_map::DatabaseEvent::GetAllCalendarEvents)
|
||||||
|
.payload(CalendarEventRequestPB {
|
||||||
|
view_id: view_id.to_string(),
|
||||||
|
})
|
||||||
|
.async_send()
|
||||||
|
.await
|
||||||
|
.parse::<RepeatedCalendarEventPB>()
|
||||||
|
.items
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn get_view(&self, view_id: &str) -> ViewPB {
|
pub async fn get_view(&self, view_id: &str) -> ViewPB {
|
||||||
EventBuilder::new(self.clone())
|
EventBuilder::new(self.clone())
|
||||||
.event(flowy_folder2::event_map::FolderEvent::ReadView)
|
.event(flowy_folder2::event_map::FolderEvent::ReadView)
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
|
use lib_infra::util::timestamp;
|
||||||
|
|
||||||
use flowy_database2::entities::{
|
use flowy_database2::entities::{
|
||||||
CellChangesetPB, DatabaseLayoutPB, DatabaseViewIdPB, FieldType, SelectOptionCellDataPB,
|
CellChangesetPB, CellIdPB, ChecklistCellDataChangesetPB, DatabaseLayoutPB,
|
||||||
|
DatabaseSettingChangesetPB, DatabaseViewIdPB, DateChangesetPB, FieldType, SelectOptionCellDataPB,
|
||||||
};
|
};
|
||||||
use flowy_test::event_builder::EventBuilder;
|
use flowy_test::event_builder::EventBuilder;
|
||||||
use flowy_test::FlowyCoreTest;
|
use flowy_test::FlowyCoreTest;
|
||||||
@ -93,6 +95,7 @@ async fn delete_field_event_test() {
|
|||||||
assert_eq!(fields.len(), 2);
|
assert_eq!(fields.len(), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The primary field is not allowed to be deleted.
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn delete_primary_field_event_test() {
|
async fn delete_primary_field_event_test() {
|
||||||
let test = FlowyCoreTest::new_with_user().await;
|
let test = FlowyCoreTest::new_with_user().await;
|
||||||
@ -162,6 +165,7 @@ async fn duplicate_field_event_test() {
|
|||||||
assert_eq!(fields.len(), 4);
|
assert_eq!(fields.len(), 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The primary field is not allowed to be duplicated. So this test should return an error.
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn duplicate_primary_field_test() {
|
async fn duplicate_primary_field_test() {
|
||||||
let test = FlowyCoreTest::new_with_user().await;
|
let test = FlowyCoreTest::new_with_user().await;
|
||||||
@ -189,6 +193,40 @@ async fn create_row_event_test() {
|
|||||||
assert_eq!(database.rows.len(), 4);
|
assert_eq!(database.rows.len(), 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn delete_row_event_test() {
|
||||||
|
let test = FlowyCoreTest::new_with_user().await;
|
||||||
|
let current_workspace = test.get_current_workspace().await.workspace;
|
||||||
|
let grid_view = test
|
||||||
|
.create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])
|
||||||
|
.await;
|
||||||
|
|
||||||
|
// delete the row
|
||||||
|
let database = test.get_database(&grid_view.id).await;
|
||||||
|
let error = test.delete_row(&grid_view.id, &database.rows[0].id).await;
|
||||||
|
assert!(error.is_none());
|
||||||
|
|
||||||
|
let database = test.get_database(&grid_view.id).await;
|
||||||
|
assert_eq!(database.rows.len(), 2);
|
||||||
|
|
||||||
|
// get the row again and check if it is deleted.
|
||||||
|
let optional_row = test.get_row(&grid_view.id, &database.rows[0].id).await;
|
||||||
|
assert!(optional_row.row.is_none());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn delete_row_event_with_invalid_row_id_test() {
|
||||||
|
let test = FlowyCoreTest::new_with_user().await;
|
||||||
|
let current_workspace = test.get_current_workspace().await.workspace;
|
||||||
|
let grid_view = test
|
||||||
|
.create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])
|
||||||
|
.await;
|
||||||
|
|
||||||
|
// delete the row with empty row_id. It should return an error.
|
||||||
|
let error = test.delete_row(&grid_view.id, "").await;
|
||||||
|
assert!(error.is_some());
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn duplicate_row_event_test() {
|
async fn duplicate_row_event_test() {
|
||||||
let test = FlowyCoreTest::new_with_user().await;
|
let test = FlowyCoreTest::new_with_user().await;
|
||||||
@ -206,6 +244,90 @@ async fn duplicate_row_event_test() {
|
|||||||
assert_eq!(database.rows.len(), 4);
|
assert_eq!(database.rows.len(), 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn duplicate_row_event_with_invalid_row_id_test() {
|
||||||
|
let test = FlowyCoreTest::new_with_user().await;
|
||||||
|
let current_workspace = test.get_current_workspace().await.workspace;
|
||||||
|
let grid_view = test
|
||||||
|
.create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])
|
||||||
|
.await;
|
||||||
|
let database = test.get_database(&grid_view.id).await;
|
||||||
|
assert_eq!(database.rows.len(), 3);
|
||||||
|
|
||||||
|
let error = test.duplicate_row(&grid_view.id, "").await;
|
||||||
|
assert!(error.is_some());
|
||||||
|
|
||||||
|
let database = test.get_database(&grid_view.id).await;
|
||||||
|
assert_eq!(database.rows.len(), 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn move_row_event_test() {
|
||||||
|
let test = FlowyCoreTest::new_with_user().await;
|
||||||
|
let current_workspace = test.get_current_workspace().await.workspace;
|
||||||
|
let grid_view = test
|
||||||
|
.create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])
|
||||||
|
.await;
|
||||||
|
let database = test.get_database(&grid_view.id).await;
|
||||||
|
let row_1 = database.rows[0].id.clone();
|
||||||
|
let row_2 = database.rows[1].id.clone();
|
||||||
|
let row_3 = database.rows[2].id.clone();
|
||||||
|
let error = test.move_row(&grid_view.id, &row_1, &row_3).await;
|
||||||
|
assert!(error.is_none());
|
||||||
|
|
||||||
|
let database = test.get_database(&grid_view.id).await;
|
||||||
|
assert_eq!(database.rows[0].id, row_2);
|
||||||
|
assert_eq!(database.rows[1].id, row_3);
|
||||||
|
assert_eq!(database.rows[2].id, row_1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn move_row_event_test2() {
|
||||||
|
let test = FlowyCoreTest::new_with_user().await;
|
||||||
|
let current_workspace = test.get_current_workspace().await.workspace;
|
||||||
|
let grid_view = test
|
||||||
|
.create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])
|
||||||
|
.await;
|
||||||
|
let database = test.get_database(&grid_view.id).await;
|
||||||
|
let row_1 = database.rows[0].id.clone();
|
||||||
|
let row_2 = database.rows[1].id.clone();
|
||||||
|
let row_3 = database.rows[2].id.clone();
|
||||||
|
let error = test.move_row(&grid_view.id, &row_2, &row_1).await;
|
||||||
|
assert!(error.is_none());
|
||||||
|
|
||||||
|
let database = test.get_database(&grid_view.id).await;
|
||||||
|
assert_eq!(database.rows[0].id, row_2);
|
||||||
|
assert_eq!(database.rows[1].id, row_1);
|
||||||
|
assert_eq!(database.rows[2].id, row_3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn move_row_event_with_invalid_row_id_test() {
|
||||||
|
let test = FlowyCoreTest::new_with_user().await;
|
||||||
|
let current_workspace = test.get_current_workspace().await.workspace;
|
||||||
|
let grid_view = test
|
||||||
|
.create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])
|
||||||
|
.await;
|
||||||
|
let database = test.get_database(&grid_view.id).await;
|
||||||
|
let row_1 = database.rows[0].id.clone();
|
||||||
|
let row_2 = database.rows[1].id.clone();
|
||||||
|
let row_3 = database.rows[2].id.clone();
|
||||||
|
|
||||||
|
for i in 0..2 {
|
||||||
|
if i == 0 {
|
||||||
|
let error = test.move_row(&grid_view.id, &row_1, "").await;
|
||||||
|
assert!(error.is_some());
|
||||||
|
} else {
|
||||||
|
let error = test.move_row(&grid_view.id, "", &row_1).await;
|
||||||
|
assert!(error.is_some());
|
||||||
|
}
|
||||||
|
let database = test.get_database(&grid_view.id).await;
|
||||||
|
assert_eq!(database.rows[0].id, row_1);
|
||||||
|
assert_eq!(database.rows[1].id, row_2);
|
||||||
|
assert_eq!(database.rows[2].id, row_3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn update_text_cell_event_test() {
|
async fn update_text_cell_event_test() {
|
||||||
let test = FlowyCoreTest::new_with_user().await;
|
let test = FlowyCoreTest::new_with_user().await;
|
||||||
@ -280,14 +402,415 @@ async fn update_single_select_cell_event_test() {
|
|||||||
let field_id = fields[1].id.clone();
|
let field_id = fields[1].id.clone();
|
||||||
assert_eq!(fields[1].field_type, FieldType::SingleSelect);
|
assert_eq!(fields[1].field_type, FieldType::SingleSelect);
|
||||||
|
|
||||||
|
// Insert a new option. This should update the cell with the new option.
|
||||||
let error = test
|
let error = test
|
||||||
.insert_option(&grid_view.id, &field_id, &row_id, "task 1")
|
.insert_option(&grid_view.id, &field_id, &row_id, "task 1")
|
||||||
.await;
|
.await;
|
||||||
assert!(error.is_none());
|
assert!(error.is_none());
|
||||||
|
|
||||||
|
// Check that the cell data is updated.
|
||||||
let cell = test.get_cell(&grid_view.id, &row_id, &field_id).await;
|
let cell = test.get_cell(&grid_view.id, &row_id, &field_id).await;
|
||||||
let select_option_cell = SelectOptionCellDataPB::try_from(Bytes::from(cell.data)).unwrap();
|
let select_option_cell = SelectOptionCellDataPB::try_from(Bytes::from(cell.data)).unwrap();
|
||||||
|
|
||||||
assert_eq!(select_option_cell.options.len(), 1);
|
assert_eq!(select_option_cell.options.len(), 1);
|
||||||
assert_eq!(select_option_cell.select_options.len(), 1);
|
assert_eq!(select_option_cell.select_options.len(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn update_date_cell_event_test() {
|
||||||
|
let test = FlowyCoreTest::new_with_user().await;
|
||||||
|
let current_workspace = test.get_current_workspace().await.workspace;
|
||||||
|
let grid_view = test
|
||||||
|
.create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])
|
||||||
|
.await;
|
||||||
|
let database = test.get_database(&grid_view.id).await;
|
||||||
|
|
||||||
|
// Create a date field
|
||||||
|
let date_field = test.create_field(&grid_view.id, FieldType::DateTime).await;
|
||||||
|
|
||||||
|
let cell_path = CellIdPB {
|
||||||
|
view_id: grid_view.id.clone(),
|
||||||
|
field_id: date_field.id.clone(),
|
||||||
|
row_id: database.rows[0].id.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Insert data into the date cell of the first row.
|
||||||
|
let timestamp = 1686300557;
|
||||||
|
let timestamp_str = 1686300557.to_string();
|
||||||
|
let error = test
|
||||||
|
.update_date_cell(DateChangesetPB {
|
||||||
|
cell_id: cell_path,
|
||||||
|
date: Some(timestamp_str.clone()),
|
||||||
|
time: None,
|
||||||
|
include_time: None,
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
assert!(error.is_none());
|
||||||
|
|
||||||
|
// Check that the cell data is updated.
|
||||||
|
let cell = test
|
||||||
|
.get_date_cell(&grid_view.id, &database.rows[0].id, &date_field.id)
|
||||||
|
.await;
|
||||||
|
assert_eq!(cell.date, "Jun 09, 2023");
|
||||||
|
assert_eq!(cell.timestamp, timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn update_date_cell_event_with_empty_time_str_test() {
|
||||||
|
let test = FlowyCoreTest::new_with_user().await;
|
||||||
|
let current_workspace = test.get_current_workspace().await.workspace;
|
||||||
|
let grid_view = test
|
||||||
|
.create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])
|
||||||
|
.await;
|
||||||
|
let database = test.get_database(&grid_view.id).await;
|
||||||
|
let row_id = database.rows[0].id.clone();
|
||||||
|
|
||||||
|
// Create a date field
|
||||||
|
let date_field = test.create_field(&grid_view.id, FieldType::DateTime).await;
|
||||||
|
let cell_path = CellIdPB {
|
||||||
|
view_id: grid_view.id.clone(),
|
||||||
|
field_id: date_field.id.clone(),
|
||||||
|
row_id: row_id.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Insert empty timestamp string
|
||||||
|
let error = test
|
||||||
|
.update_date_cell(DateChangesetPB {
|
||||||
|
cell_id: cell_path,
|
||||||
|
date: Some("".to_string()),
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
assert!(error.is_none());
|
||||||
|
|
||||||
|
// Check that the cell data is updated.
|
||||||
|
let cell = test
|
||||||
|
.get_date_cell(&grid_view.id, &row_id, &date_field.id)
|
||||||
|
.await;
|
||||||
|
assert_eq!(cell.date, "");
|
||||||
|
assert_eq!(cell.timestamp, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn create_checklist_field_test() {
|
||||||
|
let test = FlowyCoreTest::new_with_user().await;
|
||||||
|
let current_workspace = test.get_current_workspace().await.workspace;
|
||||||
|
let grid_view = test
|
||||||
|
.create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])
|
||||||
|
.await;
|
||||||
|
|
||||||
|
// create checklist field
|
||||||
|
let checklist_field = test.create_field(&grid_view.id, FieldType::Checklist).await;
|
||||||
|
let database = test.get_database(&grid_view.id).await;
|
||||||
|
|
||||||
|
// Get the checklist cell
|
||||||
|
let cell = test
|
||||||
|
.get_checklist_cell(&grid_view.id, &checklist_field.id, &database.rows[0].id)
|
||||||
|
.await;
|
||||||
|
assert_eq!(cell.options.len(), 0);
|
||||||
|
assert_eq!(cell.selected_options.len(), 0);
|
||||||
|
assert_eq!(cell.percentage, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn update_checklist_cell_test() {
|
||||||
|
let test = FlowyCoreTest::new_with_user().await;
|
||||||
|
let current_workspace = test.get_current_workspace().await.workspace;
|
||||||
|
let grid_view = test
|
||||||
|
.create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])
|
||||||
|
.await;
|
||||||
|
|
||||||
|
// create checklist field
|
||||||
|
let checklist_field = test.create_field(&grid_view.id, FieldType::Checklist).await;
|
||||||
|
let database = test.get_database(&grid_view.id).await;
|
||||||
|
|
||||||
|
// update the checklist cell
|
||||||
|
let changeset = ChecklistCellDataChangesetPB {
|
||||||
|
view_id: grid_view.id.clone(),
|
||||||
|
row_id: database.rows[0].id.clone(),
|
||||||
|
field_id: checklist_field.id.clone(),
|
||||||
|
insert_options: vec![
|
||||||
|
"task 1".to_string(),
|
||||||
|
"task 2".to_string(),
|
||||||
|
"task 3".to_string(),
|
||||||
|
],
|
||||||
|
selected_option_ids: vec![],
|
||||||
|
delete_option_ids: vec![],
|
||||||
|
update_options: vec![],
|
||||||
|
};
|
||||||
|
test.update_checklist_cell(changeset).await;
|
||||||
|
|
||||||
|
// get the cell
|
||||||
|
let cell = test
|
||||||
|
.get_checklist_cell(&grid_view.id, &checklist_field.id, &database.rows[0].id)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
assert_eq!(cell.options.len(), 3);
|
||||||
|
assert_eq!(cell.selected_options.len(), 0);
|
||||||
|
|
||||||
|
// select some options
|
||||||
|
let changeset = ChecklistCellDataChangesetPB {
|
||||||
|
view_id: grid_view.id.clone(),
|
||||||
|
row_id: database.rows[0].id.clone(),
|
||||||
|
field_id: checklist_field.id.clone(),
|
||||||
|
selected_option_ids: vec![cell.options[0].id.clone(), cell.options[1].id.clone()],
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
test.update_checklist_cell(changeset).await;
|
||||||
|
|
||||||
|
// get the cell
|
||||||
|
let cell = test
|
||||||
|
.get_checklist_cell(&grid_view.id, &checklist_field.id, &database.rows[0].id)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
assert_eq!(cell.options.len(), 3);
|
||||||
|
assert_eq!(cell.selected_options.len(), 2);
|
||||||
|
assert_eq!(cell.percentage, 0.6666666666666666);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The number of groups should be 0 if there is no group by field in grid
|
||||||
|
#[tokio::test]
|
||||||
|
async fn get_groups_event_with_grid_test() {
|
||||||
|
let test = FlowyCoreTest::new_with_user().await;
|
||||||
|
let current_workspace = test.get_current_workspace().await.workspace;
|
||||||
|
let grid_view = test
|
||||||
|
.create_grid(¤t_workspace.id, "my board view".to_owned(), vec![])
|
||||||
|
.await;
|
||||||
|
|
||||||
|
let groups = test.get_groups(&grid_view.id).await;
|
||||||
|
assert_eq!(groups.len(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn get_groups_event_test() {
|
||||||
|
let test = FlowyCoreTest::new_with_user().await;
|
||||||
|
let current_workspace = test.get_current_workspace().await.workspace;
|
||||||
|
let board_view = test
|
||||||
|
.create_board(¤t_workspace.id, "my board view".to_owned(), vec![])
|
||||||
|
.await;
|
||||||
|
|
||||||
|
let groups = test.get_groups(&board_view.id).await;
|
||||||
|
assert_eq!(groups.len(), 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn move_group_event_test() {
|
||||||
|
let test = FlowyCoreTest::new_with_user().await;
|
||||||
|
let current_workspace = test.get_current_workspace().await.workspace;
|
||||||
|
let board_view = test
|
||||||
|
.create_board(¤t_workspace.id, "my board view".to_owned(), vec![])
|
||||||
|
.await;
|
||||||
|
|
||||||
|
let groups = test.get_groups(&board_view.id).await;
|
||||||
|
assert_eq!(groups.len(), 4);
|
||||||
|
let group_1 = groups[0].group_id.clone();
|
||||||
|
let group_2 = groups[1].group_id.clone();
|
||||||
|
let group_3 = groups[2].group_id.clone();
|
||||||
|
let group_4 = groups[3].group_id.clone();
|
||||||
|
|
||||||
|
let error = test.move_group(&board_view.id, &group_2, &group_3).await;
|
||||||
|
assert!(error.is_none());
|
||||||
|
|
||||||
|
let groups = test.get_groups(&board_view.id).await;
|
||||||
|
assert_eq!(groups[0].group_id, group_1);
|
||||||
|
assert_eq!(groups[1].group_id, group_3);
|
||||||
|
assert_eq!(groups[2].group_id, group_2);
|
||||||
|
assert_eq!(groups[3].group_id, group_4);
|
||||||
|
|
||||||
|
let error = test.move_group(&board_view.id, &group_1, &group_4).await;
|
||||||
|
assert!(error.is_none());
|
||||||
|
|
||||||
|
let groups = test.get_groups(&board_view.id).await;
|
||||||
|
assert_eq!(groups[0].group_id, group_3);
|
||||||
|
assert_eq!(groups[1].group_id, group_2);
|
||||||
|
assert_eq!(groups[2].group_id, group_4);
|
||||||
|
assert_eq!(groups[3].group_id, group_1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn move_group_event_with_invalid_id_test() {
|
||||||
|
let test = FlowyCoreTest::new_with_user().await;
|
||||||
|
let current_workspace = test.get_current_workspace().await.workspace;
|
||||||
|
let board_view = test
|
||||||
|
.create_board(¤t_workspace.id, "my board view".to_owned(), vec![])
|
||||||
|
.await;
|
||||||
|
|
||||||
|
// Empty to group id
|
||||||
|
let groups = test.get_groups(&board_view.id).await;
|
||||||
|
let error = test
|
||||||
|
.move_group(&board_view.id, &groups[0].group_id, "")
|
||||||
|
.await;
|
||||||
|
assert!(error.is_some());
|
||||||
|
|
||||||
|
// empty from group id
|
||||||
|
let error = test
|
||||||
|
.move_group(&board_view.id, "", &groups[1].group_id)
|
||||||
|
.await;
|
||||||
|
assert!(error.is_some());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn rename_group_event_test() {
|
||||||
|
let test = FlowyCoreTest::new_with_user().await;
|
||||||
|
let current_workspace = test.get_current_workspace().await.workspace;
|
||||||
|
let board_view = test
|
||||||
|
.create_board(¤t_workspace.id, "my board view".to_owned(), vec![])
|
||||||
|
.await;
|
||||||
|
|
||||||
|
// Empty to group id
|
||||||
|
let groups = test.get_groups(&board_view.id).await;
|
||||||
|
let error = test
|
||||||
|
.update_group(
|
||||||
|
&board_view.id,
|
||||||
|
&groups[0].group_id,
|
||||||
|
Some("new name".to_owned()),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
assert!(error.is_none());
|
||||||
|
|
||||||
|
let groups = test.get_groups(&board_view.id).await;
|
||||||
|
assert_eq!(groups[0].group_name, "new name".to_owned());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn hide_group_event_test2() {
|
||||||
|
let test = FlowyCoreTest::new_with_user().await;
|
||||||
|
let current_workspace = test.get_current_workspace().await.workspace;
|
||||||
|
let board_view = test
|
||||||
|
.create_board(¤t_workspace.id, "my board view".to_owned(), vec![])
|
||||||
|
.await;
|
||||||
|
|
||||||
|
// Empty to group id
|
||||||
|
let groups = test.get_groups(&board_view.id).await;
|
||||||
|
assert_eq!(groups.len(), 4);
|
||||||
|
|
||||||
|
let error = test
|
||||||
|
.update_group(&board_view.id, &groups[0].group_id, None, Some(false))
|
||||||
|
.await;
|
||||||
|
assert!(error.is_none());
|
||||||
|
|
||||||
|
let groups = test.get_groups(&board_view.id).await;
|
||||||
|
assert_eq!(groups.len(), 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the database layout type from grid to board
|
||||||
|
#[tokio::test]
|
||||||
|
async fn update_database_layout_event_test() {
|
||||||
|
let test = FlowyCoreTest::new_with_user().await;
|
||||||
|
let current_workspace = test.get_current_workspace().await.workspace;
|
||||||
|
let grid_view = test
|
||||||
|
.create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])
|
||||||
|
.await;
|
||||||
|
|
||||||
|
let error = test
|
||||||
|
.update_setting(DatabaseSettingChangesetPB {
|
||||||
|
view_id: grid_view.id.clone(),
|
||||||
|
layout_type: Some(DatabaseLayoutPB::Board),
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
assert!(error.is_none());
|
||||||
|
|
||||||
|
let database = test.get_database(&grid_view.id).await;
|
||||||
|
assert_eq!(database.layout_type, DatabaseLayoutPB::Board);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the database layout type from grid to board. Set the checkbox field as the grouping field
|
||||||
|
#[tokio::test]
|
||||||
|
async fn update_database_layout_event_test2() {
|
||||||
|
let test = FlowyCoreTest::new_with_user().await;
|
||||||
|
let current_workspace = test.get_current_workspace().await.workspace;
|
||||||
|
let grid_view = test
|
||||||
|
.create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])
|
||||||
|
.await;
|
||||||
|
let fields = test.get_all_database_fields(&grid_view.id).await.items;
|
||||||
|
|
||||||
|
let checkbox_field = fields
|
||||||
|
.iter()
|
||||||
|
.find(|field| field.field_type == FieldType::Checkbox)
|
||||||
|
.unwrap();
|
||||||
|
test
|
||||||
|
.set_group_by_field(&grid_view.id, &checkbox_field.id)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
let error = test
|
||||||
|
.update_setting(DatabaseSettingChangesetPB {
|
||||||
|
view_id: grid_view.id.clone(),
|
||||||
|
layout_type: Some(DatabaseLayoutPB::Board),
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
assert!(error.is_none());
|
||||||
|
|
||||||
|
// Empty to group id
|
||||||
|
let groups = test.get_groups(&grid_view.id).await;
|
||||||
|
assert_eq!(groups.len(), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a checkbox field in the default board and then set it as the grouping field.
|
||||||
|
#[tokio::test]
|
||||||
|
async fn set_group_by_checkbox_field_test() {
|
||||||
|
let test = FlowyCoreTest::new_with_user().await;
|
||||||
|
let current_workspace = test.get_current_workspace().await.workspace;
|
||||||
|
let board_view = test
|
||||||
|
.create_board(¤t_workspace.id, "my board view".to_owned(), vec![])
|
||||||
|
.await;
|
||||||
|
|
||||||
|
let checkbox_field = test.create_field(&board_view.id, FieldType::Checkbox).await;
|
||||||
|
test
|
||||||
|
.set_group_by_field(&board_view.id, &checkbox_field.id)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
let groups = test.get_groups(&board_view.id).await;
|
||||||
|
assert_eq!(groups.len(), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn get_all_calendar_event_test() {
|
||||||
|
let test = FlowyCoreTest::new_with_user().await;
|
||||||
|
let current_workspace = test.get_current_workspace().await.workspace;
|
||||||
|
let calendar_view = test
|
||||||
|
.create_calendar(¤t_workspace.id, "my calendar view".to_owned(), vec![])
|
||||||
|
.await;
|
||||||
|
|
||||||
|
// By default, there should be no events
|
||||||
|
let events = test.get_all_calendar_events(&calendar_view.id).await;
|
||||||
|
assert!(events.is_empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn create_calendar_event_test() {
|
||||||
|
let test = FlowyCoreTest::new_with_user().await;
|
||||||
|
let current_workspace = test.get_current_workspace().await.workspace;
|
||||||
|
let calendar_view = test
|
||||||
|
.create_calendar(¤t_workspace.id, "my calendar view".to_owned(), vec![])
|
||||||
|
.await;
|
||||||
|
let fields = test.get_all_database_fields(&calendar_view.id).await.items;
|
||||||
|
let date_field = fields
|
||||||
|
.iter()
|
||||||
|
.find(|field| field.field_type == FieldType::DateTime)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// create a new row
|
||||||
|
let row = test.create_row(&calendar_view.id, None, None).await;
|
||||||
|
|
||||||
|
// Insert data into the date cell of the first row.
|
||||||
|
let timestamp_str = timestamp().to_string();
|
||||||
|
let error = test
|
||||||
|
.update_date_cell(DateChangesetPB {
|
||||||
|
cell_id: CellIdPB {
|
||||||
|
view_id: calendar_view.id.clone(),
|
||||||
|
field_id: date_field.id.clone(),
|
||||||
|
row_id: row.id,
|
||||||
|
},
|
||||||
|
date: Some(timestamp_str.clone()),
|
||||||
|
time: None,
|
||||||
|
include_time: None,
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
assert!(error.is_none());
|
||||||
|
|
||||||
|
let events = test.get_all_calendar_events(&calendar_view.id).await;
|
||||||
|
assert_eq!(events.len(), 1);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user