From 9178e0874ec3694eee8f5efcf82d6eda2ed3bc13 Mon Sep 17 00:00:00 2001 From: Pavlo Myroniuk Date: Fri, 13 Dec 2024 22:52:55 +0200 Subject: [PATCH] feat(front): implement export data configuration options; --- dataans/Cargo.toml | 1 + dataans/common/src/lib.rs | 78 +++++++++++++++++++ .../src/spaces/app_info/app_info_window.rs | 51 ++++++++---- 3 files changed, 117 insertions(+), 13 deletions(-) diff --git a/dataans/Cargo.toml b/dataans/Cargo.toml index 35c4e61..f94762a 100644 --- a/dataans/Cargo.toml +++ b/dataans/Cargo.toml @@ -41,6 +41,7 @@ web-sys = { version = "0.3", features = [ "FileList", "HtmlInputElement", "HtmlElement", + "HtmlSelectElement", ] } futures = { version = "0.3", features = ["std", "alloc"] } diff --git a/dataans/common/src/lib.rs b/dataans/common/src/lib.rs index 8b69782..042e575 100644 --- a/dataans/common/src/lib.rs +++ b/dataans/common/src/lib.rs @@ -7,6 +7,7 @@ pub mod note; pub mod space; use std::collections::HashMap; +use std::fmt; use std::path::PathBuf; use serde::{Deserialize, Serialize}; @@ -195,6 +196,48 @@ pub enum NotesExportOption { FilePerNote, } +impl NotesExportOption { + /// Returns a slice that contains all [NotesExportOption] variants. + pub fn variants() -> &'static [NotesExportOption] { + &[ + NotesExportOption::OneFile, + NotesExportOption::FilePerSpace, + NotesExportOption::FilePerNote, + ] + } + + /// Returns pretty name of [NotesExportOption]. + pub fn pretty(&self) -> &str { + match self { + NotesExportOption::OneFile => "One file", + NotesExportOption::FilePerSpace => "File per space", + NotesExportOption::FilePerNote => "File per note", + } + } + + /// Creates [NotesExportOption] from the `str`. + /// + /// Panic: on invalid value. + pub fn from_str(value: &str) -> Self { + match value { + "OneFile" => NotesExportOption::OneFile, + "FilePerSpace" => NotesExportOption::FilePerSpace, + "FilePerNote" => NotesExportOption::FilePerNote, + _ => panic!("Invalid NotesExportOption value: {}", value), + } + } +} + +impl fmt::Display for NotesExportOption { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + match self { + NotesExportOption::OneFile => f.write_str("OneFile"), + NotesExportOption::FilePerSpace => f.write_str("FilePerSpace"), + NotesExportOption::FilePerNote => f.write_str("FilePerNote"), + } + } +} + /// Format for the data exporting. #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] pub enum ExportFormat { @@ -204,6 +247,41 @@ pub enum ExportFormat { Json, } +impl ExportFormat { + /// Returns a slice that contains all [ExportFormat] variants. + pub fn variants() -> &'static [ExportFormat] { + &[ExportFormat::Md, ExportFormat::Json] + } + + /// Returns pretty name of [ExportFormat]. + pub fn pretty(&self) -> &str { + match self { + ExportFormat::Md => "Markdown", + ExportFormat::Json => "Json", + } + } + + /// Creates [ExportFormat] from the `str`. + /// + /// Panic: on invalid value. + pub fn from_str(value: &str) -> Self { + match value { + "Md" => ExportFormat::Md, + "Json" => ExportFormat::Json, + _ => panic!("Invalid ExportFormat value: {}", value), + } + } +} + +impl fmt::Display for ExportFormat { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + match self { + ExportFormat::Md => f.write_str("Md"), + ExportFormat::Json => f.write_str("Json"), + } + } +} + /// Configuration for app data export. #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] pub struct DataExportConfig { diff --git a/dataans/src/spaces/app_info/app_info_window.rs b/dataans/src/spaces/app_info/app_info_window.rs index 8e4370c..ce14059 100644 --- a/dataans/src/spaces/app_info/app_info_window.rs +++ b/dataans/src/spaces/app_info/app_info_window.rs @@ -3,6 +3,8 @@ use std::path::PathBuf; use common::{App, Appearance, Config, DataExportConfig, ExportFormat, KeyBindings, NotesExportOption}; use leptos::*; use leptos_hotkeys::use_hotkeys; +use wasm_bindgen::JsCast; +use web_sys::HtmlSelectElement; use crate::backend::export::export_data; use crate::backend::file::open; @@ -34,24 +36,26 @@ pub fn AppInfoWindow(#[prop(into)] close: Callback<(), ()>) -> impl IntoView { }) }; - let (export_option, set_export_option) = create_signal(None); + let (export_config, set_export_config) = create_signal(None); + let (export_option, set_export_option) = create_signal(NotesExportOption::OneFile); + let (export_format, set_export_format) = create_signal(ExportFormat::Md); + let export_result = create_resource( - move || export_option.get(), - move |export_option| async move { - if let Some(export_option) = export_option { - Some( - export_data(DataExportConfig { - notes_export_option: export_option, - format: ExportFormat::Md, - }) - .await, - ) + move || export_config.get(), + move |export_config| async move { + if let Some(export_config) = export_config { + Some(export_data(export_config).await) } else { None } }, ); - let export_data = move |_| set_export_option.set(Some(NotesExportOption::OneFile)); + let export_data = move |_| { + set_export_config.set(Some(DataExportConfig { + notes_export_option: export_option.get(), + format: export_format.get(), + })); + }; let open_exported_data_dir = move |path: PathBuf| spawn_local(async move { open(&path).await }); view! { @@ -200,7 +204,28 @@ pub fn AppInfoWindow(#[prop(into)] close: Callback<(), ()>) -> impl IntoView { } }}
- "One file" + + "Exporting...." }