Skip to content

Commit bb4f295

Browse files
feat(WIP): edit projects from app
not working completly constraint error???
1 parent fbf1da9 commit bb4f295

10 files changed

Lines changed: 201 additions & 37 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

episko_gui_backend/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ tauri-build = { version = "2.0.1", features = [] }
1717

1818
[dependencies]
1919
tauri = { version = "2", features = [] }
20+
chrono = { workspace = true, features = ["serde"] }
2021
tauri-plugin-shell = "2"
2122
serde_json = "1"
2223
serde = { version = "1", features = ["derive"] }

episko_gui_backend/src/commands.rs

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,25 @@
1-
use std::path::Path;
1+
use std::{ops::Deref, path::Path};
22
use tokio::sync::Mutex;
33
use uuid::Uuid;
44

55
use episko_lib::{
6+
ApplyIf,
67
files::File,
7-
metadata::{metadata_handler::MetadataHandler, Metadata},
8+
metadata::{Metadata, MetadataBuilder, metadata_handler::MetadataHandler},
89
};
910

10-
use crate::AppState;
11+
use crate::{AppState, MetadataDco, MetadataDto};
1112

1213
#[tauri::command]
13-
pub async fn get_all(state: tauri::State<'_, Mutex<AppState>>) -> Result<Vec<Metadata>, String> {
14+
pub async fn get_all(state: tauri::State<'_, Mutex<AppState>>) -> Result<Vec<MetadataDto>, String> {
1415
let state = state.lock().await;
1516

1617
let projects = Metadata::all_from_db(&state.db)
1718
.await
18-
.map_err(|err| err.to_string())?;
19+
.map_err(|err| err.to_string())?
20+
.into_iter()
21+
.map(Into::into)
22+
.collect();
1923

2024
Ok(projects)
2125
}
@@ -24,12 +28,52 @@ pub async fn get_all(state: tauri::State<'_, Mutex<AppState>>) -> Result<Vec<Met
2428
pub async fn get_with_id(
2529
id: Uuid,
2630
state: tauri::State<'_, Mutex<AppState>>,
27-
) -> Result<Metadata, String> {
31+
) -> Result<MetadataDto, String> {
2832
let state = state.lock().await;
2933

3034
Metadata::from_db(&state.db, id)
3135
.await
3236
.map_err(|err| err.to_string())
37+
.map(Into::into)
38+
}
39+
40+
#[tauri::command]
41+
pub async fn update_metadata(
42+
id: Uuid,
43+
updated: MetadataDco,
44+
state: tauri::State<'_, Mutex<AppState>>,
45+
) -> Result<MetadataDto, String> {
46+
let state = state.lock().await;
47+
48+
let metadata = Metadata::from_db(&state.db, id)
49+
.await
50+
.map_err(|err| err.to_string())?;
51+
52+
let metadata = metadata
53+
.update()
54+
.directory_path(&updated.directory)
55+
.title(&updated.title)
56+
.categories(updated.categories)
57+
.languages(updated.languages)
58+
.build_systems(updated.build_systems)
59+
.apply_if(updated.preffered_ide, MetadataBuilder::preffered_ide)
60+
.apply_if(updated.description.as_deref(), MetadataBuilder::description)
61+
.apply_if(
62+
updated.repository_url.as_deref(),
63+
MetadataBuilder::repository_url,
64+
)
65+
.build()
66+
.map_err(|err| err.to_string())?;
67+
68+
metadata
69+
.write_to_db(&state.db)
70+
.await
71+
.map_err(|err| err.to_string())?;
72+
metadata
73+
.write_file(&metadata.directory)
74+
.map_err(|err| err.to_string())?;
75+
76+
Ok(metadata.into())
3377
}
3478

3579
#[tauri::command]

episko_gui_backend/src/lib.rs

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
#![deny(clippy::pedantic)]
22
#![allow(clippy::used_underscore_binding)]
3+
use chrono::{DateTime, Utc};
34
use episko_lib::{
45
config::ConfigHandler,
56
database::DatabaseHandler,
67
files::File as _,
7-
metadata::{metadata_handler::MetadataHandler, Metadata},
8+
metadata::{BuildSystem, Category, Ide, Language, Metadata, metadata_handler::MetadataHandler},
89
};
10+
use serde::{Deserialize, Serialize, de::DeserializeOwned};
911
use tauri::Manager;
1012

1113
mod commands;
12-
use commands::{get_all, get_with_id, load_from_directory, load_from_file};
14+
use commands::{get_all, get_with_id, load_from_directory, load_from_file, update_metadata};
15+
use std::path::PathBuf;
1316
use tokio::sync::Mutex;
17+
use uuid::Uuid;
1418

1519
struct AppState {
1620
pub db: DatabaseHandler,
@@ -22,6 +26,59 @@ impl AppState {
2226
}
2327
}
2428

29+
/// Dto data transfer object
30+
#[derive(Serialize, Deserialize, Debug)]
31+
struct MetadataDto {
32+
id: Uuid,
33+
directory: PathBuf,
34+
title: String,
35+
description: Option<String>,
36+
categories: Vec<Category>,
37+
languages: Vec<Language>,
38+
build_systems: Vec<BuildSystem>,
39+
preffered_ide: Option<Ide>,
40+
repository_url: Option<String>,
41+
created: DateTime<Utc>,
42+
updated: DateTime<Utc>,
43+
}
44+
45+
/// Dco data creation object
46+
#[derive(Serialize, Deserialize, Debug)]
47+
struct MetadataDco {
48+
directory: PathBuf,
49+
title: String,
50+
description: Option<String>,
51+
categories: Vec<Category>,
52+
languages: Vec<Language>,
53+
build_systems: Vec<BuildSystem>,
54+
preffered_ide: Option<Ide>,
55+
repository_url: Option<String>,
56+
}
57+
58+
impl MetadataDco {
59+
fn create() -> Result<Metadata, String> {
60+
todo!()
61+
}
62+
}
63+
64+
impl From<Metadata> for MetadataDto {
65+
fn from(metadata: Metadata) -> MetadataDto {
66+
MetadataDto {
67+
id: metadata.id,
68+
directory: metadata.directory,
69+
title: metadata.title,
70+
description: metadata.description,
71+
categories: metadata.categories,
72+
languages: metadata.languages,
73+
build_systems: metadata.build_systems,
74+
preffered_ide: metadata.preffered_ide,
75+
repository_url: metadata.repository_url,
76+
created: metadata.created,
77+
updated: metadata.updated,
78+
}
79+
}
80+
}
81+
2582
/// !TODO!
2683
///
2784
/// # Errors
@@ -61,6 +118,7 @@ pub async fn run() -> Result<(), Box<dyn std::error::Error>> {
61118
.invoke_handler(tauri::generate_handler![
62119
get_all,
63120
get_with_id,
121+
update_metadata,
64122
load_from_file,
65123
load_from_directory,
66124
])

episko_lib/src/metadata.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -80,21 +80,21 @@ pub type Result<T> = std::result::Result<T, Error>;
8080
/// Metadata structure containing information about a project.
8181
#[derive(Debug, Serialize, Deserialize)]
8282
pub struct Metadata {
83-
pub(crate) id: Uuid,
83+
pub id: Uuid,
8484
#[serde(skip)]
85-
pub(crate) directory: PathBuf,
86-
pub(crate) title: String,
87-
pub(crate) description: Option<String>,
85+
pub directory: PathBuf,
86+
pub title: String,
87+
pub description: Option<String>,
8888
#[serde(rename = "category")]
89-
pub(crate) categories: Vec<Category>,
89+
pub categories: Vec<Category>,
9090
#[serde(rename = "language")]
91-
pub(crate) languages: Vec<Language>,
91+
pub languages: Vec<Language>,
9292
#[serde(rename = "build_system")]
93-
pub(crate) build_systems: Vec<BuildSystem>,
94-
pub(crate) preffered_ide: Option<Ide>,
95-
pub(crate) repository_url: Option<String>,
96-
pub(crate) created: DateTime<Utc>,
97-
pub(crate) updated: DateTime<Utc>,
93+
pub build_systems: Vec<BuildSystem>,
94+
pub preffered_ide: Option<Ide>,
95+
pub repository_url: Option<String>,
96+
pub created: DateTime<Utc>,
97+
pub updated: DateTime<Utc>,
9898
}
9999

100100
impl Metadata {
@@ -189,7 +189,7 @@ mod tests {
189189
fn test_metadata_checksum_is_consistent() {
190190
let metadata = get_simple_metadata();
191191
let checksum1 = metadata.get_hash().unwrap();
192-
for i in 0..100 {
192+
for _ in 0..100 {
193193
let checksum2 = metadata.get_hash().unwrap();
194194
assert_eq!(checksum1, checksum2)
195195
}

flake.nix

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
{
1818
devShells.default = pkgs.mkShell {
1919
packages = with pkgs; [
20-
rustfmt
2120
bacon
2221
];
2322
nativeBuildInputs = with pkgs; [
@@ -29,7 +28,6 @@
2928
cargo-tauri
3029
cargo-update
3130
cargo-watch
32-
rustc
3331
gobject-introspection
3432
gtk3
3533
gtk4

src/lib/commands.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { invoke } from '@tauri-apps/api/core';
2-
import type { Metadata, Uuid } from './types';
3-
import { parseMetadata, parseMetadataArray } from './schemas/metadata';
2+
import type { FormMetadata, Metadata, Uuid } from './types';
3+
import { parseMetadata, parseMetadataArray, parseMetadataDco } from './schemas/metadata';
44

55
export default {
66
async get_all(): Promise<Metadata[]> {
@@ -11,6 +11,10 @@ export default {
1111
return invoke('get_with_id', { id: id }).then((data) => parseMetadata(data));
1212
},
1313

14+
async update_metadata(id: Uuid, updated: FormMetadata): Promise<Metadata> {
15+
return invoke('update_metadata', { id: id, updated: parseMetadataDco(updated) }).then((data) => parseMetadata(data));
16+
},
17+
1418
async load_from_file(path: string): Promise<Uuid> {
1519
return invoke('load_from_file', { path: path });
1620
},

src/lib/components/project/form.svelte

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@
33
import FormLanguages from './form-languages.svelte';
44
import { Input } from '$lib/components/ui/input';
55
import type { FormMetadata, Metadata } from '$lib/types';
6-
import { type SuperValidated, superForm } from 'sveltekit-superforms';
6+
import { type SuperValidated, setError, setMessage, superForm } from 'sveltekit-superforms';
77
import { zodClient } from 'sveltekit-superforms/adapters';
88
import { MetadataFormSchema } from '$lib/schemas/metadata';
99
import Badge from '../ui/badge/badge.svelte';
1010
import { Button } from '../ui/button';
11+
import { goto } from '$app/navigation';
12+
import Commands from '$lib/commands';
13+
import { upsertMetadata } from '../../../routes/metadata-state.svelte';
1114
1215
interface Props {
1316
metadata?: Metadata;
@@ -20,7 +23,29 @@
2023
const form = superForm(formProp, {
2124
SPA: true,
2225
validators: zodClient(MetadataFormSchema),
23-
dataType: 'json'
26+
dataType: 'json',
27+
onUpdate: async ({ form }) => {
28+
console.log('FormValid:', form.valid);
29+
if (form.valid) {
30+
if (metadata) {
31+
console.log('Metadata found');
32+
await Commands.update_metadata(metadata.id, form.data)
33+
.then((metadata) => {
34+
console.log('Promise resolved');
35+
upsertMetadata(metadata);
36+
history.back();
37+
})
38+
.catch((err) => {
39+
console.error('Promise failed:', err);
40+
setError(form, err);
41+
});
42+
} else {
43+
setMessage(form, 'TODO: Create');
44+
}
45+
} else {
46+
console.log('Helloo I am under the water');
47+
}
48+
}
2449
});
2550
2651
const { form: formData, enhance } = form;
@@ -39,21 +64,33 @@
3964
</script>
4065

4166
<h1>{formTitle}</h1>
42-
<form use:enhance>
67+
<form method="POST" use:enhance>
68+
<Form.Field {form} name="directory">
69+
<Form.Control>
70+
{#snippet children({ props })}
71+
<Form.Label>Directory</Form.Label>
72+
<Input {...props} bind:value={$formData.directory} />
73+
{/snippet}
74+
</Form.Control>
75+
<Form.FieldErrors />
76+
<Form.Description>Todo: Use tauri file chooser</Form.Description>
77+
</Form.Field>
78+
4379
<Form.Field {form} name="title">
4480
<Form.Control>
4581
{#snippet children({ props })}
4682
<Form.Label>Title</Form.Label>
4783
<Input {...props} bind:value={$formData.title} />
4884
{/snippet}
4985
</Form.Control>
50-
<Form.Description>TBC: Title of the Project</Form.Description>
5186
<Form.FieldErrors />
87+
<Form.Description>TBC: Title of the Project</Form.Description>
5288
</Form.Field>
5389

5490
<FormLanguages {form} />
5591

5692
<!-- similiar like languages probably also seperate component-->
93+
Categories
5794
{#each $formData.categories as _, i}
5895
<Badge
5996
>{$formData.categories[i].name}

0 commit comments

Comments
 (0)