Skip to content

Commit

Permalink
feat(front): implement export data configuration options;
Browse files Browse the repository at this point in the history
  • Loading branch information
TheBestTvarynka committed Dec 13, 2024
1 parent 33c99cb commit 9178e08
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 13 deletions.
1 change: 1 addition & 0 deletions dataans/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ web-sys = { version = "0.3", features = [
"FileList",
"HtmlInputElement",
"HtmlElement",
"HtmlSelectElement",
] }
futures = { version = "0.3", features = ["std", "alloc"] }

Expand Down
78 changes: 78 additions & 0 deletions dataans/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down
51 changes: 38 additions & 13 deletions dataans/src/spaces/app_info/app_info_window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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! {
Expand Down Expand Up @@ -200,7 +204,28 @@ pub fn AppInfoWindow(#[prop(into)] close: Callback<(), ()>) -> impl IntoView {
}
}}
<div class="horizontal">
<span>"One file"</span>
<select
on:change=move |ev: leptos::ev::Event| {
let select: HtmlSelectElement = ev.target().unwrap().unchecked_into();
set_export_option.set(NotesExportOption::from_str(&select.value()));
}
prop:value=move || export_option.get().to_string()
>
{NotesExportOption::variants().into_iter().map(|export_option| view! {
<option value=export_option.to_string()>{export_option.pretty()}</option>
}).collect_view()}
</select>
<select
on:change=move |ev: leptos::ev::Event| {
let select: HtmlSelectElement = ev.target().unwrap().unchecked_into();
set_export_format.set(ExportFormat::from_str(&select.value()));
}
prop:value=move || export_format.get().to_string()
>
{ExportFormat::variants().into_iter().map(|export_format| view! {
<option value=export_format.to_string()>{export_format.pretty()}</option>
}).collect_view()}
</select>
<button class="button_ok" on:click=export_data>"Export"</button>
<Suspense
fallback=move || view! { <span>"Exporting...."</span> }
Expand Down

0 comments on commit 9178e08

Please sign in to comment.