mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
fix: group with not support field test (#1890)
This commit is contained in:
parent
bf8e36a08b
commit
4a81fed6e4
4
frontend/.vscode/launch.json
vendored
4
frontend/.vscode/launch.json
vendored
@ -12,8 +12,8 @@
|
|||||||
"type": "dart",
|
"type": "dart",
|
||||||
"preLaunchTask": "AF: Build Appflowy Core",
|
"preLaunchTask": "AF: Build Appflowy Core",
|
||||||
"env": {
|
"env": {
|
||||||
"RUST_LOG": "trace",
|
// "RUST_LOG": "trace",
|
||||||
// "RUST_LOG": "debug"
|
"RUST_LOG": "debug"
|
||||||
},
|
},
|
||||||
"cwd": "${workspaceRoot}/appflowy_flutter"
|
"cwd": "${workspaceRoot}/appflowy_flutter"
|
||||||
},
|
},
|
||||||
|
@ -18,7 +18,7 @@ on_error_task = "catch"
|
|||||||
run_task = { name = ["restore-crate-type"] }
|
run_task = { name = ["restore-crate-type"] }
|
||||||
|
|
||||||
[env]
|
[env]
|
||||||
RUST_LOG = "debug"
|
RUST_LOG = "info"
|
||||||
CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true
|
CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true
|
||||||
CARGO_MAKE_CRATE_FS_NAME = "dart_ffi"
|
CARGO_MAKE_CRATE_FS_NAME = "dart_ffi"
|
||||||
CARGO_MAKE_CRATE_NAME = "dart-ffi"
|
CARGO_MAKE_CRATE_NAME = "dart-ffi"
|
||||||
@ -48,7 +48,6 @@ TAURI_BACKEND_SERVICE_PATH = "appflowy_tauri/src/services/backend"
|
|||||||
# Test default config
|
# Test default config
|
||||||
TEST_CRATE_TYPE = "cdylib"
|
TEST_CRATE_TYPE = "cdylib"
|
||||||
TEST_LIB_EXT = "dylib"
|
TEST_LIB_EXT = "dylib"
|
||||||
TEST_RUST_LOG = "info"
|
|
||||||
TEST_BUILD_FLAG = "debug"
|
TEST_BUILD_FLAG = "debug"
|
||||||
TEST_COMPILE_TARGET = "x86_64-apple-darwin"
|
TEST_COMPILE_TARGET = "x86_64-apple-darwin"
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ class DatabaseBackendService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Either<Unit, FlowyError>> closeGrid() {
|
Future<Either<Unit, FlowyError>> closeView() {
|
||||||
final request = ViewIdPB(value: viewId);
|
final request = ViewIdPB(value: viewId);
|
||||||
return FolderEventCloseView(request).send();
|
return FolderEventCloseView(request).send();
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,7 @@ class BoardDataController {
|
|||||||
|
|
||||||
Future<void> dispose() async {
|
Future<void> dispose() async {
|
||||||
await _viewCache.dispose();
|
await _viewCache.dispose();
|
||||||
await _databaseFFIService.closeGrid();
|
await _databaseFFIService.closeView();
|
||||||
await fieldController.dispose();
|
await fieldController.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ class CalendarDataController {
|
|||||||
|
|
||||||
Future<void> dispose() async {
|
Future<void> dispose() async {
|
||||||
await _viewCache.dispose();
|
await _viewCache.dispose();
|
||||||
await _databaseBackendSvc.closeGrid();
|
await _databaseBackendSvc.closeView();
|
||||||
await fieldController.dispose();
|
await fieldController.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ class DatabaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> dispose() async {
|
Future<void> dispose() async {
|
||||||
await _databaseBackendSvc.closeGrid();
|
await _databaseBackendSvc.closeView();
|
||||||
await fieldController.dispose();
|
await fieldController.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ void main() {
|
|||||||
await boardResponseFuture();
|
await boardResponseFuture();
|
||||||
});
|
});
|
||||||
|
|
||||||
group('Group with not support grouping field:', () {
|
group('Group with not support grouping field', () {
|
||||||
blocTest<FieldEditorBloc, FieldEditorState>(
|
blocTest<FieldEditorBloc, FieldEditorState>(
|
||||||
"switch to text field",
|
"switch to text field",
|
||||||
build: () => editorBloc,
|
build: () => editorBloc,
|
||||||
|
2
frontend/appflowy_tauri/src-tauri/Cargo.lock
generated
2
frontend/appflowy_tauri/src-tauri/Cargo.lock
generated
@ -1225,6 +1225,8 @@ dependencies = [
|
|||||||
"lib-ws",
|
"lib-ws",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"revision-model",
|
"revision-model",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
"user-model",
|
"user-model",
|
||||||
|
@ -14,7 +14,7 @@ class CellIdentifier {
|
|||||||
class CellBackendService {
|
class CellBackendService {
|
||||||
static updateCell = async (cellId: CellIdentifier, data: string) => {
|
static updateCell = async (cellId: CellIdentifier, data: string) => {
|
||||||
const payload = CellChangesetPB.fromObject({
|
const payload = CellChangesetPB.fromObject({
|
||||||
database_id: cellId.viewId,
|
view_id: cellId.viewId,
|
||||||
field_id: cellId.fieldId,
|
field_id: cellId.fieldId,
|
||||||
row_id: cellId.rowId,
|
row_id: cellId.rowId,
|
||||||
type_cell_data: data,
|
type_cell_data: data,
|
||||||
@ -24,7 +24,7 @@ class CellBackendService {
|
|||||||
|
|
||||||
getCell = async (cellId: CellIdentifier) => {
|
getCell = async (cellId: CellIdentifier) => {
|
||||||
const payload = CellIdPB.fromObject({
|
const payload = CellIdPB.fromObject({
|
||||||
database_id: cellId.viewId,
|
view_id: cellId.viewId,
|
||||||
field_id: cellId.fieldId,
|
field_id: cellId.fieldId,
|
||||||
row_id: cellId.rowId,
|
row_id: cellId.rowId,
|
||||||
});
|
});
|
||||||
|
@ -39,7 +39,7 @@ export class DateCellDataPersistence extends CellDataPersistence<CalendarData> {
|
|||||||
|
|
||||||
function _makeCellPath(cellIdentifier: CellIdentifier): CellIdPB {
|
function _makeCellPath(cellIdentifier: CellIdentifier): CellIdPB {
|
||||||
return CellIdPB.fromObject({
|
return CellIdPB.fromObject({
|
||||||
database_id: cellIdentifier.viewId,
|
view_id: cellIdentifier.viewId,
|
||||||
field_id: cellIdentifier.fieldId,
|
field_id: cellIdentifier.fieldId,
|
||||||
row_id: cellIdentifier.rowId,
|
row_id: cellIdentifier.rowId,
|
||||||
});
|
});
|
||||||
|
@ -28,7 +28,7 @@ export class FieldBackendService {
|
|||||||
visibility?: boolean;
|
visibility?: boolean;
|
||||||
width?: number;
|
width?: number;
|
||||||
}) => {
|
}) => {
|
||||||
const payload = FieldChangesetPB.fromObject({ database_id: this.viewId, field_id: this.fieldId });
|
const payload = FieldChangesetPB.fromObject({ view_id: this.viewId, field_id: this.fieldId });
|
||||||
|
|
||||||
if (data.name !== undefined) {
|
if (data.name !== undefined) {
|
||||||
payload.name = data.name;
|
payload.name = data.name;
|
||||||
|
@ -3,8 +3,8 @@ import { ChangeNotifier } from '../../../../utils/change_notifier';
|
|||||||
import { FieldInfo } from '../field/controller';
|
import { FieldInfo } from '../field/controller';
|
||||||
import { CellCache, CellCacheKey } from '../cell/cache';
|
import { CellCache, CellCacheKey } from '../cell/cache';
|
||||||
import {
|
import {
|
||||||
ViewRowsChangesetPB,
|
RowsChangesetPB,
|
||||||
ViewRowsVisibilityChangesetPB,
|
RowsVisibilityChangesetPB,
|
||||||
} from '../../../../../services/backend/models/flowy-database/view_entities';
|
} from '../../../../../services/backend/models/flowy-database/view_entities';
|
||||||
import { CellIdentifier } from '../cell/backend_service';
|
import { CellIdentifier } from '../cell/backend_service';
|
||||||
import { ReorderSingleRowPB } from '../../../../../services/backend/models/flowy-database/sort_entities';
|
import { ReorderSingleRowPB } from '../../../../../services/backend/models/flowy-database/sort_entities';
|
||||||
@ -49,13 +49,13 @@ export class RowCache {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
applyRowsChanged = (changeset: ViewRowsChangesetPB) => {
|
applyRowsChanged = (changeset: RowsChangesetPB) => {
|
||||||
this._deleteRows(changeset.deleted_rows);
|
this._deleteRows(changeset.deleted_rows);
|
||||||
this._insertRows(changeset.inserted_rows);
|
this._insertRows(changeset.inserted_rows);
|
||||||
this._updateRows(changeset.updated_rows);
|
this._updateRows(changeset.updated_rows);
|
||||||
};
|
};
|
||||||
|
|
||||||
applyRowsVisibility = (changeset: ViewRowsVisibilityChangesetPB) => {
|
applyRowsVisibility = (changeset: RowsVisibilityChangesetPB) => {
|
||||||
this._hideRows(changeset.invisible_rows);
|
this._hideRows(changeset.invisible_rows);
|
||||||
this._displayRows(changeset.visible_rows);
|
this._displayRows(changeset.visible_rows);
|
||||||
};
|
};
|
||||||
|
@ -5,15 +5,15 @@ import {
|
|||||||
ReorderSingleRowPB,
|
ReorderSingleRowPB,
|
||||||
} from '../../../../../services/backend/events/flowy-database';
|
} from '../../../../../services/backend/events/flowy-database';
|
||||||
import {
|
import {
|
||||||
ViewRowsChangesetPB,
|
RowsChangesetPB,
|
||||||
ViewRowsVisibilityChangesetPB,
|
RowsVisibilityChangesetPB,
|
||||||
} from '../../../../../services/backend/models/flowy-database/view_entities';
|
} from '../../../../../services/backend/models/flowy-database/view_entities';
|
||||||
import { FlowyError } from '../../../../../services/backend/models/flowy-error/errors';
|
import { FlowyError } from '../../../../../services/backend/models/flowy-error/errors';
|
||||||
import { ChangeNotifier } from '../../../../utils/change_notifier';
|
import { ChangeNotifier } from '../../../../utils/change_notifier';
|
||||||
import { DatabaseNotificationObserver } from '../notifications/observer';
|
import { DatabaseNotificationObserver } from '../notifications/observer';
|
||||||
|
|
||||||
export type RowsVisibilityNotifyValue = Result<ViewRowsVisibilityChangesetPB, FlowyError>;
|
export type RowsVisibilityNotifyValue = Result<RowsVisibilityChangesetPB, FlowyError>;
|
||||||
export type RowsNotifyValue = Result<ViewRowsChangesetPB, FlowyError>;
|
export type RowsNotifyValue = Result<RowsChangesetPB, FlowyError>;
|
||||||
export type ReorderRowsNotifyValue = Result<string[], FlowyError>;
|
export type ReorderRowsNotifyValue = Result<string[], FlowyError>;
|
||||||
export type ReorderSingleRowNotifyValue = Result<ReorderSingleRowPB, FlowyError>;
|
export type ReorderSingleRowNotifyValue = Result<ReorderSingleRowPB, FlowyError>;
|
||||||
|
|
||||||
@ -43,10 +43,10 @@ export class DatabaseViewRowsObserver {
|
|||||||
parserHandler: (notification, payload) => {
|
parserHandler: (notification, payload) => {
|
||||||
switch (notification) {
|
switch (notification) {
|
||||||
case DatabaseNotification.DidUpdateViewRowsVisibility:
|
case DatabaseNotification.DidUpdateViewRowsVisibility:
|
||||||
this._rowsVisibilityNotifier.notify(Ok(ViewRowsVisibilityChangesetPB.deserializeBinary(payload)));
|
this._rowsVisibilityNotifier.notify(Ok(RowsVisibilityChangesetPB.deserializeBinary(payload)));
|
||||||
break;
|
break;
|
||||||
case DatabaseNotification.DidUpdateViewRows:
|
case DatabaseNotification.DidUpdateViewRows:
|
||||||
this._rowsNotifier.notify(Ok(ViewRowsChangesetPB.deserializeBinary(payload)));
|
this._rowsNotifier.notify(Ok(RowsChangesetPB.deserializeBinary(payload)));
|
||||||
break;
|
break;
|
||||||
case DatabaseNotification.DidReorderRows:
|
case DatabaseNotification.DidReorderRows:
|
||||||
this._reorderRowsNotifier.notify(Ok(ReorderAllRowsPB.deserializeBinary(payload).row_orders));
|
this._reorderRowsNotifier.notify(Ok(ReorderAllRowsPB.deserializeBinary(payload).row_orders));
|
||||||
|
@ -41,7 +41,6 @@ export class AppBackendService {
|
|||||||
belong_to_id: this.appId,
|
belong_to_id: this.appId,
|
||||||
name: params.name,
|
name: params.name,
|
||||||
desc: params.desc || '',
|
desc: params.desc || '',
|
||||||
data_format: params.dataFormatType,
|
|
||||||
layout: params.layoutType,
|
layout: params.layoutType,
|
||||||
initial_data: encoder.encode(params.initialData || ''),
|
initial_data: encoder.encode(params.initialData || ''),
|
||||||
});
|
});
|
||||||
|
@ -109,18 +109,18 @@ impl DatabaseRevisionPad {
|
|||||||
&mut self,
|
&mut self,
|
||||||
field_id: &str,
|
field_id: &str,
|
||||||
) -> SyncResult<Option<DatabaseRevisionChangeset>> {
|
) -> SyncResult<Option<DatabaseRevisionChangeset>> {
|
||||||
self.modify_database(|grid_meta| {
|
self.modify_database(|database| {
|
||||||
match grid_meta
|
match database
|
||||||
.fields
|
.fields
|
||||||
.iter()
|
.iter()
|
||||||
.position(|field| field.id == field_id)
|
.position(|field| field.id == field_id)
|
||||||
{
|
{
|
||||||
None => Ok(None),
|
None => Ok(None),
|
||||||
Some(index) => {
|
Some(index) => {
|
||||||
if grid_meta.fields[index].is_primary {
|
if database.fields[index].is_primary {
|
||||||
Err(SyncError::can_not_delete_primary_field())
|
Err(SyncError::can_not_delete_primary_field())
|
||||||
} else {
|
} else {
|
||||||
grid_meta.fields.remove(index);
|
database.fields.remove(index);
|
||||||
Ok(Some(()))
|
Ok(Some(()))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -572,7 +572,7 @@ impl FieldType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn can_be_group(&self) -> bool {
|
pub fn can_be_group(&self) -> bool {
|
||||||
self.is_select_option() || self.is_checkbox()
|
self.is_select_option() || self.is_checkbox() || self.is_url()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ pub(crate) async fn delete_field_handler(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "trace", skip(data, manager), err)]
|
#[tracing::instrument(level = "debug", skip(data, manager), err)]
|
||||||
pub(crate) async fn switch_to_field_handler(
|
pub(crate) async fn switch_to_field_handler(
|
||||||
data: AFPluginData<UpdateFieldTypePayloadPB>,
|
data: AFPluginData<UpdateFieldTypePayloadPB>,
|
||||||
manager: AFPluginState<Arc<DatabaseManager>>,
|
manager: AFPluginState<Arc<DatabaseManager>>,
|
||||||
|
@ -40,7 +40,7 @@ pub trait DatabaseUser: Send + Sync {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct DatabaseManager {
|
pub struct DatabaseManager {
|
||||||
database_editors: RwLock<HashMap<String, Arc<DatabaseEditor>>>,
|
editors_by_database_id: RwLock<HashMap<String, Arc<DatabaseEditor>>>,
|
||||||
database_user: Arc<dyn DatabaseUser>,
|
database_user: Arc<dyn DatabaseUser>,
|
||||||
block_indexer: Arc<BlockRowIndexer>,
|
block_indexer: Arc<BlockRowIndexer>,
|
||||||
database_ref_indexer: Arc<DatabaseRefIndexer>,
|
database_ref_indexer: Arc<DatabaseRefIndexer>,
|
||||||
@ -58,7 +58,7 @@ impl DatabaseManager {
|
|||||||
task_scheduler: Arc<RwLock<TaskDispatcher>>,
|
task_scheduler: Arc<RwLock<TaskDispatcher>>,
|
||||||
database_db: Arc<dyn DatabaseDBConnection>,
|
database_db: Arc<dyn DatabaseDBConnection>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let database_editors = RwLock::new(HashMap::new());
|
let editors_by_database_id = RwLock::new(HashMap::new());
|
||||||
let kv_persistence = Arc::new(DatabaseKVPersistence::new(database_db.clone()));
|
let kv_persistence = Arc::new(DatabaseKVPersistence::new(database_db.clone()));
|
||||||
let block_indexer = Arc::new(BlockRowIndexer::new(database_db.clone()));
|
let block_indexer = Arc::new(BlockRowIndexer::new(database_db.clone()));
|
||||||
let database_ref_indexer = Arc::new(DatabaseRefIndexer::new(database_db.clone()));
|
let database_ref_indexer = Arc::new(DatabaseRefIndexer::new(database_db.clone()));
|
||||||
@ -68,7 +68,7 @@ impl DatabaseManager {
|
|||||||
database_ref_indexer.clone(),
|
database_ref_indexer.clone(),
|
||||||
);
|
);
|
||||||
Self {
|
Self {
|
||||||
database_editors,
|
editors_by_database_id,
|
||||||
database_user,
|
database_user,
|
||||||
kv_persistence,
|
kv_persistence,
|
||||||
block_indexer,
|
block_indexer,
|
||||||
@ -141,7 +141,6 @@ impl DatabaseManager {
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, fields(view_id), err)]
|
|
||||||
pub async fn close_database_view<T: AsRef<str>>(&self, view_id: T) -> FlowyResult<()> {
|
pub async fn close_database_view<T: AsRef<str>>(&self, view_id: T) -> FlowyResult<()> {
|
||||||
let view_id = view_id.as_ref();
|
let view_id = view_id.as_ref();
|
||||||
let database_info = self.database_ref_indexer.get_database_with_view(view_id)?;
|
let database_info = self.database_ref_indexer.get_database_with_view(view_id)?;
|
||||||
@ -149,7 +148,7 @@ impl DatabaseManager {
|
|||||||
|
|
||||||
let mut should_remove_editor = false;
|
let mut should_remove_editor = false;
|
||||||
if let Some(database_editor) = self
|
if let Some(database_editor) = self
|
||||||
.database_editors
|
.editors_by_database_id
|
||||||
.write()
|
.write()
|
||||||
.await
|
.await
|
||||||
.get(&database_info.database_id)
|
.get(&database_info.database_id)
|
||||||
@ -162,8 +161,9 @@ impl DatabaseManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if should_remove_editor {
|
if should_remove_editor {
|
||||||
|
tracing::debug!("Close database base editor: {}", database_info.database_id);
|
||||||
self
|
self
|
||||||
.database_editors
|
.editors_by_database_id
|
||||||
.write()
|
.write()
|
||||||
.await
|
.await
|
||||||
.remove(&database_info.database_id);
|
.remove(&database_info.database_id);
|
||||||
@ -173,15 +173,19 @@ impl DatabaseManager {
|
|||||||
|
|
||||||
// #[tracing::instrument(level = "debug", skip(self), err)]
|
// #[tracing::instrument(level = "debug", skip(self), err)]
|
||||||
pub async fn get_database_editor(&self, view_id: &str) -> FlowyResult<Arc<DatabaseEditor>> {
|
pub async fn get_database_editor(&self, view_id: &str) -> FlowyResult<Arc<DatabaseEditor>> {
|
||||||
let read_guard = self.database_editors.read().await;
|
let database_info = self.database_ref_indexer.get_database_with_view(view_id)?;
|
||||||
let editor = read_guard.get(view_id);
|
let database_editor = self
|
||||||
match editor {
|
.editors_by_database_id
|
||||||
|
.read()
|
||||||
|
.await
|
||||||
|
.get(&database_info.database_id)
|
||||||
|
.cloned();
|
||||||
|
match database_editor {
|
||||||
None => {
|
None => {
|
||||||
// Drop the read_guard ASAP in case of the following read/write lock
|
// Drop the read_guard ASAP in case of the following read/write lock
|
||||||
drop(read_guard);
|
|
||||||
self.open_database_view(view_id).await
|
self.open_database_view(view_id).await
|
||||||
},
|
},
|
||||||
Some(editor) => Ok(editor.clone()),
|
Some(editor) => Ok(editor),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,7 +204,7 @@ impl DatabaseManager {
|
|||||||
database_id: &str,
|
database_id: &str,
|
||||||
view_id: &str,
|
view_id: &str,
|
||||||
) -> FlowyResult<Arc<DatabaseEditor>> {
|
) -> FlowyResult<Arc<DatabaseEditor>> {
|
||||||
if let Some(database_editor) = self.database_editors.read().await.get(database_id) {
|
if let Some(database_editor) = self.editors_by_database_id.read().await.get(database_id) {
|
||||||
let user_id = self.database_user.user_id()?;
|
let user_id = self.database_user.user_id()?;
|
||||||
let (view_pad, view_rev_manager) =
|
let (view_pad, view_rev_manager) =
|
||||||
make_database_view_revision_pad(view_id, self.database_user.clone()).await?;
|
make_database_view_revision_pad(view_id, self.database_user.clone()).await?;
|
||||||
@ -217,10 +221,10 @@ impl DatabaseManager {
|
|||||||
return Ok(database_editor.clone());
|
return Ok(database_editor.clone());
|
||||||
}
|
}
|
||||||
// Lock the database_editors
|
// Lock the database_editors
|
||||||
let mut database_editors = self.database_editors.write().await;
|
let mut editors_by_database_id = self.editors_by_database_id.write().await;
|
||||||
let db_pool = self.database_user.db_pool()?;
|
let db_pool = self.database_user.db_pool()?;
|
||||||
let editor = self.make_database_rev_editor(view_id, db_pool).await?;
|
let editor = self.make_database_rev_editor(view_id, db_pool).await?;
|
||||||
database_editors.insert(database_id.to_string(), editor.clone());
|
editors_by_database_id.insert(database_id.to_string(), editor.clone());
|
||||||
Ok(editor)
|
Ok(editor)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,7 +240,7 @@ impl DatabaseManager {
|
|||||||
make_database_view_revision_pad(view_id, user.clone()).await?;
|
make_database_view_revision_pad(view_id, user.clone()).await?;
|
||||||
let mut database_id = base_view_pad.database_id.clone();
|
let mut database_id = base_view_pad.database_id.clone();
|
||||||
|
|
||||||
tracing::debug!("Open database:{}", database_id);
|
tracing::debug!("Open database: {}", database_id);
|
||||||
if database_id.is_empty() {
|
if database_id.is_empty() {
|
||||||
// Before the database_id concept comes up, we used the view_id directly. So if
|
// Before the database_id concept comes up, we used the view_id directly. So if
|
||||||
// the database_id is empty, which means we can used the view_id. After the version 0.1.1,
|
// the database_id is empty, which means we can used the view_id. After the version 0.1.1,
|
||||||
|
@ -129,15 +129,14 @@ impl DatabaseBlockEditor {
|
|||||||
if let Ok(pad) = self.pad.try_read() {
|
if let Ok(pad) = self.pad.try_read() {
|
||||||
Ok(pad.get_row_rev(row_id))
|
Ok(pad.get_row_rev(row_id))
|
||||||
} else {
|
} else {
|
||||||
tracing::error!("Required grid block read lock failed, retrying");
|
|
||||||
let retry = GetRowDataRetryAction {
|
let retry = GetRowDataRetryAction {
|
||||||
row_id: row_id.to_owned(),
|
row_id: row_id.to_owned(),
|
||||||
pad: self.pad.clone(),
|
pad: self.pad.clone(),
|
||||||
};
|
};
|
||||||
match spawn_retry(3, 300, retry).await {
|
match spawn_retry(3, 300, retry).await {
|
||||||
Ok(value) => Ok(value),
|
Ok(value) => Ok(value),
|
||||||
Err(err) => {
|
Err(_) => {
|
||||||
tracing::error!("Read row revision failed with: {}", err);
|
tracing::error!("Required database block read lock failed");
|
||||||
Ok(None)
|
Ok(None)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -116,7 +116,7 @@ impl DatabaseEditor {
|
|||||||
self.database_views.open(view_editor).await
|
self.database_views.open(view_editor).await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(name = "close database editor view", level = "trace", skip_all)]
|
#[tracing::instrument(name = "Close database editor view", level = "debug", skip_all)]
|
||||||
pub async fn close_view_editor(&self, view_id: &str) {
|
pub async fn close_view_editor(&self, view_id: &str) {
|
||||||
self.rev_manager.generate_snapshot().await;
|
self.rev_manager.generate_snapshot().await;
|
||||||
self.database_views.close(view_id).await;
|
self.database_views.close(view_id).await;
|
||||||
@ -175,7 +175,7 @@ impl DatabaseEditor {
|
|||||||
|
|
||||||
self
|
self
|
||||||
.database_views
|
.database_views
|
||||||
.did_update_view_field_type_option(view_id, field_id, old_field_rev)
|
.did_update_field_type_option(view_id, field_id, old_field_rev)
|
||||||
.await?;
|
.await?;
|
||||||
self.notify_did_update_database_field(field_id).await?;
|
self.notify_did_update_database_field(field_id).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -275,7 +275,7 @@ impl DatabaseEditor {
|
|||||||
if is_changed {
|
if is_changed {
|
||||||
match self
|
match self
|
||||||
.database_views
|
.database_views
|
||||||
.did_update_view_field_type_option(view_id, field_id, old_field_rev)
|
.did_update_field_type_option(view_id, field_id, old_field_rev)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(_) => {},
|
Ok(_) => {},
|
||||||
@ -600,7 +600,7 @@ impl DatabaseEditor {
|
|||||||
field_id: &str,
|
field_id: &str,
|
||||||
) -> FlowyResult<Vec<RowSingleCellData>> {
|
) -> FlowyResult<Vec<RowSingleCellData>> {
|
||||||
let view_editor = self.database_views.get_view_editor(view_id).await?;
|
let view_editor = self.database_views.get_view_editor(view_id).await?;
|
||||||
view_editor.get_cells_for_field(field_id).await
|
view_editor.v_get_cells_for_field(field_id).await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "trace", skip_all, err)]
|
#[tracing::instrument(level = "trace", skip_all, err)]
|
||||||
|
@ -222,20 +222,20 @@ impl DatabaseViewEditor {
|
|||||||
.send();
|
.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn sort_rows(&self, rows: &mut Vec<Arc<RowRevision>>) {
|
pub async fn v_sort_rows(&self, rows: &mut Vec<Arc<RowRevision>>) {
|
||||||
self.sort_controller.write().await.sort_rows(rows).await
|
self.sort_controller.write().await.sort_rows(rows).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn filter_rows(&self, _block_id: &str, rows: &mut Vec<Arc<RowRevision>>) {
|
pub async fn v_filter_rows(&self, _block_id: &str, rows: &mut Vec<Arc<RowRevision>>) {
|
||||||
self.filter_controller.filter_row_revs(rows).await;
|
self.filter_controller.filter_row_revs(rows).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn duplicate_view_data(&self) -> FlowyResult<String> {
|
pub async fn v_duplicate_data(&self) -> FlowyResult<String> {
|
||||||
let json_str = self.pad.read().await.json_str()?;
|
let json_str = self.pad.read().await.json_str()?;
|
||||||
Ok(json_str)
|
Ok(json_str)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn will_create_view_row(&self, row_rev: &mut RowRevision, params: &CreateRowParams) {
|
pub async fn v_will_create_row(&self, row_rev: &mut RowRevision, params: &CreateRowParams) {
|
||||||
if params.group_id.is_none() {
|
if params.group_id.is_none() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -248,7 +248,7 @@ impl DatabaseViewEditor {
|
|||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn did_create_view_row(&self, row_pb: &RowPB, params: &CreateRowParams) {
|
pub async fn v_did_create_row(&self, row_pb: &RowPB, params: &CreateRowParams) {
|
||||||
// Send the group notification if the current view has groups
|
// Send the group notification if the current view has groups
|
||||||
match params.group_id.as_ref() {
|
match params.group_id.as_ref() {
|
||||||
None => {},
|
None => {},
|
||||||
@ -275,7 +275,7 @@ impl DatabaseViewEditor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "trace", skip_all)]
|
#[tracing::instrument(level = "trace", skip_all)]
|
||||||
pub async fn did_delete_view_row(&self, row_rev: &RowRevision) {
|
pub async fn v_did_delete_row(&self, row_rev: &RowRevision) {
|
||||||
// Send the group notification if the current view has groups;
|
// Send the group notification if the current view has groups;
|
||||||
let result = self
|
let result = self
|
||||||
.mut_group_controller(|group_controller, field_rev| {
|
.mut_group_controller(|group_controller, field_rev| {
|
||||||
@ -291,7 +291,7 @@ impl DatabaseViewEditor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn did_update_view_row(
|
pub async fn v_did_update_row(
|
||||||
&self,
|
&self,
|
||||||
old_row_rev: Option<Arc<RowRevision>>,
|
old_row_rev: Option<Arc<RowRevision>>,
|
||||||
row_rev: &RowRevision,
|
row_rev: &RowRevision,
|
||||||
@ -339,7 +339,7 @@ impl DatabaseViewEditor {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn move_view_group_row(
|
pub async fn v_move_group_row(
|
||||||
&self,
|
&self,
|
||||||
row_rev: &RowRevision,
|
row_rev: &RowRevision,
|
||||||
row_changeset: &mut RowChangeset,
|
row_changeset: &mut RowChangeset,
|
||||||
@ -377,7 +377,7 @@ impl DatabaseViewEditor {
|
|||||||
}
|
}
|
||||||
/// Only call once after grid view editor initialized
|
/// Only call once after grid view editor initialized
|
||||||
#[tracing::instrument(level = "trace", skip(self))]
|
#[tracing::instrument(level = "trace", skip(self))]
|
||||||
pub async fn load_view_groups(&self) -> FlowyResult<Vec<GroupPB>> {
|
pub async fn v_load_groups(&self) -> FlowyResult<Vec<GroupPB>> {
|
||||||
let groups = self
|
let groups = self
|
||||||
.group_controller
|
.group_controller
|
||||||
.read()
|
.read()
|
||||||
@ -391,7 +391,7 @@ impl DatabaseViewEditor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "trace", skip(self), err)]
|
#[tracing::instrument(level = "trace", skip(self), err)]
|
||||||
pub async fn move_view_group(&self, params: MoveGroupParams) -> FlowyResult<()> {
|
pub async fn v_move_group(&self, params: MoveGroupParams) -> FlowyResult<()> {
|
||||||
self
|
self
|
||||||
.group_controller
|
.group_controller
|
||||||
.write()
|
.write()
|
||||||
@ -430,7 +430,7 @@ impl DatabaseViewEditor {
|
|||||||
|
|
||||||
/// Initialize new group when grouping by a new field
|
/// Initialize new group when grouping by a new field
|
||||||
///
|
///
|
||||||
pub async fn initialize_new_group(&self, params: InsertGroupParams) -> FlowyResult<()> {
|
pub async fn v_initialize_new_group(&self, params: InsertGroupParams) -> FlowyResult<()> {
|
||||||
if let Some(field_rev) = self.delegate.get_field_rev(¶ms.field_id).await {
|
if let Some(field_rev) = self.delegate.get_field_rev(¶ms.field_id).await {
|
||||||
self
|
self
|
||||||
.modify(|pad| {
|
.modify(|pad| {
|
||||||
@ -445,13 +445,13 @@ impl DatabaseViewEditor {
|
|||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
if self.group_controller.read().await.field_id() != params.field_id {
|
if self.group_controller.read().await.field_id() != params.field_id {
|
||||||
self.group_by_view_field(¶ms.field_id).await?;
|
self.v_update_group_setting(¶ms.field_id).await?;
|
||||||
self.notify_did_update_setting().await;
|
self.notify_did_update_setting().await;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_view_group(&self, params: DeleteGroupParams) -> FlowyResult<()> {
|
pub async fn v_delete_group(&self, params: DeleteGroupParams) -> FlowyResult<()> {
|
||||||
self
|
self
|
||||||
.modify(|pad| {
|
.modify(|pad| {
|
||||||
let changeset =
|
let changeset =
|
||||||
@ -461,18 +461,18 @@ impl DatabaseViewEditor {
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_view_setting(&self) -> DatabaseViewSettingPB {
|
pub async fn v_get_setting(&self) -> DatabaseViewSettingPB {
|
||||||
let field_revs = self.delegate.get_field_revs(None).await;
|
let field_revs = self.delegate.get_field_revs(None).await;
|
||||||
make_database_view_setting(&*self.pad.read().await, &field_revs)
|
make_database_view_setting(&*self.pad.read().await, &field_revs)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_all_view_sorts(&self) -> Vec<Arc<SortRevision>> {
|
pub async fn v_get_all_sorts(&self) -> Vec<Arc<SortRevision>> {
|
||||||
let field_revs = self.delegate.get_field_revs(None).await;
|
let field_revs = self.delegate.get_field_revs(None).await;
|
||||||
self.pad.read().await.get_all_sorts(&field_revs)
|
self.pad.read().await.get_all_sorts(&field_revs)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "trace", skip(self), err)]
|
#[tracing::instrument(level = "trace", skip(self), err)]
|
||||||
pub async fn insert_view_sort(&self, params: AlterSortParams) -> FlowyResult<SortRevision> {
|
pub async fn v_insert_sort(&self, params: AlterSortParams) -> FlowyResult<SortRevision> {
|
||||||
let sort_type = SortType::from(¶ms);
|
let sort_type = SortType::from(¶ms);
|
||||||
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 {
|
||||||
@ -514,7 +514,7 @@ impl DatabaseViewEditor {
|
|||||||
Ok(sort_rev)
|
Ok(sort_rev)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_view_sort(&self, params: DeleteSortParams) -> FlowyResult<()> {
|
pub async fn v_delete_sort(&self, params: DeleteSortParams) -> FlowyResult<()> {
|
||||||
let notification = self
|
let notification = self
|
||||||
.sort_controller
|
.sort_controller
|
||||||
.write()
|
.write()
|
||||||
@ -537,8 +537,8 @@ impl DatabaseViewEditor {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_all_view_sorts(&self) -> FlowyResult<()> {
|
pub async fn v_delete_all_sorts(&self) -> FlowyResult<()> {
|
||||||
let all_sorts = self.get_all_view_sorts().await;
|
let all_sorts = self.v_get_all_sorts().await;
|
||||||
self.sort_controller.write().await.delete_all_sorts().await;
|
self.sort_controller.write().await.delete_all_sorts().await;
|
||||||
self
|
self
|
||||||
.modify(|pad| {
|
.modify(|pad| {
|
||||||
@ -556,12 +556,12 @@ impl DatabaseViewEditor {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_all_view_filters(&self) -> Vec<Arc<FilterRevision>> {
|
pub async fn v_get_all_filters(&self) -> Vec<Arc<FilterRevision>> {
|
||||||
let field_revs = self.delegate.get_field_revs(None).await;
|
let field_revs = self.delegate.get_field_revs(None).await;
|
||||||
self.pad.read().await.get_all_filters(&field_revs)
|
self.pad.read().await.get_all_filters(&field_revs)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_view_filters(&self, filter_type: &FilterType) -> Vec<Arc<FilterRevision>> {
|
pub async fn v_get_filters(&self, filter_type: &FilterType) -> Vec<Arc<FilterRevision>> {
|
||||||
let field_type_rev: FieldTypeRevision = filter_type.field_type.clone().into();
|
let field_type_rev: FieldTypeRevision = filter_type.field_type.clone().into();
|
||||||
self
|
self
|
||||||
.pad
|
.pad
|
||||||
@ -571,7 +571,7 @@ impl DatabaseViewEditor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "trace", skip(self), err)]
|
#[tracing::instrument(level = "trace", skip(self), err)]
|
||||||
pub async fn insert_view_filter(&self, params: AlterFilterParams) -> FlowyResult<()> {
|
pub async fn v_insert_filter(&self, params: AlterFilterParams) -> FlowyResult<()> {
|
||||||
let filter_type = FilterType::from(¶ms);
|
let filter_type = FilterType::from(¶ms);
|
||||||
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 {
|
||||||
@ -624,7 +624,7 @@ impl DatabaseViewEditor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "trace", skip(self), err)]
|
#[tracing::instrument(level = "trace", skip(self), err)]
|
||||||
pub async fn delete_view_filter(&self, params: DeleteFilterParams) -> FlowyResult<()> {
|
pub async fn v_delete_filter(&self, params: DeleteFilterParams) -> FlowyResult<()> {
|
||||||
let filter_type = params.filter_type;
|
let filter_type = params.filter_type;
|
||||||
let changeset = self
|
let changeset = self
|
||||||
.filter_controller
|
.filter_controller
|
||||||
@ -649,7 +649,7 @@ impl DatabaseViewEditor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the current calendar settings
|
/// Returns the current calendar settings
|
||||||
pub async fn get_calendar_settings(&self) -> FlowyResult<CalendarSettingsParams> {
|
pub async fn v_get_calendar_settings(&self) -> FlowyResult<CalendarSettingsParams> {
|
||||||
let settings = self
|
let settings = self
|
||||||
.pad
|
.pad
|
||||||
.read()
|
.read()
|
||||||
@ -660,7 +660,10 @@ impl DatabaseViewEditor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Update the calendar settings and send the notification to refresh the UI
|
/// Update the calendar settings and send the notification to refresh the UI
|
||||||
pub async fn update_calendar_settings(&self, params: CalendarSettingsParams) -> FlowyResult<()> {
|
pub async fn v_update_calendar_settings(
|
||||||
|
&self,
|
||||||
|
params: CalendarSettingsParams,
|
||||||
|
) -> FlowyResult<()> {
|
||||||
// Maybe it needs no send notification to refresh the UI
|
// Maybe it needs no send notification to refresh the UI
|
||||||
self
|
self
|
||||||
.modify(|pad| Ok(pad.update_layout_setting(&LayoutRevision::Calendar, ¶ms)?))
|
.modify(|pad| Ok(pad.update_layout_setting(&LayoutRevision::Calendar, ¶ms)?))
|
||||||
@ -669,7 +672,7 @@ impl DatabaseViewEditor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "trace", skip_all, err)]
|
#[tracing::instrument(level = "trace", skip_all, err)]
|
||||||
pub async fn did_update_view_field_type_option(
|
pub async fn v_did_update_field_type_option(
|
||||||
&self,
|
&self,
|
||||||
field_id: &str,
|
field_id: &str,
|
||||||
old_field_rev: Option<Arc<FieldRevision>>,
|
old_field_rev: Option<Arc<FieldRevision>>,
|
||||||
@ -709,7 +712,7 @@ impl DatabaseViewEditor {
|
|||||||
/// * `field_id`:
|
/// * `field_id`:
|
||||||
///
|
///
|
||||||
#[tracing::instrument(level = "debug", skip_all, err)]
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
||||||
pub async fn group_by_view_field(&self, field_id: &str) -> FlowyResult<()> {
|
pub async fn v_update_group_setting(&self, field_id: &str) -> FlowyResult<()> {
|
||||||
if let Some(field_rev) = self.delegate.get_field_rev(field_id).await {
|
if let Some(field_rev) = self.delegate.get_field_rev(field_id).await {
|
||||||
let row_revs = self.delegate.get_row_revs(None).await;
|
let row_revs = self.delegate.get_row_revs(None).await;
|
||||||
let configuration_reader = GroupConfigurationReaderImpl {
|
let configuration_reader = GroupConfigurationReaderImpl {
|
||||||
@ -750,7 +753,7 @@ impl DatabaseViewEditor {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn get_cells_for_field(
|
pub(crate) async fn v_get_cells_for_field(
|
||||||
&self,
|
&self,
|
||||||
field_id: &str,
|
field_id: &str,
|
||||||
) -> FlowyResult<Vec<RowSingleCellData>> {
|
) -> FlowyResult<Vec<RowSingleCellData>> {
|
||||||
@ -758,7 +761,7 @@ impl DatabaseViewEditor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn notify_did_update_setting(&self) {
|
async fn notify_did_update_setting(&self) {
|
||||||
let setting = self.get_view_setting().await;
|
let setting = self.v_get_setting().await;
|
||||||
send_notification(&self.view_id, DatabaseNotification::DidUpdateSettings)
|
send_notification(&self.view_id, DatabaseNotification::DidUpdateSettings)
|
||||||
.payload(setting)
|
.payload(setting)
|
||||||
.send();
|
.send();
|
||||||
|
@ -84,8 +84,8 @@ impl DatabaseViews {
|
|||||||
.get_row_revs(Some(vec![block_id.to_owned()]))
|
.get_row_revs(Some(vec![block_id.to_owned()]))
|
||||||
.await;
|
.await;
|
||||||
if let Ok(view_editor) = self.get_view_editor(view_id).await {
|
if let Ok(view_editor) = self.get_view_editor(view_id).await {
|
||||||
view_editor.filter_rows(block_id, &mut row_revs).await;
|
view_editor.v_filter_rows(block_id, &mut row_revs).await;
|
||||||
view_editor.sort_rows(&mut row_revs).await;
|
view_editor.v_sort_rows(&mut row_revs).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(row_revs)
|
Ok(row_revs)
|
||||||
@ -93,21 +93,21 @@ impl DatabaseViews {
|
|||||||
|
|
||||||
pub async fn duplicate_database_view(&self, view_id: &str) -> FlowyResult<String> {
|
pub async fn duplicate_database_view(&self, view_id: &str) -> FlowyResult<String> {
|
||||||
let editor = self.get_view_editor(view_id).await?;
|
let editor = self.get_view_editor(view_id).await?;
|
||||||
let view_data = editor.duplicate_view_data().await?;
|
let view_data = editor.v_duplicate_data().await?;
|
||||||
Ok(view_data)
|
Ok(view_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// When the row was created, we may need to modify the [RowRevision] according to the [CreateRowParams].
|
/// When the row was created, we may need to modify the [RowRevision] according to the [CreateRowParams].
|
||||||
pub async fn will_create_row(&self, row_rev: &mut RowRevision, params: &CreateRowParams) {
|
pub async fn will_create_row(&self, row_rev: &mut RowRevision, params: &CreateRowParams) {
|
||||||
for view_editor in self.view_editors.read().await.values() {
|
for view_editor in self.view_editors.read().await.values() {
|
||||||
view_editor.will_create_view_row(row_rev, params).await;
|
view_editor.v_will_create_row(row_rev, params).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Notify the view that the row was created. For the moment, the view is just sending notifications.
|
/// Notify the view that the row was created. For the moment, the view is just sending notifications.
|
||||||
pub async fn did_create_row(&self, row_pb: &RowPB, params: &CreateRowParams) {
|
pub async fn did_create_row(&self, row_pb: &RowPB, params: &CreateRowParams) {
|
||||||
for view_editor in self.view_editors.read().await.values() {
|
for view_editor in self.view_editors.read().await.values() {
|
||||||
view_editor.did_create_view_row(row_pb, params).await;
|
view_editor.v_did_create_row(row_pb, params).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,7 +120,7 @@ impl DatabaseViews {
|
|||||||
Some((_, row_rev)) => {
|
Some((_, row_rev)) => {
|
||||||
for view_editor in self.view_editors.read().await.values() {
|
for view_editor in self.view_editors.read().await.values() {
|
||||||
view_editor
|
view_editor
|
||||||
.did_update_view_row(old_row_rev.clone(), &row_rev)
|
.v_did_update_row(old_row_rev.clone(), &row_rev)
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -129,24 +129,24 @@ impl DatabaseViews {
|
|||||||
|
|
||||||
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_editor = self.get_view_editor(view_id).await?;
|
let view_editor = self.get_view_editor(view_id).await?;
|
||||||
view_editor.group_by_view_field(field_id).await?;
|
view_editor.v_update_group_setting(field_id).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn did_delete_row(&self, row_rev: Arc<RowRevision>) {
|
pub async fn did_delete_row(&self, row_rev: Arc<RowRevision>) {
|
||||||
for view_editor in self.view_editors.read().await.values() {
|
for view_editor in self.view_editors.read().await.values() {
|
||||||
view_editor.did_delete_view_row(&row_rev).await;
|
view_editor.v_did_delete_row(&row_rev).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_setting(&self, view_id: &str) -> FlowyResult<DatabaseViewSettingPB> {
|
pub async fn get_setting(&self, view_id: &str) -> FlowyResult<DatabaseViewSettingPB> {
|
||||||
let view_editor = self.get_view_editor(view_id).await?;
|
let view_editor = self.get_view_editor(view_id).await?;
|
||||||
Ok(view_editor.get_view_setting().await)
|
Ok(view_editor.v_get_setting().await)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_all_filters(&self, view_id: &str) -> FlowyResult<Vec<Arc<FilterRevision>>> {
|
pub async fn get_all_filters(&self, view_id: &str) -> FlowyResult<Vec<Arc<FilterRevision>>> {
|
||||||
let view_editor = self.get_view_editor(view_id).await?;
|
let view_editor = self.get_view_editor(view_id).await?;
|
||||||
Ok(view_editor.get_all_view_filters().await)
|
Ok(view_editor.v_get_all_filters().await)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_filters(
|
pub async fn get_filters(
|
||||||
@ -155,58 +155,58 @@ impl DatabaseViews {
|
|||||||
filter_id: &FilterType,
|
filter_id: &FilterType,
|
||||||
) -> FlowyResult<Vec<Arc<FilterRevision>>> {
|
) -> FlowyResult<Vec<Arc<FilterRevision>>> {
|
||||||
let view_editor = self.get_view_editor(view_id).await?;
|
let view_editor = self.get_view_editor(view_id).await?;
|
||||||
Ok(view_editor.get_view_filters(filter_id).await)
|
Ok(view_editor.v_get_filters(filter_id).await)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create_or_update_filter(&self, params: AlterFilterParams) -> FlowyResult<()> {
|
pub async fn create_or_update_filter(&self, params: AlterFilterParams) -> FlowyResult<()> {
|
||||||
let view_editor = self.get_view_editor(¶ms.view_id).await?;
|
let view_editor = self.get_view_editor(¶ms.view_id).await?;
|
||||||
view_editor.insert_view_filter(params).await
|
view_editor.v_insert_filter(params).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_filter(&self, params: DeleteFilterParams) -> FlowyResult<()> {
|
pub async fn delete_filter(&self, params: DeleteFilterParams) -> FlowyResult<()> {
|
||||||
let view_editor = self.get_view_editor(¶ms.view_id).await?;
|
let view_editor = self.get_view_editor(¶ms.view_id).await?;
|
||||||
view_editor.delete_view_filter(params).await
|
view_editor.v_delete_filter(params).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_all_sorts(&self, view_id: &str) -> FlowyResult<Vec<Arc<SortRevision>>> {
|
pub async fn get_all_sorts(&self, view_id: &str) -> FlowyResult<Vec<Arc<SortRevision>>> {
|
||||||
let view_editor = self.get_view_editor(view_id).await?;
|
let view_editor = self.get_view_editor(view_id).await?;
|
||||||
Ok(view_editor.get_all_view_sorts().await)
|
Ok(view_editor.v_get_all_sorts().await)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create_or_update_sort(&self, params: AlterSortParams) -> FlowyResult<SortRevision> {
|
pub async fn create_or_update_sort(&self, params: AlterSortParams) -> FlowyResult<SortRevision> {
|
||||||
let view_editor = self.get_view_editor(¶ms.view_id).await?;
|
let view_editor = self.get_view_editor(¶ms.view_id).await?;
|
||||||
view_editor.insert_view_sort(params).await
|
view_editor.v_insert_sort(params).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_all_sorts(&self, view_id: &str) -> FlowyResult<()> {
|
pub async fn delete_all_sorts(&self, view_id: &str) -> FlowyResult<()> {
|
||||||
let view_editor = self.get_view_editor(view_id).await?;
|
let view_editor = self.get_view_editor(view_id).await?;
|
||||||
view_editor.delete_all_view_sorts().await
|
view_editor.v_delete_all_sorts().await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_sort(&self, params: DeleteSortParams) -> FlowyResult<()> {
|
pub async fn delete_sort(&self, params: DeleteSortParams) -> FlowyResult<()> {
|
||||||
let view_editor = self.get_view_editor(¶ms.view_id).await?;
|
let view_editor = self.get_view_editor(¶ms.view_id).await?;
|
||||||
view_editor.delete_view_sort(params).await
|
view_editor.v_delete_sort(params).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn load_groups(&self, view_id: &str) -> FlowyResult<RepeatedGroupPB> {
|
pub async fn load_groups(&self, view_id: &str) -> FlowyResult<RepeatedGroupPB> {
|
||||||
let view_editor = self.get_view_editor(view_id).await?;
|
let view_editor = self.get_view_editor(view_id).await?;
|
||||||
let groups = view_editor.load_view_groups().await?;
|
let groups = view_editor.v_load_groups().await?;
|
||||||
Ok(RepeatedGroupPB { items: groups })
|
Ok(RepeatedGroupPB { items: groups })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn insert_or_update_group(&self, params: InsertGroupParams) -> FlowyResult<()> {
|
pub async fn insert_or_update_group(&self, params: InsertGroupParams) -> FlowyResult<()> {
|
||||||
let view_editor = self.get_view_editor(¶ms.view_id).await?;
|
let view_editor = self.get_view_editor(¶ms.view_id).await?;
|
||||||
view_editor.initialize_new_group(params).await
|
view_editor.v_initialize_new_group(params).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_group(&self, params: DeleteGroupParams) -> FlowyResult<()> {
|
pub async fn delete_group(&self, params: DeleteGroupParams) -> FlowyResult<()> {
|
||||||
let view_editor = self.get_view_editor(¶ms.view_id).await?;
|
let view_editor = self.get_view_editor(¶ms.view_id).await?;
|
||||||
view_editor.delete_view_group(params).await
|
view_editor.v_delete_group(params).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn move_group(&self, params: MoveGroupParams) -> FlowyResult<()> {
|
pub async fn move_group(&self, params: MoveGroupParams) -> FlowyResult<()> {
|
||||||
let view_editor = self.get_view_editor(¶ms.view_id).await?;
|
let view_editor = self.get_view_editor(¶ms.view_id).await?;
|
||||||
view_editor.move_view_group(params).await?;
|
view_editor.v_move_group(params).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,7 +224,7 @@ impl DatabaseViews {
|
|||||||
let mut row_changeset = RowChangeset::new(row_rev.id.clone());
|
let mut row_changeset = RowChangeset::new(row_rev.id.clone());
|
||||||
let view_editor = self.get_view_editor(view_id).await?;
|
let view_editor = self.get_view_editor(view_id).await?;
|
||||||
view_editor
|
view_editor
|
||||||
.move_view_group_row(
|
.v_move_group_row(
|
||||||
&row_rev,
|
&row_rev,
|
||||||
&mut row_changeset,
|
&mut row_changeset,
|
||||||
&to_group_id,
|
&to_group_id,
|
||||||
@ -246,20 +246,22 @@ impl DatabaseViews {
|
|||||||
///
|
///
|
||||||
/// * `field_id`: the id of the field in current view
|
/// * `field_id`: the id of the field in current view
|
||||||
///
|
///
|
||||||
#[tracing::instrument(level = "trace", skip(self), err)]
|
#[tracing::instrument(level = "debug", skip(self, old_field_rev), err)]
|
||||||
pub async fn did_update_view_field_type_option(
|
pub async fn did_update_field_type_option(
|
||||||
&self,
|
&self,
|
||||||
view_id: &str,
|
view_id: &str,
|
||||||
field_id: &str,
|
field_id: &str,
|
||||||
old_field_rev: Option<Arc<FieldRevision>>,
|
old_field_rev: Option<Arc<FieldRevision>>,
|
||||||
) -> FlowyResult<()> {
|
) -> FlowyResult<()> {
|
||||||
let view_editor = self.get_view_editor(view_id).await?;
|
let view_editor = self.get_view_editor(view_id).await?;
|
||||||
|
// If the id of the grouping field is equal to the updated field's id, then we need to
|
||||||
|
// update the group setting
|
||||||
if view_editor.group_id().await == field_id {
|
if view_editor.group_id().await == field_id {
|
||||||
view_editor.group_by_view_field(field_id).await?;
|
view_editor.v_update_group_setting(field_id).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
view_editor
|
view_editor
|
||||||
.did_update_view_field_type_option(field_id, old_field_rev)
|
.v_did_update_field_type_option(field_id, old_field_rev)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -269,6 +271,7 @@ impl DatabaseViews {
|
|||||||
if let Some(editor) = self.view_editors.read().await.get(view_id) {
|
if let Some(editor) = self.view_editors.read().await.get(view_id) {
|
||||||
return Ok(editor);
|
return Ok(editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
tracing::trace!("{:p} create view:{} editor", self, view_id);
|
tracing::trace!("{:p} create view:{} editor", self, view_id);
|
||||||
let mut view_editors = self.view_editors.write().await;
|
let mut view_editors = self.view_editors.write().await;
|
||||||
let editor = Arc::new(self.make_view_editor(view_id).await?);
|
let editor = Arc::new(self.make_view_editor(view_id).await?);
|
||||||
|
@ -26,7 +26,17 @@ use std::sync::Arc;
|
|||||||
/// * `configuration_reader`: a reader used to read the group configuration from disk
|
/// * `configuration_reader`: a reader used to read the group configuration from disk
|
||||||
/// * `configuration_writer`: as writer used to write the group configuration to disk
|
/// * `configuration_writer`: as writer used to write the group configuration to disk
|
||||||
///
|
///
|
||||||
#[tracing::instrument(level = "trace", skip_all, err)]
|
#[tracing::instrument(
|
||||||
|
level = "debug",
|
||||||
|
skip(
|
||||||
|
row_revs,
|
||||||
|
configuration_reader,
|
||||||
|
configuration_writer,
|
||||||
|
grouping_field_rev
|
||||||
|
),
|
||||||
|
fields(grouping_field_id=%grouping_field_rev.id, grouping_field_type)
|
||||||
|
err
|
||||||
|
)]
|
||||||
pub async fn make_group_controller<R, W>(
|
pub async fn make_group_controller<R, W>(
|
||||||
view_id: String,
|
view_id: String,
|
||||||
grouping_field_rev: Arc<FieldRevision>,
|
grouping_field_rev: Arc<FieldRevision>,
|
||||||
@ -39,6 +49,7 @@ where
|
|||||||
W: GroupConfigurationWriter,
|
W: GroupConfigurationWriter,
|
||||||
{
|
{
|
||||||
let grouping_field_type: FieldType = grouping_field_rev.ty.into();
|
let grouping_field_type: FieldType = grouping_field_rev.ty.into();
|
||||||
|
tracing::Span::current().record("grouping_field_type", &format!("{}", grouping_field_type));
|
||||||
|
|
||||||
let mut group_controller: Box<dyn GroupController>;
|
let mut group_controller: Box<dyn GroupController>;
|
||||||
let configuration_reader = Arc::new(configuration_reader);
|
let configuration_reader = Arc::new(configuration_reader);
|
||||||
@ -99,17 +110,31 @@ where
|
|||||||
Ok(group_controller)
|
Ok(group_controller)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
pub fn find_grouping_field(
|
pub fn find_grouping_field(
|
||||||
field_revs: &[Arc<FieldRevision>],
|
field_revs: &[Arc<FieldRevision>],
|
||||||
_layout: &LayoutRevision,
|
_layout: &LayoutRevision,
|
||||||
) -> Option<Arc<FieldRevision>> {
|
) -> Option<Arc<FieldRevision>> {
|
||||||
field_revs
|
let mut groupable_field_revs = field_revs
|
||||||
.iter()
|
.iter()
|
||||||
.find(|field_rev| {
|
.flat_map(|field_rev| {
|
||||||
let field_type: FieldType = field_rev.ty.into();
|
let field_type: FieldType = field_rev.ty.into();
|
||||||
field_type.can_be_group()
|
match field_type.can_be_group() {
|
||||||
|
true => Some(field_rev.clone()),
|
||||||
|
false => None,
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.cloned()
|
.collect::<Vec<Arc<FieldRevision>>>();
|
||||||
|
|
||||||
|
if groupable_field_revs.is_empty() {
|
||||||
|
// If there is not groupable fields then we use the primary field.
|
||||||
|
field_revs
|
||||||
|
.iter()
|
||||||
|
.find(|field_rev| field_rev.is_primary)
|
||||||
|
.cloned()
|
||||||
|
} else {
|
||||||
|
Some(groupable_field_revs.remove(0))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a `default` group configuration for the [FieldRevision]
|
/// Returns a `default` group configuration for the [FieldRevision]
|
||||||
|
@ -189,21 +189,21 @@ diesel::table! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
diesel::allow_tables_to_appear_in_same_query!(
|
diesel::allow_tables_to_appear_in_same_query!(
|
||||||
app_table,
|
app_table,
|
||||||
database_refs,
|
database_refs,
|
||||||
document_rev_snapshot,
|
document_rev_snapshot,
|
||||||
document_rev_table,
|
document_rev_table,
|
||||||
folder_rev_snapshot,
|
folder_rev_snapshot,
|
||||||
grid_block_index_table,
|
grid_block_index_table,
|
||||||
grid_meta_rev_table,
|
grid_meta_rev_table,
|
||||||
grid_rev_snapshot,
|
grid_rev_snapshot,
|
||||||
grid_rev_table,
|
grid_rev_table,
|
||||||
grid_view_rev_table,
|
grid_view_rev_table,
|
||||||
kv_table,
|
kv_table,
|
||||||
rev_snapshot,
|
rev_snapshot,
|
||||||
rev_table,
|
rev_table,
|
||||||
trash_table,
|
trash_table,
|
||||||
user_table,
|
user_table,
|
||||||
view_table,
|
view_table,
|
||||||
workspace_table,
|
workspace_table,
|
||||||
);
|
);
|
||||||
|
@ -189,22 +189,35 @@ script = [
|
|||||||
]
|
]
|
||||||
script_runner = "@duckscript"
|
script_runner = "@duckscript"
|
||||||
|
|
||||||
[tasks.build-test-lib]
|
[tasks.build_test_backend]
|
||||||
category = "Build"
|
category = "Build"
|
||||||
dependencies = ["env_check"]
|
dependencies = ["env_check"]
|
||||||
run_task = { name = [
|
run_task = { name = [
|
||||||
"setup-test-crate-type",
|
"setup-test-crate-type",
|
||||||
"build-test-backend",
|
"compile_test_backend",
|
||||||
"copy-to-sandbox-folder",
|
"copy-to-sandbox-folder",
|
||||||
"restore-test-crate-type",
|
"restore-test-crate-type",
|
||||||
] }
|
] }
|
||||||
|
|
||||||
[tasks.build-test-backend]
|
[tasks.compile_test_backend]
|
||||||
mac_alias = "build-test-backend-default"
|
mac_alias = "compile_test_backend_default"
|
||||||
windows_alias = "build-test-backend-widnows"
|
windows_alias = "compile_test_backend_widnows"
|
||||||
linux_alias = "build-test-backend-default"
|
linux_alias = "compile_test_backend_default"
|
||||||
|
|
||||||
[tasks.build-test-backend-default]
|
[tasks.compile_test_backend_default]
|
||||||
|
private = true
|
||||||
|
script = [
|
||||||
|
"""
|
||||||
|
cd rust-lib/
|
||||||
|
rustup show
|
||||||
|
echo RUST_LOG=${RUST_LOG} cargo build --package=dart-ffi --target ${TEST_COMPILE_TARGET} --features "${FLUTTER_DESKTOP_FEATURES}"
|
||||||
|
RUST_LOG=${RUST_LOG} cargo build --package=dart-ffi --target ${TEST_COMPILE_TARGET} --features "${FLUTTER_DESKTOP_FEATURES}"
|
||||||
|
cd ../
|
||||||
|
""",
|
||||||
|
]
|
||||||
|
script_runner = "@shell"
|
||||||
|
|
||||||
|
[tasks.compile_test_backend_widnows]
|
||||||
private = true
|
private = true
|
||||||
script = [
|
script = [
|
||||||
"""
|
"""
|
||||||
@ -217,19 +230,6 @@ script = [
|
|||||||
]
|
]
|
||||||
script_runner = "@shell"
|
script_runner = "@shell"
|
||||||
|
|
||||||
[tasks.build-test-backend-widnows]
|
|
||||||
private = true
|
|
||||||
script = [
|
|
||||||
"""
|
|
||||||
cd rust-lib/
|
|
||||||
rustup show
|
|
||||||
echo cargo build --package=dart-ffi --target ${TEST_COMPILE_TARGET} --features "${FLUTTER_DESKTOP_FEATURES}"
|
|
||||||
RUST_LOG=${TEST_RUST_LOG} cargo build --package=dart-ffi --target ${TEST_COMPILE_TARGET} --features "${FLUTTER_DESKTOP_FEATURES}"
|
|
||||||
cd ../
|
|
||||||
""",
|
|
||||||
]
|
|
||||||
script_runner = "@shell"
|
|
||||||
|
|
||||||
[tasks.copy-to-sandbox-folder]
|
[tasks.copy-to-sandbox-folder]
|
||||||
mac_alias = "copy-to-sandbox-folder-default"
|
mac_alias = "copy-to-sandbox-folder-default"
|
||||||
windows_alias = "copy-to-sandbox-folder-windows"
|
windows_alias = "copy-to-sandbox-folder-windows"
|
||||||
|
@ -1,29 +1,29 @@
|
|||||||
|
|
||||||
[tasks.dart_unit_test]
|
[tasks.dart_unit_test]
|
||||||
script = '''
|
script = '''
|
||||||
cargo make --profile test-macos dart_unit_test_inner
|
cargo make --profile test-macos dart_unit_test_impl
|
||||||
'''
|
'''
|
||||||
script_runner = "@shell"
|
script_runner = "@shell"
|
||||||
|
|
||||||
[tasks.dart_unit_test.windows]
|
[tasks.dart_unit_test.windows]
|
||||||
script = '''
|
script = '''
|
||||||
cargo make --profile test-windows dart_unit_test_inner
|
cargo make --profile test-windows dart_unit_test_impl
|
||||||
'''
|
'''
|
||||||
script_runner = "@shell"
|
script_runner = "@shell"
|
||||||
|
|
||||||
[tasks.dart_unit_test.linux]
|
[tasks.dart_unit_test.linux]
|
||||||
script = '''
|
script = '''
|
||||||
cargo make --profile test-linux dart_unit_test_inner
|
cargo make --profile test-linux dart_unit_test_impl
|
||||||
'''
|
'''
|
||||||
script_runner = "@shell"
|
script_runner = "@shell"
|
||||||
|
|
||||||
[tasks.dart_unit_test_inner]
|
[tasks.dart_unit_test_impl]
|
||||||
env = { RUST_LOG = "info", TEST_RUST_LOG = "info" }
|
env = { RUST_LOG = "info" }
|
||||||
dependencies = ["build-test-lib"]
|
dependencies = ["build_test_backend"]
|
||||||
description = "Run flutter unit tests"
|
description = "Run flutter unit tests"
|
||||||
script = '''
|
script = '''
|
||||||
cd appflowy_flutter
|
cd appflowy_flutter
|
||||||
flutter test --dart-define=RUST_LOG=${TEST_RUST_LOG} -j, --concurrency=1
|
flutter test --dart-define=RUST_LOG=${RUST_LOG} -j, --concurrency=1
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[tasks.rust_unit_test]
|
[tasks.rust_unit_test]
|
||||||
|
@ -115,7 +115,7 @@ pub struct FieldRevision {
|
|||||||
#[serde(with = "indexmap::serde_seq")]
|
#[serde(with = "indexmap::serde_seq")]
|
||||||
pub type_options: IndexMap<String, String>,
|
pub type_options: IndexMap<String, String>,
|
||||||
|
|
||||||
#[serde(default = "DEFAULT_IS_PRIMARY")]
|
#[serde(default = "DEFAULT_IS_PRIMARY_VALUE")]
|
||||||
pub is_primary: bool,
|
pub is_primary: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,7 +125,7 @@ impl AsRef<FieldRevision> for FieldRevision {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const DEFAULT_IS_PRIMARY: fn() -> bool = || false;
|
const DEFAULT_IS_PRIMARY_VALUE: fn() -> bool = || false;
|
||||||
|
|
||||||
impl FieldRevision {
|
impl FieldRevision {
|
||||||
pub fn new<T: Into<FieldTypeRevision>>(
|
pub fn new<T: Into<FieldTypeRevision>>(
|
||||||
|
Loading…
Reference in New Issue
Block a user