mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
docs: update code documentation (#1804)
* docs: update code documentation * chore: fix bloc test * chore: reduce lock granularity * chore: fix bloc test
This commit is contained in:
parent
4d5063de6a
commit
1df2619c9f
2
frontend/.vscode/tasks.json
vendored
2
frontend/.vscode/tasks.json
vendored
@ -58,7 +58,7 @@
|
||||
"label": "AF: Build Appflowy Core",
|
||||
"type": "shell",
|
||||
"windows": {
|
||||
"command": "cargo make --profile development-windows appflowy-core-dev"
|
||||
"command": "cargo make --profile development-windows-x86 appflowy-core-dev"
|
||||
},
|
||||
"linux": {
|
||||
"command": "cargo make --profile \"development-linux-$(uname -m)\" appflowy-core-dev"
|
||||
|
@ -34,7 +34,7 @@ class DocumentPluginBuilder extends PluginBuilder {
|
||||
PluginType get pluginType => PluginType.editor;
|
||||
|
||||
@override
|
||||
ViewDataFormatPB get dataFormatType => ViewDataFormatPB.TreeFormat;
|
||||
ViewDataFormatPB get dataFormatType => ViewDataFormatPB.NodeFormat;
|
||||
}
|
||||
|
||||
class DocumentPlugin extends Plugin<int> {
|
||||
|
@ -147,8 +147,10 @@ class SelectOptionCellEditorBloc
|
||||
}
|
||||
|
||||
void _filterOption(String optionName, Emitter<SelectOptionEditorState> emit) {
|
||||
final _MakeOptionResult result =
|
||||
_makeOptions(Some(optionName), state.allOptions);
|
||||
final _MakeOptionResult result = _makeOptions(
|
||||
Some(optionName),
|
||||
state.allOptions,
|
||||
);
|
||||
emit(state.copyWith(
|
||||
filter: Some(optionName),
|
||||
options: result.options,
|
||||
@ -159,6 +161,7 @@ class SelectOptionCellEditorBloc
|
||||
Future<void> _loadOptions() async {
|
||||
final result = await _selectOptionService.getOptionContext();
|
||||
if (isClosed) {
|
||||
Log.warn("Unexpected closing the bloc");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -177,7 +180,9 @@ class SelectOptionCellEditorBloc
|
||||
}
|
||||
|
||||
_MakeOptionResult _makeOptions(
|
||||
Option<String> filter, List<SelectOptionPB> allOptions) {
|
||||
Option<String> filter,
|
||||
List<SelectOptionPB> allOptions,
|
||||
) {
|
||||
final List<SelectOptionPB> options = List.from(allOptions);
|
||||
Option<String> createOption = filter;
|
||||
|
||||
|
@ -12,7 +12,7 @@ import 'type_option_context.dart';
|
||||
class TypeOptionDataController {
|
||||
final String databaseId;
|
||||
final IFieldTypeOptionLoader loader;
|
||||
late TypeOptionPB _data;
|
||||
late TypeOptionPB _typeOptiondata;
|
||||
final PublishNotifier<FieldPB> _fieldNotifier = PublishNotifier();
|
||||
|
||||
/// Returns a [TypeOptionDataController] used to modify the specified
|
||||
@ -27,7 +27,7 @@ class TypeOptionDataController {
|
||||
FieldInfo? fieldInfo,
|
||||
}) {
|
||||
if (fieldInfo != null) {
|
||||
_data = TypeOptionPB.create()
|
||||
_typeOptiondata = TypeOptionPB.create()
|
||||
..databaseId = databaseId
|
||||
..field_2 = fieldInfo.field;
|
||||
}
|
||||
@ -38,7 +38,7 @@ class TypeOptionDataController {
|
||||
return result.fold(
|
||||
(data) {
|
||||
data.freeze();
|
||||
_data = data;
|
||||
_typeOptiondata = data;
|
||||
_fieldNotifier.value = data.field_2;
|
||||
return left(data);
|
||||
},
|
||||
@ -50,28 +50,28 @@ class TypeOptionDataController {
|
||||
}
|
||||
|
||||
FieldPB get field {
|
||||
return _data.field_2;
|
||||
return _typeOptiondata.field_2;
|
||||
}
|
||||
|
||||
T getTypeOption<T>(TypeOptionDataParser<T> parser) {
|
||||
return parser.fromBuffer(_data.typeOptionData);
|
||||
return parser.fromBuffer(_typeOptiondata.typeOptionData);
|
||||
}
|
||||
|
||||
set fieldName(String name) {
|
||||
_data = _data.rebuild((rebuildData) {
|
||||
_typeOptiondata = _typeOptiondata.rebuild((rebuildData) {
|
||||
rebuildData.field_2 = rebuildData.field_2.rebuild((rebuildField) {
|
||||
rebuildField.name = name;
|
||||
});
|
||||
});
|
||||
|
||||
_fieldNotifier.value = _data.field_2;
|
||||
_fieldNotifier.value = _typeOptiondata.field_2;
|
||||
|
||||
FieldService(databaseId: databaseId, fieldId: field.id)
|
||||
.updateField(name: name);
|
||||
}
|
||||
|
||||
set typeOptionData(List<int> typeOptionData) {
|
||||
_data = _data.rebuild((rebuildData) {
|
||||
_typeOptiondata = _typeOptiondata.rebuild((rebuildData) {
|
||||
if (typeOptionData.isNotEmpty) {
|
||||
rebuildData.typeOptionData = typeOptionData;
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ abstract class PluginBuilder {
|
||||
|
||||
PluginType get pluginType;
|
||||
|
||||
ViewDataFormatPB get dataFormatType => ViewDataFormatPB.TreeFormat;
|
||||
ViewDataFormatPB get dataFormatType => ViewDataFormatPB.NodeFormat;
|
||||
|
||||
ViewLayoutTypePB? get layoutType => ViewLayoutTypePB.Document;
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ class AppService {
|
||||
..to = toIndex
|
||||
..ty = MoveFolderItemType.MoveView;
|
||||
|
||||
return FolderEventMoveFolderItem(payload).send();
|
||||
return FolderEventMoveItem(payload).send();
|
||||
}
|
||||
|
||||
Future<List<Tuple2<AppPB, List<ViewPB>>>> fetchViews(
|
||||
|
@ -65,6 +65,6 @@ class WorkspaceService {
|
||||
..to = toIndex
|
||||
..ty = MoveFolderItemType.MoveApp;
|
||||
|
||||
return FolderEventMoveFolderItem(payload).send();
|
||||
return FolderEventMoveItem(payload).send();
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ void main() {
|
||||
final gridGroupBloc = GridGroupBloc(
|
||||
viewId: context.gridView.id,
|
||||
fieldController: context.fieldController,
|
||||
);
|
||||
)..add(const GridGroupEvent.initial());
|
||||
gridGroupBloc.add(GridGroupEvent.setGroupByField(
|
||||
checkboxField.id,
|
||||
checkboxField.fieldType,
|
||||
|
@ -14,7 +14,7 @@ void main() {
|
||||
boardTest = await AppFlowyBoardTest.ensureInitialized();
|
||||
});
|
||||
|
||||
test('group by multi select with no options test', () async {
|
||||
test('no status group name test', () async {
|
||||
final context = await boardTest.createTestBoard();
|
||||
|
||||
// create multi-select field
|
||||
@ -27,7 +27,9 @@ void main() {
|
||||
final gridGroupBloc = GridGroupBloc(
|
||||
viewId: context.gridView.id,
|
||||
fieldController: context.fieldController,
|
||||
);
|
||||
)..add(const GridGroupEvent.initial());
|
||||
await boardResponseFuture();
|
||||
|
||||
gridGroupBloc.add(GridGroupEvent.setGroupByField(
|
||||
multiSelectField.id,
|
||||
multiSelectField.fieldType,
|
||||
@ -72,7 +74,9 @@ void main() {
|
||||
final gridGroupBloc = GridGroupBloc(
|
||||
viewId: context.gridView.id,
|
||||
fieldController: context.fieldController,
|
||||
);
|
||||
)..add(const GridGroupEvent.initial());
|
||||
await boardResponseFuture();
|
||||
|
||||
gridGroupBloc.add(GridGroupEvent.setGroupByField(
|
||||
multiSelectField.id,
|
||||
multiSelectField.fieldType,
|
||||
|
@ -64,15 +64,24 @@ void main() {
|
||||
|
||||
bloc.add(const SelectOptionEditorEvent.newOption("A"));
|
||||
await gridResponseFuture();
|
||||
assert(bloc.state.options.length == 1,
|
||||
"Expect 1 but receive ${bloc.state.options.length}, Options: ${bloc.state.options}");
|
||||
|
||||
bloc.add(const SelectOptionEditorEvent.newOption("B"));
|
||||
await gridResponseFuture();
|
||||
assert(bloc.state.options.length == 2,
|
||||
"Expect 2 but receive ${bloc.state.options.length}, Options: ${bloc.state.options}");
|
||||
|
||||
bloc.add(const SelectOptionEditorEvent.newOption("C"));
|
||||
await gridResponseFuture();
|
||||
assert(bloc.state.options.length == 3,
|
||||
"Expect 3 but receive ${bloc.state.options.length}. Options: ${bloc.state.options}");
|
||||
|
||||
bloc.add(const SelectOptionEditorEvent.deleteAllOptions());
|
||||
await gridResponseFuture();
|
||||
|
||||
assert(bloc.state.options.isEmpty);
|
||||
assert(bloc.state.options.isEmpty,
|
||||
"Expect empty but receive ${bloc.state.options.length}");
|
||||
});
|
||||
|
||||
test('select/unselect option', () async {
|
||||
@ -161,18 +170,41 @@ void main() {
|
||||
|
||||
bloc.add(const SelectOptionEditorEvent.newOption("abcd"));
|
||||
await gridResponseFuture();
|
||||
expect(
|
||||
bloc.state.options.length,
|
||||
1,
|
||||
reason: "Options: ${bloc.state.options}",
|
||||
);
|
||||
|
||||
bloc.add(const SelectOptionEditorEvent.newOption("aaaa"));
|
||||
await gridResponseFuture();
|
||||
expect(
|
||||
bloc.state.options.length,
|
||||
2,
|
||||
reason: "Options: ${bloc.state.options}",
|
||||
);
|
||||
|
||||
bloc.add(const SelectOptionEditorEvent.newOption("defg"));
|
||||
await gridResponseFuture();
|
||||
expect(
|
||||
bloc.state.options.length,
|
||||
3,
|
||||
reason: "Options: ${bloc.state.options}",
|
||||
);
|
||||
|
||||
bloc.add(const SelectOptionEditorEvent.filterOption("a"));
|
||||
await gridResponseFuture();
|
||||
|
||||
expect(bloc.state.options.length, 2);
|
||||
expect(bloc.state.allOptions.length, 3);
|
||||
expect(
|
||||
bloc.state.options.length,
|
||||
2,
|
||||
reason: "Options: ${bloc.state.options}",
|
||||
);
|
||||
expect(
|
||||
bloc.state.allOptions.length,
|
||||
3,
|
||||
reason: "Options: ${bloc.state.options}",
|
||||
);
|
||||
expect(bloc.state.createOption, const Some("a"));
|
||||
expect(bloc.state.filter, const Some("a"));
|
||||
});
|
||||
|
@ -1,6 +1,5 @@
|
||||
import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/prelude.dart';
|
||||
import 'package:bloc_test/bloc_test.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database/field_entities.pb.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import '../util.dart';
|
||||
@ -28,75 +27,69 @@ void main() {
|
||||
gridTest = await AppFlowyGridTest.ensureInitialized();
|
||||
});
|
||||
|
||||
group('$FieldEditorBloc', () {
|
||||
late FieldEditorBloc editorBloc;
|
||||
test('rename field', () async {
|
||||
final editorBloc = await makeEditorBloc(gridTest);
|
||||
editorBloc.add(const FieldEditorEvent.updateName('Hello world'));
|
||||
await gridResponseFuture();
|
||||
|
||||
setUp(() async {
|
||||
final context = await gridTest.createTestGrid();
|
||||
final fieldInfo = context.singleSelectFieldContext();
|
||||
final loader = FieldTypeOptionLoader(
|
||||
databaseId: context.gridView.id,
|
||||
field: fieldInfo.field,
|
||||
);
|
||||
|
||||
editorBloc = FieldEditorBloc(
|
||||
databaseId: context.gridView.id,
|
||||
fieldName: fieldInfo.name,
|
||||
isGroupField: fieldInfo.isGroupField,
|
||||
loader: loader,
|
||||
)..add(const FieldEditorEvent.initial());
|
||||
|
||||
await gridResponseFuture();
|
||||
});
|
||||
|
||||
blocTest<FieldEditorBloc, FieldEditorState>(
|
||||
"rename field",
|
||||
build: () => editorBloc,
|
||||
act: (bloc) async {
|
||||
editorBloc.add(const FieldEditorEvent.updateName('Hello world'));
|
||||
},
|
||||
wait: gridResponseDuration(),
|
||||
verify: (bloc) {
|
||||
bloc.state.field.fold(
|
||||
() => throw Exception("The field should not be none"),
|
||||
(field) {
|
||||
assert(field.name == 'Hello world');
|
||||
},
|
||||
);
|
||||
editorBloc.state.field.fold(
|
||||
() => throw Exception("The field should not be none"),
|
||||
(field) {
|
||||
assert(field.name == 'Hello world');
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
blocTest<FieldEditorBloc, FieldEditorState>(
|
||||
"switch to text field",
|
||||
build: () => editorBloc,
|
||||
act: (bloc) async {
|
||||
editorBloc
|
||||
.add(const FieldEditorEvent.switchToField(FieldType.RichText));
|
||||
},
|
||||
wait: gridResponseDuration(),
|
||||
verify: (bloc) {
|
||||
bloc.state.field.fold(
|
||||
() => throw Exception("The field should not be none"),
|
||||
(field) {
|
||||
// The default length of the fields is 3. The length of the fields
|
||||
// should not change after switching to other field type
|
||||
// assert(gridTest.fieldContexts.length == 3);
|
||||
assert(field.fieldType == FieldType.RichText);
|
||||
},
|
||||
);
|
||||
test('switch to text field', () async {
|
||||
final editorBloc = await makeEditorBloc(gridTest);
|
||||
|
||||
editorBloc.add(const FieldEditorEvent.switchToField(FieldType.RichText));
|
||||
await gridResponseFuture();
|
||||
|
||||
editorBloc.state.field.fold(
|
||||
() => throw Exception("The field should not be none"),
|
||||
(field) {
|
||||
// The default length of the fields is 3. The length of the fields
|
||||
// should not change after switching to other field type
|
||||
// assert(gridTest.fieldContexts.length == 3);
|
||||
assert(field.fieldType == FieldType.RichText);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
blocTest<FieldEditorBloc, FieldEditorState>(
|
||||
"delete field",
|
||||
build: () => editorBloc,
|
||||
act: (bloc) async {
|
||||
editorBloc.add(const FieldEditorEvent.deleteField());
|
||||
},
|
||||
wait: gridResponseDuration(),
|
||||
verify: (bloc) {
|
||||
// assert(gridTest.fieldContexts.length == 2);
|
||||
test('delete field', () async {
|
||||
final editorBloc = await makeEditorBloc(gridTest);
|
||||
editorBloc.add(const FieldEditorEvent.switchToField(FieldType.RichText));
|
||||
await gridResponseFuture();
|
||||
|
||||
editorBloc.state.field.fold(
|
||||
() => throw Exception("The field should not be none"),
|
||||
(field) {
|
||||
// The default length of the fields is 3. The length of the fields
|
||||
// should not change after switching to other field type
|
||||
// assert(gridTest.fieldContexts.length == 3);
|
||||
assert(field.fieldType == FieldType.RichText);
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Future<FieldEditorBloc> makeEditorBloc(AppFlowyGridTest gridTest) async {
|
||||
final context = await gridTest.createTestGrid();
|
||||
final fieldInfo = context.singleSelectFieldContext();
|
||||
final loader = FieldTypeOptionLoader(
|
||||
databaseId: context.gridView.id,
|
||||
field: fieldInfo.field,
|
||||
);
|
||||
|
||||
final editorBloc = FieldEditorBloc(
|
||||
databaseId: context.gridView.id,
|
||||
fieldName: fieldInfo.name,
|
||||
isGroupField: fieldInfo.isGroupField,
|
||||
loader: loader,
|
||||
)..add(const FieldEditorEvent.initial());
|
||||
|
||||
await gridResponseFuture();
|
||||
|
||||
return editorBloc;
|
||||
}
|
||||
|
@ -210,7 +210,7 @@ class AppFlowyGridCellTest {
|
||||
|
||||
Future<GridSelectOptionCellController> makeSelectOptionCellController(
|
||||
FieldType fieldType, int rowIndex) async {
|
||||
return context.makeSelectOptionCellController(fieldType, rowIndex);
|
||||
return await context.makeSelectOptionCellController(fieldType, rowIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ void main() {
|
||||
viewBloc.add(const ViewEvent.duplicate());
|
||||
await blocResponseFuture();
|
||||
|
||||
assert(appBloc.state.views.length == 2);
|
||||
expect(appBloc.state.views.length, 2);
|
||||
});
|
||||
|
||||
test('delete view test', () async {
|
||||
@ -59,7 +59,7 @@ void main() {
|
||||
DocumentPluginBuilder(),
|
||||
));
|
||||
await blocResponseFuture();
|
||||
assert(appBloc.state.views.length == 1);
|
||||
expect(appBloc.state.views.length, 1);
|
||||
|
||||
final viewBloc = ViewBloc(view: appBloc.state.views.first)
|
||||
..add(const ViewEvent.initial());
|
||||
|
@ -211,7 +211,7 @@ impl ViewDataProcessor for DocumentViewDataProcessor {
|
||||
}
|
||||
|
||||
fn data_types(&self) -> Vec<ViewDataFormatPB> {
|
||||
vec![ViewDataFormatPB::DeltaFormat, ViewDataFormatPB::TreeFormat]
|
||||
vec![ViewDataFormatPB::DeltaFormat, ViewDataFormatPB::NodeFormat]
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -297,7 +297,7 @@ impl UserStatusListener {
|
||||
async fn did_sign_up(&self, user_profile: &UserProfile) -> FlowyResult<()> {
|
||||
let view_data_type = match self.config.document.version {
|
||||
DocumentVersionPB::V0 => ViewDataFormatPB::DeltaFormat,
|
||||
DocumentVersionPB::V1 => ViewDataFormatPB::TreeFormat,
|
||||
DocumentVersionPB::V1 => ViewDataFormatPB::NodeFormat,
|
||||
};
|
||||
self.folder_manager
|
||||
.initialize_with_new_user(&user_profile.id, &user_profile.token, view_data_type)
|
||||
|
@ -5,6 +5,7 @@ use crate::services::field::*;
|
||||
use crate::services::filter::{FilterChangeset, FilterResult, FilterResultNotification, FilterType};
|
||||
use crate::services::row::DatabaseBlockRowRevision;
|
||||
use crate::services::view_editor::{GridViewChanged, GridViewChangedNotifier};
|
||||
use dashmap::DashMap;
|
||||
use flowy_error::FlowyResult;
|
||||
use flowy_task::{QualityOfService, Task, TaskContent, TaskDispatcher};
|
||||
use grid_model::{CellRevision, FieldId, FieldRevision, FilterRevision, RowRevision};
|
||||
@ -34,7 +35,7 @@ pub struct FilterController {
|
||||
view_id: String,
|
||||
handler_id: String,
|
||||
delegate: Box<dyn FilterDelegate>,
|
||||
result_by_row_id: HashMap<RowId, FilterResult>,
|
||||
result_by_row_id: DashMap<RowId, FilterResult>,
|
||||
cell_data_cache: AtomicCellDataCache,
|
||||
cell_filter_cache: AtomicCellFilterCache,
|
||||
task_scheduler: Arc<RwLock<TaskDispatcher>>,
|
||||
@ -54,11 +55,11 @@ impl FilterController {
|
||||
where
|
||||
T: FilterDelegate + 'static,
|
||||
{
|
||||
let mut this = Self {
|
||||
let this = Self {
|
||||
view_id: view_id.to_string(),
|
||||
handler_id: handler_id.to_string(),
|
||||
delegate: Box::new(delegate),
|
||||
result_by_row_id: HashMap::default(),
|
||||
result_by_row_id: DashMap::default(),
|
||||
cell_data_cache,
|
||||
cell_filter_cache: AnyTypeCache::<FilterType>::new(),
|
||||
task_scheduler,
|
||||
@ -83,7 +84,7 @@ impl FilterController {
|
||||
self.task_scheduler.write().await.add_task(task);
|
||||
}
|
||||
|
||||
pub async fn filter_row_revs(&mut self, row_revs: &mut Vec<Arc<RowRevision>>) {
|
||||
pub async fn filter_row_revs(&self, row_revs: &mut Vec<Arc<RowRevision>>) {
|
||||
if self.cell_filter_cache.read().is_empty() {
|
||||
return;
|
||||
}
|
||||
@ -91,7 +92,7 @@ impl FilterController {
|
||||
row_revs.iter().for_each(|row_rev| {
|
||||
let _ = filter_row(
|
||||
row_rev,
|
||||
&mut self.result_by_row_id,
|
||||
&self.result_by_row_id,
|
||||
&field_rev_by_field_id,
|
||||
&self.cell_data_cache,
|
||||
&self.cell_filter_cache,
|
||||
@ -116,7 +117,7 @@ impl FilterController {
|
||||
}
|
||||
|
||||
#[tracing::instrument(name = "process_filter_task", level = "trace", skip_all, fields(filter_result), err)]
|
||||
pub async fn process(&mut self, predicate: &str) -> FlowyResult<()> {
|
||||
pub async fn process(&self, predicate: &str) -> FlowyResult<()> {
|
||||
let event_type = FilterEvent::from_str(predicate).unwrap();
|
||||
match event_type {
|
||||
FilterEvent::FilterDidChanged => self.filter_all_rows().await?,
|
||||
@ -125,13 +126,13 @@ impl FilterController {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn filter_row(&mut self, row_id: String) -> FlowyResult<()> {
|
||||
async fn filter_row(&self, row_id: String) -> FlowyResult<()> {
|
||||
if let Some((_, row_rev)) = self.delegate.get_row_rev(&row_id).await {
|
||||
let field_rev_by_field_id = self.get_filter_revs_map().await;
|
||||
let mut notification = FilterResultNotification::new(self.view_id.clone(), row_rev.block_id.clone());
|
||||
if let Some((row_id, is_visible)) = filter_row(
|
||||
&row_rev,
|
||||
&mut self.result_by_row_id,
|
||||
&self.result_by_row_id,
|
||||
&field_rev_by_field_id,
|
||||
&self.cell_data_cache,
|
||||
&self.cell_filter_cache,
|
||||
@ -153,7 +154,7 @@ impl FilterController {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn filter_all_rows(&mut self) -> FlowyResult<()> {
|
||||
async fn filter_all_rows(&self) -> FlowyResult<()> {
|
||||
let field_rev_by_field_id = self.get_filter_revs_map().await;
|
||||
for block in self.delegate.get_blocks().await.into_iter() {
|
||||
// The row_ids contains the row that its visibility was changed.
|
||||
@ -163,7 +164,7 @@ impl FilterController {
|
||||
for (index, row_rev) in block.row_revs.iter().enumerate() {
|
||||
if let Some((row_id, is_visible)) = filter_row(
|
||||
row_rev,
|
||||
&mut self.result_by_row_id,
|
||||
&self.result_by_row_id,
|
||||
&field_rev_by_field_id,
|
||||
&self.cell_data_cache,
|
||||
&self.cell_filter_cache,
|
||||
@ -198,7 +199,7 @@ impl FilterController {
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "trace", skip(self))]
|
||||
pub async fn did_receive_changes(&mut self, changeset: FilterChangeset) -> Option<FilterChangesetNotificationPB> {
|
||||
pub async fn did_receive_changes(&self, changeset: FilterChangeset) -> Option<FilterChangesetNotificationPB> {
|
||||
let mut notification: Option<FilterChangesetNotificationPB> = None;
|
||||
if let Some(filter_type) = &changeset.insert_filter {
|
||||
if let Some(filter) = self.filter_from_filter_type(filter_type).await {
|
||||
@ -258,7 +259,7 @@ impl FilterController {
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "trace", skip_all)]
|
||||
async fn refresh_filters(&mut self, filter_revs: Vec<Arc<FilterRevision>>) {
|
||||
async fn refresh_filters(&self, filter_revs: Vec<Arc<FilterRevision>>) {
|
||||
for filter_rev in filter_revs {
|
||||
if let Some(field_rev) = self.delegate.get_field_rev(&filter_rev.field_id).await {
|
||||
let filter_type = FilterType::from(&field_rev);
|
||||
@ -309,13 +310,13 @@ impl FilterController {
|
||||
#[tracing::instrument(level = "trace", skip_all)]
|
||||
fn filter_row(
|
||||
row_rev: &Arc<RowRevision>,
|
||||
result_by_row_id: &mut HashMap<RowId, FilterResult>,
|
||||
result_by_row_id: &DashMap<RowId, FilterResult>,
|
||||
field_rev_by_field_id: &HashMap<FieldId, Arc<FieldRevision>>,
|
||||
cell_data_cache: &AtomicCellDataCache,
|
||||
cell_filter_cache: &AtomicCellFilterCache,
|
||||
) -> Option<(String, bool)> {
|
||||
// Create a filter result cache if it's not exist
|
||||
let filter_result = result_by_row_id
|
||||
let mut filter_result = result_by_row_id
|
||||
.entry(row_rev.id.clone())
|
||||
.or_insert_with(FilterResult::default);
|
||||
let old_is_visible = filter_result.is_visible();
|
||||
|
@ -3,15 +3,14 @@ use flowy_task::{TaskContent, TaskHandler};
|
||||
use lib_infra::future::BoxResultFuture;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
pub struct FilterTaskHandler {
|
||||
handler_id: String,
|
||||
filter_controller: Arc<RwLock<FilterController>>,
|
||||
filter_controller: Arc<FilterController>,
|
||||
}
|
||||
|
||||
impl FilterTaskHandler {
|
||||
pub fn new(handler_id: String, filter_controller: Arc<RwLock<FilterController>>) -> Self {
|
||||
pub fn new(handler_id: String, filter_controller: Arc<FilterController>) -> Self {
|
||||
Self {
|
||||
handler_id,
|
||||
filter_controller,
|
||||
@ -33,8 +32,6 @@ impl TaskHandler for FilterTaskHandler {
|
||||
Box::pin(async move {
|
||||
if let TaskContent::Text(predicate) = content {
|
||||
filter_controller
|
||||
.write()
|
||||
.await
|
||||
.process(&predicate)
|
||||
.await
|
||||
.map_err(anyhow::Error::from)?;
|
||||
|
@ -74,7 +74,7 @@ pub struct DatabaseViewRevisionEditor {
|
||||
rev_manager: Arc<RevisionManager<Arc<ConnectionPool>>>,
|
||||
delegate: Arc<dyn DatabaseViewEditorDelegate>,
|
||||
group_controller: Arc<RwLock<Box<dyn GroupController>>>,
|
||||
filter_controller: Arc<RwLock<FilterController>>,
|
||||
filter_controller: Arc<FilterController>,
|
||||
sort_controller: Arc<RwLock<SortController>>,
|
||||
pub notifier: GridViewChangedNotifier,
|
||||
}
|
||||
@ -156,7 +156,7 @@ impl DatabaseViewRevisionEditor {
|
||||
pub async fn close(&self) {
|
||||
self.rev_manager.generate_snapshot().await;
|
||||
self.rev_manager.close().await;
|
||||
self.filter_controller.read().await.close().await;
|
||||
self.filter_controller.close().await;
|
||||
self.sort_controller.read().await.close().await;
|
||||
}
|
||||
|
||||
@ -194,7 +194,7 @@ impl DatabaseViewRevisionEditor {
|
||||
}
|
||||
|
||||
pub async fn filter_rows(&self, _block_id: &str, rows: &mut Vec<Arc<RowRevision>>) {
|
||||
self.filter_controller.write().await.filter_row_revs(rows).await;
|
||||
self.filter_controller.filter_row_revs(rows).await;
|
||||
}
|
||||
|
||||
pub async fn duplicate_view_data(&self) -> FlowyResult<String> {
|
||||
@ -286,7 +286,7 @@ impl DatabaseViewRevisionEditor {
|
||||
let sort_controller = self.sort_controller.clone();
|
||||
let row_id = row_rev.id.clone();
|
||||
tokio::spawn(async move {
|
||||
filter_controller.read().await.did_receive_row_changed(&row_id).await;
|
||||
filter_controller.did_receive_row_changed(&row_id).await;
|
||||
sort_controller.read().await.did_receive_row_changed(&row_id).await;
|
||||
});
|
||||
}
|
||||
@ -514,7 +514,7 @@ impl DatabaseViewRevisionEditor {
|
||||
condition: params.condition,
|
||||
content: params.content,
|
||||
};
|
||||
let mut filter_controller = self.filter_controller.write().await;
|
||||
let filter_controller = self.filter_controller.clone();
|
||||
let changeset = if is_exist {
|
||||
let old_filter_type = self
|
||||
.delegate
|
||||
@ -555,8 +555,6 @@ impl DatabaseViewRevisionEditor {
|
||||
let filter_type = params.filter_type;
|
||||
let changeset = self
|
||||
.filter_controller
|
||||
.write()
|
||||
.await
|
||||
.did_receive_changes(FilterChangeset::from_delete(filter_type.clone()))
|
||||
.await;
|
||||
|
||||
@ -590,15 +588,14 @@ impl DatabaseViewRevisionEditor {
|
||||
.did_update_view_field_type_option(&field_rev)
|
||||
.await;
|
||||
|
||||
if let Some(changeset) = self
|
||||
.filter_controller
|
||||
.write()
|
||||
.await
|
||||
.did_receive_changes(filter_changeset)
|
||||
.await
|
||||
{
|
||||
self.notify_did_update_filter(changeset).await;
|
||||
}
|
||||
let filter_controller = self.filter_controller.clone();
|
||||
let _ = tokio::spawn(async move {
|
||||
if let Some(notification) = filter_controller.did_receive_changes(filter_changeset).await {
|
||||
send_notification(¬ification.view_id, DatabaseNotification::DidUpdateFilter)
|
||||
.payload(notification)
|
||||
.send();
|
||||
}
|
||||
});
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@ -830,7 +827,7 @@ async fn make_filter_controller(
|
||||
notifier: GridViewChangedNotifier,
|
||||
cell_data_cache: AtomicCellDataCache,
|
||||
pad: Arc<RwLock<GridViewRevisionPad>>,
|
||||
) -> Arc<RwLock<FilterController>> {
|
||||
) -> Arc<FilterController> {
|
||||
let field_revs = delegate.get_field_revs(None).await;
|
||||
let filter_revs = pad.read().await.get_all_filters(&field_revs);
|
||||
let task_scheduler = delegate.get_task_scheduler();
|
||||
@ -849,7 +846,7 @@ async fn make_filter_controller(
|
||||
notifier,
|
||||
)
|
||||
.await;
|
||||
let filter_controller = Arc::new(RwLock::new(filter_controller));
|
||||
let filter_controller = Arc::new(filter_controller);
|
||||
task_scheduler
|
||||
.write()
|
||||
.await
|
||||
@ -861,7 +858,7 @@ async fn make_sort_controller(
|
||||
view_id: &str,
|
||||
delegate: Arc<dyn DatabaseViewEditorDelegate>,
|
||||
notifier: GridViewChangedNotifier,
|
||||
filter_controller: Arc<RwLock<FilterController>>,
|
||||
filter_controller: Arc<FilterController>,
|
||||
pad: Arc<RwLock<GridViewRevisionPad>>,
|
||||
cell_data_cache: AtomicCellDataCache,
|
||||
) -> Arc<RwLock<SortController>> {
|
||||
|
@ -185,7 +185,7 @@ impl FilterDelegate for GridViewFilterDelegateImpl {
|
||||
pub(crate) struct GridViewSortDelegateImpl {
|
||||
pub(crate) editor_delegate: Arc<dyn DatabaseViewEditorDelegate>,
|
||||
pub(crate) view_revision_pad: Arc<RwLock<GridViewRevisionPad>>,
|
||||
pub(crate) filter_controller: Arc<RwLock<FilterController>>,
|
||||
pub(crate) filter_controller: Arc<FilterController>,
|
||||
}
|
||||
|
||||
impl SortDelegate for GridViewSortDelegateImpl {
|
||||
@ -209,7 +209,7 @@ impl SortDelegate for GridViewSortDelegateImpl {
|
||||
let editor_delegate = self.editor_delegate.clone();
|
||||
to_fut(async move {
|
||||
let mut row_revs = editor_delegate.get_row_revs(None).await;
|
||||
filter_controller.write().await.filter_row_revs(&mut row_revs).await;
|
||||
filter_controller.filter_row_revs(&mut row_revs).await;
|
||||
row_revs
|
||||
})
|
||||
}
|
||||
|
@ -2,11 +2,9 @@ pub mod app;
|
||||
mod parser;
|
||||
pub mod trash;
|
||||
pub mod view;
|
||||
mod view_info;
|
||||
pub mod workspace;
|
||||
|
||||
pub use app::*;
|
||||
pub use trash::*;
|
||||
pub use view::*;
|
||||
pub use view_info::*;
|
||||
pub use workspace::*;
|
||||
|
@ -50,9 +50,13 @@ impl std::convert::From<ViewRevision> for ViewPB {
|
||||
|
||||
#[derive(Eq, PartialEq, Hash, Debug, ProtoBuf_Enum, Clone)]
|
||||
pub enum ViewDataFormatPB {
|
||||
/// Indicate this view is using `Delta` for the persistence data format, it's deprecated.
|
||||
DeltaFormat = 0,
|
||||
/// Indicate this view is using `Database` for the persistence data format. It is used in AppFlowy database
|
||||
/// views including Grid,Board, and Calendar.
|
||||
DatabaseFormat = 1,
|
||||
TreeFormat = 2,
|
||||
/// Indicate this view is using `Node` for the persistence data format. It is used in AppFlowy document
|
||||
NodeFormat = 2,
|
||||
}
|
||||
|
||||
impl std::default::Default for ViewDataFormatPB {
|
||||
@ -66,7 +70,7 @@ impl std::convert::From<ViewDataFormatRevision> for ViewDataFormatPB {
|
||||
match rev {
|
||||
ViewDataFormatRevision::DeltaFormat => ViewDataFormatPB::DeltaFormat,
|
||||
ViewDataFormatRevision::DatabaseFormat => ViewDataFormatPB::DatabaseFormat,
|
||||
ViewDataFormatRevision::TreeFormat => ViewDataFormatPB::TreeFormat,
|
||||
ViewDataFormatRevision::NodeFormat => ViewDataFormatPB::NodeFormat,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -76,7 +80,7 @@ impl std::convert::From<ViewDataFormatPB> for ViewDataFormatRevision {
|
||||
match ty {
|
||||
ViewDataFormatPB::DeltaFormat => ViewDataFormatRevision::DeltaFormat,
|
||||
ViewDataFormatPB::DatabaseFormat => ViewDataFormatRevision::DatabaseFormat,
|
||||
ViewDataFormatPB::TreeFormat => ViewDataFormatRevision::TreeFormat,
|
||||
ViewDataFormatPB::NodeFormat => ViewDataFormatRevision::NodeFormat,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,26 +0,0 @@
|
||||
use crate::entities::{RepeatedViewPB, ViewDataFormatPB};
|
||||
use flowy_derive::ProtoBuf;
|
||||
|
||||
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
|
||||
pub struct ViewInfoPB {
|
||||
#[pb(index = 1)]
|
||||
pub id: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub belong_to_id: String,
|
||||
|
||||
#[pb(index = 3)]
|
||||
pub name: String,
|
||||
|
||||
#[pb(index = 4)]
|
||||
pub desc: String,
|
||||
|
||||
#[pb(index = 5)]
|
||||
pub data_type: ViewDataFormatPB,
|
||||
|
||||
#[pb(index = 6)]
|
||||
pub belongings: RepeatedViewPB,
|
||||
|
||||
#[pb(index = 7)]
|
||||
pub ext_data: String,
|
||||
}
|
@ -63,12 +63,11 @@ pub fn init(folder: Arc<FolderManager>) -> AFPlugin {
|
||||
.event(FolderEvent::CreateView, create_view_handler)
|
||||
.event(FolderEvent::ReadView, read_view_handler)
|
||||
.event(FolderEvent::UpdateView, update_view_handler)
|
||||
.event(FolderEvent::ReadViewInfo, read_view_info_handler)
|
||||
.event(FolderEvent::DeleteView, delete_view_handler)
|
||||
.event(FolderEvent::DuplicateView, duplicate_view_handler)
|
||||
.event(FolderEvent::SetLatestView, set_latest_view_handler)
|
||||
.event(FolderEvent::CloseView, close_view_handler)
|
||||
.event(FolderEvent::MoveFolderItem, move_item_handler);
|
||||
.event(FolderEvent::MoveItem, move_item_handler);
|
||||
|
||||
// Trash
|
||||
plugin = plugin
|
||||
@ -84,78 +83,99 @@ pub fn init(folder: Arc<FolderManager>) -> AFPlugin {
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)]
|
||||
#[event_err = "FlowyError"]
|
||||
pub enum FolderEvent {
|
||||
/// Create a new workspace
|
||||
#[event(input = "CreateWorkspacePayloadPB", output = "WorkspacePB")]
|
||||
CreateWorkspace = 0,
|
||||
|
||||
/// Read the current opening workspace
|
||||
#[event(output = "WorkspaceSettingPB")]
|
||||
ReadCurrentWorkspace = 1,
|
||||
|
||||
/// Open the workspace and mark it as the current workspace
|
||||
#[event(input = "WorkspaceIdPB", output = "RepeatedWorkspacePB")]
|
||||
ReadWorkspaces = 2,
|
||||
|
||||
/// Delete the workspace
|
||||
#[event(input = "WorkspaceIdPB")]
|
||||
DeleteWorkspace = 3,
|
||||
|
||||
/// Open the workspace and mark it as the current workspace
|
||||
#[event(input = "WorkspaceIdPB", output = "WorkspacePB")]
|
||||
OpenWorkspace = 4,
|
||||
|
||||
/// Return a list of apps that belong to this workspace
|
||||
#[event(input = "WorkspaceIdPB", output = "RepeatedAppPB")]
|
||||
ReadWorkspaceApps = 5,
|
||||
|
||||
/// Create a new app
|
||||
#[event(input = "CreateAppPayloadPB", output = "AppPB")]
|
||||
CreateApp = 101,
|
||||
|
||||
/// Delete the app
|
||||
#[event(input = "AppIdPB")]
|
||||
DeleteApp = 102,
|
||||
|
||||
/// Read the app
|
||||
#[event(input = "AppIdPB", output = "AppPB")]
|
||||
ReadApp = 103,
|
||||
|
||||
/// Update the app's properties including the name,description, etc.
|
||||
#[event(input = "UpdateAppPayloadPB")]
|
||||
UpdateApp = 104,
|
||||
|
||||
/// Create a new view in the corresponding app
|
||||
#[event(input = "CreateViewPayloadPB", output = "ViewPB")]
|
||||
CreateView = 201,
|
||||
|
||||
/// Return the view info
|
||||
#[event(input = "ViewIdPB", output = "ViewPB")]
|
||||
ReadView = 202,
|
||||
|
||||
/// Update the view's properties including the name,description, etc.
|
||||
#[event(input = "UpdateViewPayloadPB", output = "ViewPB")]
|
||||
UpdateView = 203,
|
||||
|
||||
/// Move the view to the trash folder
|
||||
#[event(input = "RepeatedViewIdPB")]
|
||||
DeleteView = 204,
|
||||
|
||||
/// Duplicate the view
|
||||
#[event(input = "ViewPB")]
|
||||
DuplicateView = 205,
|
||||
|
||||
/// Close and release the resources that are used by this view.
|
||||
/// It should get called when the 'View' page get destroy
|
||||
#[event(input = "ViewIdPB")]
|
||||
CloseView = 206,
|
||||
|
||||
#[event(input = "ViewIdPB", output = "ViewInfoPB")]
|
||||
ReadViewInfo = 207,
|
||||
|
||||
#[event()]
|
||||
CopyLink = 220,
|
||||
|
||||
/// Set the current visiting view
|
||||
#[event(input = "ViewIdPB")]
|
||||
SetLatestView = 221,
|
||||
|
||||
/// Move the view or app to another place
|
||||
#[event(input = "MoveFolderItemPayloadPB")]
|
||||
MoveFolderItem = 230,
|
||||
MoveItem = 230,
|
||||
|
||||
/// Read the trash that was deleted by the user
|
||||
#[event(output = "RepeatedTrashPB")]
|
||||
ReadTrash = 300,
|
||||
|
||||
/// Put back the trash to the origin folder
|
||||
#[event(input = "TrashIdPB")]
|
||||
PutbackTrash = 301,
|
||||
|
||||
/// Delete the trash from the disk
|
||||
#[event(input = "RepeatedTrashIdPB")]
|
||||
DeleteTrash = 302,
|
||||
|
||||
/// Put back all the trash to its original folder
|
||||
#[event()]
|
||||
RestoreAllTrash = 303,
|
||||
|
||||
/// Delete all the trash from the disk
|
||||
#[event()]
|
||||
DeleteAllTrash = 304,
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ impl ViewTable {
|
||||
let data_type = match view_rev.data_format {
|
||||
ViewDataFormatRevision::DeltaFormat => SqlViewDataFormat::Delta,
|
||||
ViewDataFormatRevision::DatabaseFormat => SqlViewDataFormat::Database,
|
||||
ViewDataFormatRevision::TreeFormat => SqlViewDataFormat::Tree,
|
||||
ViewDataFormatRevision::NodeFormat => SqlViewDataFormat::Tree,
|
||||
};
|
||||
|
||||
ViewTable {
|
||||
@ -113,7 +113,7 @@ impl std::convert::From<ViewTable> for ViewRevision {
|
||||
let data_type = match table.view_type {
|
||||
SqlViewDataFormat::Delta => ViewDataFormatRevision::DeltaFormat,
|
||||
SqlViewDataFormat::Database => ViewDataFormatRevision::DatabaseFormat,
|
||||
SqlViewDataFormat::Tree => ViewDataFormatRevision::TreeFormat,
|
||||
SqlViewDataFormat::Tree => ViewDataFormatRevision::NodeFormat,
|
||||
};
|
||||
|
||||
ViewRevision {
|
||||
|
@ -1,10 +1,10 @@
|
||||
pub use crate::entities::view::ViewDataFormatPB;
|
||||
use crate::entities::{AppPB, DeletedViewPB, ViewInfoPB, ViewLayoutTypePB};
|
||||
use crate::entities::{AppPB, DeletedViewPB, ViewLayoutTypePB};
|
||||
use crate::manager::{ViewDataProcessor, ViewDataProcessorMap};
|
||||
use crate::{
|
||||
entities::{
|
||||
trash::{RepeatedTrashIdPB, TrashType},
|
||||
view::{CreateViewParams, RepeatedViewPB, UpdateViewParams, ViewIdPB, ViewPB},
|
||||
view::{CreateViewParams, UpdateViewParams, ViewIdPB, ViewPB},
|
||||
},
|
||||
errors::{FlowyError, FlowyResult},
|
||||
event_map::{FolderCouldServiceV1, WorkspaceUser},
|
||||
@ -139,35 +139,6 @@ impl ViewController {
|
||||
Ok(view_rev)
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(self, view_id), fields(view_id = %view_id.value), err)]
|
||||
pub(crate) async fn read_view_pb(&self, view_id: ViewIdPB) -> Result<ViewInfoPB, FlowyError> {
|
||||
let view_info = self
|
||||
.persistence
|
||||
.begin_transaction(|transaction| {
|
||||
let view_rev = transaction.read_view(&view_id.value)?;
|
||||
|
||||
let items: Vec<ViewPB> = view_rev
|
||||
.belongings
|
||||
.into_iter()
|
||||
.map(|view_rev| view_rev.into())
|
||||
.collect();
|
||||
|
||||
let view_info = ViewInfoPB {
|
||||
id: view_rev.id,
|
||||
belong_to_id: view_rev.app_id,
|
||||
name: view_rev.name,
|
||||
desc: view_rev.desc,
|
||||
data_type: view_rev.data_format.into(),
|
||||
belongings: RepeatedViewPB { items },
|
||||
ext_data: view_rev.ext_data,
|
||||
};
|
||||
Ok(view_info)
|
||||
})
|
||||
.await?;
|
||||
|
||||
Ok(view_info)
|
||||
}
|
||||
|
||||
pub(crate) async fn read_local_views(&self, ids: Vec<String>) -> Result<Vec<ViewRevision>, FlowyError> {
|
||||
self.persistence
|
||||
.begin_transaction(|transaction| {
|
||||
|
@ -1,5 +1,4 @@
|
||||
use crate::entities::view::{MoveFolderItemParams, MoveFolderItemPayloadPB, MoveFolderItemType};
|
||||
use crate::entities::ViewInfoPB;
|
||||
use crate::manager::FolderManager;
|
||||
use crate::services::{notify_workspace_setting_did_change, AppController};
|
||||
use crate::{
|
||||
@ -35,15 +34,6 @@ pub(crate) async fn read_view_handler(
|
||||
data_result(view_rev.into())
|
||||
}
|
||||
|
||||
pub(crate) async fn read_view_info_handler(
|
||||
data: AFPluginData<ViewIdPB>,
|
||||
controller: AFPluginState<Arc<ViewController>>,
|
||||
) -> DataResult<ViewInfoPB, FlowyError> {
|
||||
let view_id: ViewIdPB = data.into_inner();
|
||||
let view_info = controller.read_view_pb(view_id.clone()).await?;
|
||||
data_result(view_info)
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(data, controller), err)]
|
||||
pub(crate) async fn update_view_handler(
|
||||
data: AFPluginData<UpdateViewPayloadPB>,
|
||||
|
@ -182,7 +182,7 @@ impl FolderTest {
|
||||
FolderScript::CreateView { name, desc, data_type } => {
|
||||
let layout = match data_type {
|
||||
ViewDataFormatPB::DeltaFormat => ViewLayoutTypePB::Document,
|
||||
ViewDataFormatPB::TreeFormat => ViewLayoutTypePB::Document,
|
||||
ViewDataFormatPB::NodeFormat => ViewLayoutTypePB::Document,
|
||||
ViewDataFormatPB::DatabaseFormat => ViewLayoutTypePB::Grid,
|
||||
};
|
||||
let view = create_view(sdk, &self.app.id, &name, &desc, data_type, layout).await;
|
||||
|
@ -58,7 +58,7 @@ impl ViewTest {
|
||||
pub async fn new_document_view(sdk: &FlowySDKTest) -> Self {
|
||||
let view_data_format = match sdk.document_version() {
|
||||
DocumentVersionPB::V0 => ViewDataFormatPB::DeltaFormat,
|
||||
DocumentVersionPB::V1 => ViewDataFormatPB::TreeFormat,
|
||||
DocumentVersionPB::V1 => ViewDataFormatPB::NodeFormat,
|
||||
};
|
||||
Self::new(sdk, view_data_format, ViewLayoutTypePB::Document, vec![]).await
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ impl std::convert::From<ViewRevision> for TrashRevision {
|
||||
pub enum ViewDataFormatRevision {
|
||||
DeltaFormat = 0,
|
||||
DatabaseFormat = 1,
|
||||
TreeFormat = 2,
|
||||
NodeFormat = 2,
|
||||
}
|
||||
|
||||
impl std::default::Default for ViewDataFormatRevision {
|
||||
|
Loading…
Reference in New Issue
Block a user