Browse Source

feat: save csv data to local file (#2681)

Nathan.fooo 1 year ago
parent
commit
82dcd4b99e

+ 14 - 0
frontend/appflowy_flutter/lib/workspace/application/settings/share/export_service.dart

@@ -0,0 +1,14 @@
+import 'package:appflowy_backend/dispatch/dispatch.dart';
+import 'package:appflowy_backend/protobuf/flowy-database2/database_entities.pb.dart';
+import 'package:appflowy_backend/protobuf/flowy-database2/share_entities.pb.dart';
+import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
+import 'package:dartz/dartz.dart';
+
+class BackendExportService {
+  static Future<Either<DatabaseExportDataPB, FlowyError>> exportDatabaseAsCSV(
+    String viewId,
+  ) async {
+    final payload = DatabaseViewIdPB.create()..value = viewId;
+    return DatabaseEventExportCSV(payload).send();
+  }
+}

+ 8 - 2
frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_file_exporter_widget.dart

@@ -6,6 +6,7 @@ import 'package:appflowy/plugins/document/application/prelude.dart';
 import 'package:appflowy/startup/startup.dart';
 import 'package:appflowy/util/file_picker/file_picker_service.dart';
 import 'package:appflowy/workspace/application/settings/settings_file_exporter_cubit.dart';
+import 'package:appflowy/workspace/application/settings/share/export_service.dart';
 import 'package:appflowy_backend/log.dart';
 import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
 import 'package:dartz/dartz.dart' as dartz;
@@ -243,8 +244,13 @@ class _AppFlowyFileExporter {
           fileExtension = 'afdocument';
           break;
         default:
-          // TODO(nathan): export the new databse data to json
-          content = null;
+          final result =
+              await BackendExportService.exportDatabaseAsCSV(view.id);
+          result.fold(
+            (l) => content = l.data,
+            (r) => Log.error(r),
+          );
+          fileExtension = 'csv';
           break;
       }
       if (content != null) {

+ 1 - 0
frontend/appflowy_tauri/src-tauri/Cargo.lock

@@ -1911,6 +1911,7 @@ dependencies = [
  "flowy-derive",
  "flowy-error",
  "flowy-notification",
+ "indexmap",
  "lib-dispatch",
  "nanoid",
  "parking_lot 0.12.1",

+ 2 - 0
frontend/rust-lib/flowy-database2/src/entities/mod.rs

@@ -12,6 +12,7 @@ mod view_entities;
 
 #[macro_use]
 mod macros;
+mod share_entities;
 mod type_option_entities;
 
 pub use calendar_entities::*;
@@ -22,6 +23,7 @@ pub use filter_entities::*;
 pub use group_entities::*;
 pub use row_entities::*;
 pub use setting_entities::*;
+pub use share_entities::*;
 pub use sort_entities::*;
 pub use type_option_entities::*;
 pub use view_entities::*;

+ 21 - 0
frontend/rust-lib/flowy-database2/src/entities/share_entities.rs

@@ -0,0 +1,21 @@
+use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
+
+#[derive(Debug, ProtoBuf_Enum, Clone)]
+pub enum DatabaseExportDataType {
+  CSV = 0,
+}
+
+impl Default for DatabaseExportDataType {
+  fn default() -> Self {
+    DatabaseExportDataType::CSV
+  }
+}
+
+#[derive(Debug, ProtoBuf, Default, Clone)]
+pub struct DatabaseExportDataPB {
+  #[pb(index = 1)]
+  pub export_type: DatabaseExportDataType,
+
+  #[pb(index = 2)]
+  pub data: String,
+}

+ 15 - 0
frontend/rust-lib/flowy-database2/src/event_handler.rs

@@ -16,6 +16,7 @@ use crate::services::field::{
   type_option_data_from_pb_or_default, DateCellChangeset, SelectOptionCellChangeset,
 };
 use crate::services::group::{GroupChangeset, GroupSettingChangeset};
+use crate::services::share::csv::CSVFormat;
 
 #[tracing::instrument(level = "trace", skip_all, err)]
 pub(crate) async fn get_database_data_handler(
@@ -727,3 +728,17 @@ pub(crate) async fn create_database_view(
   // let data: CreateDatabaseViewParams = data.into_inner().try_into()?;
   Ok(())
 }
+
+#[tracing::instrument(level = "debug", skip_all, err)]
+pub(crate) async fn export_csv_handler(
+  data: AFPluginData<DatabaseViewIdPB>,
+  manager: AFPluginState<Arc<DatabaseManager2>>,
+) -> DataResult<DatabaseExportDataPB, FlowyError> {
+  let view_id = data.into_inner().value;
+  let database = manager.get_database_with_view_id(&view_id).await?;
+  let data = database.export_csv(CSVFormat::Original).await?;
+  data_result_ok(DatabaseExportDataPB {
+    export_type: DatabaseExportDataType::CSV,
+    data,
+  })
+}

+ 4 - 0
frontend/rust-lib/flowy-database2/src/event_map.rs

@@ -67,6 +67,7 @@ pub fn init(database_manager: Arc<DatabaseManager2>) -> AFPlugin {
         .event(DatabaseEvent::SetLayoutSetting, set_layout_setting_handler)
         .event(DatabaseEvent::GetLayoutSetting, get_layout_setting_handler)
         .event(DatabaseEvent::CreateDatabaseView, create_database_view)
+        .event(DatabaseEvent::ExportCSV, export_csv_handler)
 }
 
 /// [DatabaseEvent] defines events that are used to interact with the Grid. You could check [this](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/architecture/backend/protobuf)
@@ -286,4 +287,7 @@ pub enum DatabaseEvent {
 
   #[event(input = "CreateDatabaseViewPayloadPB")]
   CreateDatabaseView = 130,
+
+  #[event(input = "DatabaseViewIdPB", output = "DatabaseExportDataPB")]
+  ExportCSV = 141,
 }