feat: row document (#2792)

* chore: create orphan view handler

* feat: save icon url and cover url in view

* feat: implement emoji picker UI

* chore: config ui

* chore: config ui again

* chore: replace RowPB with RowMetaPB to exposing more row information

* fix: compile error

* feat: show emoji in row

* chore: update

* test: insert emoji test

* test: add update emoji test

* test: add remove emoji test

* test: add create field tests

* test: add create row and delete row integration tests

* test: add create row from row menu

* test: document in row detail page

* test: delete, duplicate row in row detail page

* test: check the row count displayed in grid page

* test: rename existing field in grid page

* test: update field type of exisiting field in grid page

* test: delete field test

* test: add duplicate field test

* test: add hide field test

* test: add edit text cell test

* test: add insert text to text cell test

* test: add edit number cell test

* test: add edit multiple number cells

* test: add edit checkbox cell test

* feat: integrate editor into database row

* test: add edit create time and last edit time cell test

* test: add edit date cell by selecting a date test

* chore: remove unused code

* chore: update checklist bg color

* test: add update database layout test

---------

Co-authored-by: Lucas.Xu <lucas.xu@appflowy.io>
This commit is contained in:
Nathan.fooo
2023-06-14 22:16:33 +08:00
committed by GitHub
parent b8983e4466
commit 27dd719aa8
145 changed files with 4414 additions and 1366 deletions

View File

@ -99,7 +99,7 @@ checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
[[package]]
name = "appflowy-integrate"
version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4f5837#4f58377a1411745577c216a34672c49dc17413ec"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e9f7fc#e9f7fc76192f2dbb2379f1a02310047763bd4426"
dependencies = [
"anyhow",
"collab",
@ -1024,7 +1024,7 @@ dependencies = [
[[package]]
name = "collab"
version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4f5837#4f58377a1411745577c216a34672c49dc17413ec"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e9f7fc#e9f7fc76192f2dbb2379f1a02310047763bd4426"
dependencies = [
"anyhow",
"bytes",
@ -1042,7 +1042,7 @@ dependencies = [
[[package]]
name = "collab-client-ws"
version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4f5837#4f58377a1411745577c216a34672c49dc17413ec"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e9f7fc#e9f7fc76192f2dbb2379f1a02310047763bd4426"
dependencies = [
"bytes",
"collab-sync",
@ -1060,7 +1060,7 @@ dependencies = [
[[package]]
name = "collab-database"
version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4f5837#4f58377a1411745577c216a34672c49dc17413ec"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e9f7fc#e9f7fc76192f2dbb2379f1a02310047763bd4426"
dependencies = [
"anyhow",
"async-trait",
@ -1086,7 +1086,7 @@ dependencies = [
[[package]]
name = "collab-derive"
version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4f5837#4f58377a1411745577c216a34672c49dc17413ec"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e9f7fc#e9f7fc76192f2dbb2379f1a02310047763bd4426"
dependencies = [
"proc-macro2",
"quote",
@ -1098,7 +1098,7 @@ dependencies = [
[[package]]
name = "collab-document"
version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4f5837#4f58377a1411745577c216a34672c49dc17413ec"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e9f7fc#e9f7fc76192f2dbb2379f1a02310047763bd4426"
dependencies = [
"anyhow",
"collab",
@ -1109,13 +1109,14 @@ dependencies = [
"serde",
"serde_json",
"thiserror",
"tokio",
"tracing",
]
[[package]]
name = "collab-folder"
version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4f5837#4f58377a1411745577c216a34672c49dc17413ec"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e9f7fc#e9f7fc76192f2dbb2379f1a02310047763bd4426"
dependencies = [
"anyhow",
"chrono",
@ -1135,7 +1136,7 @@ dependencies = [
[[package]]
name = "collab-persistence"
version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4f5837#4f58377a1411745577c216a34672c49dc17413ec"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e9f7fc#e9f7fc76192f2dbb2379f1a02310047763bd4426"
dependencies = [
"bincode",
"chrono",
@ -1155,7 +1156,7 @@ dependencies = [
[[package]]
name = "collab-plugins"
version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4f5837#4f58377a1411745577c216a34672c49dc17413ec"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e9f7fc#e9f7fc76192f2dbb2379f1a02310047763bd4426"
dependencies = [
"anyhow",
"async-trait",
@ -1186,7 +1187,7 @@ dependencies = [
[[package]]
name = "collab-sync"
version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4f5837#4f58377a1411745577c216a34672c49dc17413ec"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e9f7fc#e9f7fc76192f2dbb2379f1a02310047763bd4426"
dependencies = [
"bytes",
"collab",
@ -5006,6 +5007,12 @@ dependencies = [
"digest 0.10.6",
]
[[package]]
name = "sha1_smol"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012"
[[package]]
name = "sha2"
version = "0.10.6"
@ -6206,6 +6213,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "345444e32442451b267fc254ae85a209c64be56d2890e601a0c37ff0c3c5ecd2"
dependencies = [
"getrandom 0.2.9",
"sha1_smol",
]
[[package]]

View File

@ -34,12 +34,12 @@ default = ["custom-protocol"]
custom-protocol = ["tauri/custom-protocol"]
[patch.crates-io]
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4f5837" }
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4f5837" }
collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4f5837" }
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4f5837" }
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4f5837" }
appflowy-integrate = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4f5837" }
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e9f7fc" }
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e9f7fc" }
collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e9f7fc" }
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e9f7fc" }
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e9f7fc" }
appflowy-integrate = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e9f7fc" }
#collab = { path = "../../AppFlowy-Collab/collab" }
#collab-folder = { path = "../../AppFlowy-Collab/collab-folder" }

View File

@ -1,4 +1,11 @@
import { DatabaseNotification, FlowyError, GroupPB, GroupRowsNotificationPB, RowPB } from '@/services/backend';
import {
DatabaseNotification,
FlowyError,
GroupPB,
GroupRowsNotificationPB,
RowMetaPB,
RowPB,
} from '@/services/backend';
import { ChangeNotifier } from '$app/utils/change_notifier';
import { None, Ok, Option, Result, Some } from 'ts-results';
import { DatabaseNotificationObserver } from '../notifications/observer';
@ -7,10 +14,10 @@ import { DatabaseBackendService } from '../database_bd_svc';
export type GroupDataCallbacks = {
onRemoveRow: (groupId: string, rowId: string) => void;
onInsertRow: (groupId: string, row: RowPB, index?: number) => void;
onUpdateRow: (groupId: string, row: RowPB) => void;
onInsertRow: (groupId: string, row: RowMetaPB, index?: number) => void;
onUpdateRow: (groupId: string, row: RowMetaPB) => void;
onCreateRow: (groupId: string, row: RowPB) => void;
onCreateRow: (groupId: string, row: RowMetaPB) => void;
};
export class DatabaseGroupController {
@ -37,7 +44,7 @@ export class DatabaseGroupController {
this.group = group;
};
rowAtIndex = (index: number): Option<RowPB> => {
rowAtIndex = (index: number): Option<RowMetaPB> => {
if (this.group.rows.length < index) {
return None;
}
@ -59,16 +66,16 @@ export class DatabaseGroupController {
changeset.inserted_rows.forEach((insertedRow) => {
let index: number | undefined = insertedRow.index;
if (insertedRow.has_index && this.group.rows.length > insertedRow.index) {
this.group.rows.splice(index, 0, insertedRow.row);
this.group.rows.splice(index, 0, insertedRow.row_meta);
} else {
index = undefined;
this.group.rows.push(insertedRow.row);
this.group.rows.push(insertedRow.row_meta);
}
if (insertedRow.is_new) {
this.callbacks?.onCreateRow(this.group.group_id, insertedRow.row);
this.callbacks?.onCreateRow(this.group.group_id, insertedRow.row_meta);
} else {
this.callbacks?.onInsertRow(this.group.group_id, insertedRow.row, index);
this.callbacks?.onInsertRow(this.group.group_id, insertedRow.row_meta, index);
}
});

View File

@ -7,12 +7,13 @@ import {
RowsChangePB,
RowsVisibilityChangePB,
ReorderSingleRowPB,
RowMetaPB,
} from '@/services/backend';
import { ChangeNotifier } from '$app/utils/change_notifier';
import { FieldInfo } from '../field/field_controller';
import { CellCache, CellCacheKey } from '../cell/cell_cache';
import { CellIdentifier } from '../cell/cell_bd_svc';
import { DatabaseEventGetRow } from '@/services/backend/events/flowy-database2';
import { DatabaseEventGetRow, DatabaseEventGetRowMeta } from '@/services/backend/events/flowy-database2';
import { None, Option, Some } from 'ts-results';
import { Log } from '$app/utils/log';
@ -75,7 +76,7 @@ export class RowCache {
this.notifier.withChange(RowChangedReason.FieldDidChanged);
};
initializeRows = (rows: RowPB[]) => {
initializeRows = (rows: RowMetaPB[]) => {
rows.forEach((rowPB) => {
this.rowList.push(this._toRowInfo(rowPB));
});
@ -106,11 +107,7 @@ export class RowCache {
}
};
private _refreshRow = (opRow: OptionalRowPB) => {
if (!opRow.has_row) {
return;
}
const updatedRow = opRow.row;
private _refreshRow = (updatedRow: RowMetaPB) => {
const option = this.rowList.getRowWithIndex(updatedRow.id);
if (option.some) {
const { rowInfo, index } = option.val;
@ -124,7 +121,7 @@ export class RowCache {
private _loadRow = (rowId: string) => {
const payload = RowIdPB.fromObject({ view_id: this.viewId, row_id: rowId });
return DatabaseEventGetRow(payload);
return DatabaseEventGetRowMeta(payload);
};
private _deleteRows = (rowIds: string[]) => {
@ -138,7 +135,7 @@ export class RowCache {
private _insertRows = (rows: InsertedRowPB[]) => {
rows.forEach((insertedRow) => {
const rowInfo = this._toRowInfo(insertedRow.row);
const rowInfo = this._toRowInfo(insertedRow.row_meta);
const insertedIndex = this.rowList.insert(insertedRow.index, rowInfo);
if (insertedIndex !== undefined) {
this.notifier.withChange(RowChangedReason.Insert, insertedIndex.rowId);
@ -154,11 +151,11 @@ export class RowCache {
const rowInfos: RowInfo[] = [];
updatedRows.forEach((updatedRow) => {
updatedRow.field_ids.forEach((fieldId) => {
const key = new CellCacheKey(fieldId, updatedRow.row.id);
const key = new CellCacheKey(fieldId, updatedRow.row_meta.id);
this.cellCache.remove(key);
});
rowInfos.push(this._toRowInfo(updatedRow.row));
rowInfos.push(this._toRowInfo(updatedRow.row_meta));
});
const updatedIndexs = this.rowList.insertRows(rowInfos);
@ -178,7 +175,7 @@ export class RowCache {
private _displayRows = (insertedRows: InsertedRowPB[]) => {
insertedRows.forEach((insertedRow) => {
const insertedIndex = this.rowList.insert(insertedRow.index, this._toRowInfo(insertedRow.row));
const insertedIndex = this.rowList.insert(insertedRow.index, this._toRowInfo(insertedRow.row_meta));
if (insertedIndex !== undefined) {
this.notifier.withChange(RowChangedReason.Insert, insertedIndex.rowId);
@ -190,7 +187,7 @@ export class RowCache {
this.notifier.dispose();
};
private _toRowInfo = (rowPB: RowPB) => {
private _toRowInfo = (rowPB: RowMetaPB) => {
return new RowInfo(this.viewId, this.getFieldInfos(), rowPB);
};
@ -338,10 +335,10 @@ export class RowInfo {
constructor(
public readonly viewId: string,
public readonly fieldInfos: readonly FieldInfo[],
public readonly row: RowPB
public readonly row: RowMetaPB
) {}
copyWith = (params: { row?: RowPB; fieldInfos?: readonly FieldInfo[] }) => {
copyWith = (params: { row?: RowMetaPB; fieldInfos?: readonly FieldInfo[] }) => {
return new RowInfo(this.viewId, params.fieldInfos || this.fieldInfos, params.row || this.row);
};
}

View File

@ -1,7 +1,7 @@
import { DatabaseViewRowsObserver } from './view_row_observer';
import { RowCache, RowInfo } from '../row/row_cache';
import { FieldController } from '../field/field_controller';
import { RowPB } from '@/services/backend';
import { RowMetaPB, RowPB } from '@/services/backend';
export class DatabaseViewCache {
private readonly rowsObserver: DatabaseViewRowsObserver;
@ -20,7 +20,7 @@ export class DatabaseViewCache {
});
}
initializeWithRows = (rows: RowPB[]) => {
initializeWithRows = (rows: RowMetaPB[]) => {
this.rowCache.initializeRows(rows);
};