From f8234c0488cc57d450196de3a615145bff6ae19a Mon Sep 17 00:00:00 2001 From: mina Date: Wed, 25 Jun 2025 18:10:31 +0200 Subject: [PATCH 01/10] Frontend passt wieder --- src/lib/components/ListItem.svelte | 85 +++++++++++++++++++ src/lib/icons/Cube.svelte | 7 +- .../(token-based)/list/[vorgang]/+page.svelte | 43 ++++------ 3 files changed, 109 insertions(+), 26 deletions(-) create mode 100644 src/lib/components/ListItem.svelte diff --git a/src/lib/components/ListItem.svelte b/src/lib/components/ListItem.svelte new file mode 100644 index 0000000..0b5f0e8 --- /dev/null +++ b/src/lib/components/ListItem.svelte @@ -0,0 +1,85 @@ + + + +
+ +
+ {#if admin} + { + editName(); + }} + /> + + + + + {:else} + + {item.name} + + {/if} + +

{shortenFileSize(item.size)}

+
+
+ +
diff --git a/src/lib/icons/Cube.svelte b/src/lib/icons/Cube.svelte index 4992960..ff56e24 100644 --- a/src/lib/icons/Cube.svelte +++ b/src/lib/icons/Cube.svelte @@ -1,10 +1,15 @@ + + - import shortenFileSize from '$lib/helper/shortenFileSize'; import { page } from '$app/stores'; - - import timeElapsed from '$lib/helper/timeElapsed'; - import Alert from '$lib/components/Alert.svelte'; import Button from '$lib/components/Button.svelte'; import Modal from '$lib/components/Modal/Modal.svelte'; import ModalTitle from '$lib/components/Modal/ModalTitle.svelte'; import ModalContent from '$lib/components/Modal/ModalContent.svelte'; import ModalFooter from '$lib/components/Modal/ModalFooter.svelte'; - import Cube from '$lib/icons/Cube.svelte'; - import Edit from '$lib/icons/Edit.svelte'; - import Trash from '$lib/icons/Trash.svelte'; + import ListItem from '$lib/components/ListItem.svelte'; - /** export let data; */ - /** @type {import('./$types').PageData} */ export let data; interface ListItem { @@ -28,6 +20,7 @@ const crimesList: ListItem[] = data.crimesList; const token: string = data.caseToken; + export let vorgang = $page.params.vorgang; let open = false; $: open; @@ -43,20 +36,20 @@ open = false; } - function defocus_element(i: number) { - let item = crimesList[i]; - let text_field_id = `label__${item.name}`; + // function defocus_element(i: number) { + // let item = crimesList[i]; + // let text_field_id = `label__${item.name}`; - let text_field = document.getElementById(text_field_id); - if (text_field) { - text_field.setAttribute('contenteditable', 'false'); - text_field.textContent = item.name; - } + // let text_field = document.getElementById(text_field_id); + // if (text_field) { + // text_field.setAttribute('contenteditable', 'false'); + // text_field.textContent = item.name; + // } - // reshow button - crimesList[i].show_button = true; - return; - } + // // reshow button + // crimesList[i].show_button = true; + // return; + // } async function handle_input(ev: KeyboardEvent, i: number) { let item = crimesList[i]; @@ -132,13 +125,13 @@
-

Vorgang {$page.params.vorgang}

+

Vorgang {vorgang}

- + --> + {/each} -- 2.43.0 From f87b106ad2c0a0cc1d00bd14df4218f6a490be9c Mon Sep 17 00:00:00 2001 From: mina Date: Thu, 26 Jun 2025 18:40:09 +0200 Subject: [PATCH 02/10] =?UTF-8?q?erstellt=20EditableItem=20=20mit=20fronte?= =?UTF-8?q?nd-error-handling=20eingef=C3=BCgt=20caselist,=20crimelist?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/lib/components/EditableItem.svelte | 123 +++++++++++++++ src/lib/components/ListItem.svelte | 85 ----------- src/lib/helper/error-utils.ts | 9 ++ src/routes/(angemeldet)/list/+page.svelte | 48 +++--- .../(token-based)/list/[vorgang]/+page.svelte | 144 +++++------------- 5 files changed, 196 insertions(+), 213 deletions(-) create mode 100644 src/lib/components/EditableItem.svelte delete mode 100644 src/lib/components/ListItem.svelte create mode 100644 src/lib/helper/error-utils.ts diff --git a/src/lib/components/EditableItem.svelte b/src/lib/components/EditableItem.svelte new file mode 100644 index 0000000..ada2542 --- /dev/null +++ b/src/lib/components/EditableItem.svelte @@ -0,0 +1,123 @@ + + +
+
+ {#if editing} + + {:else} + {value} + {#if !editing && editable} + + + {/if} + {/if} +
+ {#if editing && errors} +

{errors[0]}

+ {/if} +
diff --git a/src/lib/components/ListItem.svelte b/src/lib/components/ListItem.svelte deleted file mode 100644 index 0b5f0e8..0000000 --- a/src/lib/components/ListItem.svelte +++ /dev/null @@ -1,85 +0,0 @@ - - - -
- -
- {#if admin} - { - editName(); - }} - /> - - - - - {:else} - - {item.name} - - {/if} - -

{shortenFileSize(item.size)}

-
-
- -
diff --git a/src/lib/helper/error-utils.ts b/src/lib/helper/error-utils.ts new file mode 100644 index 0000000..eabfb86 --- /dev/null +++ b/src/lib/helper/error-utils.ts @@ -0,0 +1,9 @@ +export function validateInput(oldValue:string, value: string, options: { minLength?: number; existingNames?: string[] }) { + const errors: string[] = []; + + if (!value.trim()) errors.push('Feld darf nicht leer sein'); + if (options.existingNames?.includes(value) && oldValue !== value) + errors.push('Name existiert bereits'); + + return errors; +} diff --git a/src/routes/(angemeldet)/list/+page.svelte b/src/routes/(angemeldet)/list/+page.svelte index b730a95..2635462 100644 --- a/src/routes/(angemeldet)/list/+page.svelte +++ b/src/routes/(angemeldet)/list/+page.svelte @@ -1,11 +1,17 @@ -
+
{#if editing} {:else} - {value} + {inputValue} {#if !editing && editable} - {/if} diff --git a/src/lib/helper/error-utils.ts b/src/lib/helper/error-utils.ts index eabfb86..66cf1f2 100644 --- a/src/lib/helper/error-utils.ts +++ b/src/lib/helper/error-utils.ts @@ -1,9 +1,27 @@ -export function validateInput(oldValue:string, value: string, options: { minLength?: number; existingNames?: string[] }) { +/** + * + * @param oldValue + * @param inputValue + * @param options + * @returns + */ +export function validateNameInput(oldValue:string, inputValue: string, options: { minLength?: number; existingNames?: string[] }) { const errors: string[] = []; - if (!value.trim()) errors.push('Feld darf nicht leer sein'); - if (options.existingNames?.includes(value) && oldValue !== value) + if (!inputValue.trim()) errors.push('Feld darf nicht leer sein'); + if (options.existingNames?.includes(inputValue) && oldValue !== inputValue) errors.push('Name existiert bereits'); return errors; } + + +// siehe suche: fail + +// Button +// BaseInputField + +// fetch siehe b038 + +// api/list/vorgang/tatort/server.ts +// api/list/vorgang/server.ts diff --git a/src/routes/(angemeldet)/list/+page.svelte b/src/routes/(angemeldet)/list/+page.svelte index 2635462..5912182 100644 --- a/src/routes/(angemeldet)/list/+page.svelte +++ b/src/routes/(angemeldet)/list/+page.svelte @@ -60,15 +60,17 @@ (editingId = i)} + editStart={() => (editingId = i)} variant="casename" existings={caseList} - on:save={(e) => console.log('Gespeichert:', e.detail)} - on:delete={(e) => { - console.log('Gelöscht:', e.detail); - delete_item(e); + save={(data) => { + console.log('Gespeichert:', data); + }} + deleteItem={(data) => { + console.log('Gelöscht:', data); + delete_item(data.customEvent); }} >
diff --git a/src/routes/(token-based)/list/[vorgang]/+page.svelte b/src/routes/(token-based)/list/[vorgang]/+page.svelte index ef80e95..83ff4dd 100644 --- a/src/routes/(token-based)/list/[vorgang]/+page.svelte +++ b/src/routes/(token-based)/list/[vorgang]/+page.svelte @@ -134,13 +134,13 @@ (editingId = i)} + editStart={() => (editingId = i)} variant="crimename" existings={crimesList} - on:save={(e) => console.log('Gespeichert:', e.detail)} - on:delete={(e) => console.log('Gelöscht:', e.detail)} + save={(e) => console.log('Gespeichert:', e)} + deleteItem={(e) => console.log('Gelöscht:', e)} > {:else} Date: Tue, 8 Jul 2025 09:32:19 +0200 Subject: [PATCH 04/10] hochladen --- src/lib/components/EditableItem.svelte | 175 ++++++++---------- src/routes/(angemeldet)/list/+page.svelte | 102 +++++++--- .../(token-based)/list/[vorgang]/+page.svelte | 77 ++++---- src/routes/api/list/[[vorgang]]/+server.ts | 91 +++++++-- 4 files changed, 262 insertions(+), 183 deletions(-) diff --git a/src/lib/components/EditableItem.svelte b/src/lib/components/EditableItem.svelte index b55ba2a..e5405d8 100644 --- a/src/lib/components/EditableItem.svelte +++ b/src/lib/components/EditableItem.svelte @@ -1,126 +1,101 @@ -
-
- {#if editing} - - {:else} - {inputValue} - {#if !editing && editable} - - - {/if} - {/if} -
- {#if editing && errors} -

{errors[0]}

+
+ + + + {#if manualError || error} +

{manualError || error}

{/if}
diff --git a/src/routes/(angemeldet)/list/+page.svelte b/src/routes/(angemeldet)/list/+page.svelte index 5912182..e6b27b9 100644 --- a/src/routes/(angemeldet)/list/+page.svelte +++ b/src/routes/(angemeldet)/list/+page.svelte @@ -2,17 +2,23 @@ import Folder from '$lib/icons/Folder.svelte'; import EditableItem from '$lib/components/EditableItem.svelte'; - export let data; - export let editingId: number; - interface ListItem { name: string; token?: string; // add other properties as needed } + let { data } = $props(); + const caseList: ListItem[] = data.caseList; + //Variabeln für EditableItem + let names: string[] = $state(caseList.map((l) => l.name)); + let editedName: string = $state(''); + + function getNameById(list: ListItem[], id: number) { + return list[id].name; + } async function delete_item(ev: Event) { let delete_item = window.confirm('Bist du sicher?'); @@ -42,6 +48,51 @@ } } } + + async function handleSave(newName: string, oldName: string) { + console.log('Eltern, speichern erfolgreich', newName, oldName); + try { + const res = await fetch(`/api/list/${oldName}`, { + method: 'PUT', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ oldName, newName }) + }); + + if (!res.ok) { + const msg = await res.text(); + console.error('❌ Fehler beim Speichern:', msg); + } else { + console.log('✅ Erfolgreich gespeichert:', newName); + } + } catch (err) { + console.error('⚠️ Netzwerkfehler:', err); + } + } + + async function handleDelete(name: string) { + try { + const res = await fetch(`/api/list/${name}`, { + method: 'DELETE', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ name }) + }); + + if (!res.ok) { + const msg = await res.text(); + console.error('❌ Fehler beim Löschen:', msg); + } else { + console.log('🗑️ Erfolgreich gelöscht:', name); + // Optional: Lokale Liste aktualisieren + //S items = items.filter((item) => item.name !== name); + } + } catch (err) { + console.error('⚠️ Netzwerkfehler beim Löschen:', err); + } + }
@@ -52,33 +103,28 @@ diff --git a/src/routes/(token-based)/list/[vorgang]/+page.svelte b/src/routes/(token-based)/list/[vorgang]/+page.svelte index 83ff4dd..239d683 100644 --- a/src/routes/(token-based)/list/[vorgang]/+page.svelte +++ b/src/routes/(token-based)/list/[vorgang]/+page.svelte @@ -122,49 +122,48 @@ diff --git a/src/routes/api/list/[[vorgang]]/+server.ts b/src/routes/api/list/[[vorgang]]/+server.ts index 5a76090..dcd9078 100644 --- a/src/routes/api/list/[[vorgang]]/+server.ts +++ b/src/routes/api/list/[[vorgang]]/+server.ts @@ -1,24 +1,83 @@ import { client } from '$lib/minio'; +import type { RequestHandler } from '@sveltejs/kit'; +import { json } from '@sveltejs/kit'; -export async function DELETE({ params }) { - const vorgang = params.vorgang; - const object_list = await new Promise((resolve, reject) => { - const res = []; - const items_str = client.listObjects('tatort', vorgang, true); - items_str.on('data', (obj) => { - res.push(obj.name); - }); +// Beispiel-Datenquelle (ersetzen durch echte DB oder Datei) +let mockList = [ "202505-test-se", "Minas-TestVorgang", "Testing-Mina", "xyz-123" ]; - items_str.on('error', reject); +export const GET: RequestHandler = async ({ params }) => { + const { filename } = params; - items_str.on('end', async () => { - resolve(res); - }); - }); + // TODO: Datei lesen oder Datenbankabfrage + return json({ filename, list: mockList }); +}; - await client.removeObjects('tatort', object_list); +export const PUT: RequestHandler = async ({ request, params }) => { + const { filename } = params; + const { oldName, newName } = await request.json(); - return new Response(null, { status: 204 }); -} + if (!newName || !newName.trim()) { + return new Response('Ungültiger Name', { status: 400 }); + } + + const index = mockList.findIndex((name) => name === oldName); + if (index === -1) { + return new Response('Name nicht gefunden', { status: 404 }); + } + + if (mockList.includes(newName)) { + return new Response('Name existiert bereits', { status: 409 }); + } + + + console.log('📥 PUT-Request empfangen:', mockList); + mockList[index] = newName; + console.log('📄 Datei:', filename); + console.log('🔁 Umbenennen:', oldName, '→', newName, mockList); + +// return new Response(JSON.stringify({ success: true }), { status: 200 }); + + return json({ success: true, updated: newName }); +}; + +export const DELETE: RequestHandler = async ({ request, params }) => { + const { filename } = params; + const { name } = await request.json(); + + const index = mockList.findIndex((n) => n === name); + if (index === -1) { + return new Response('Name nicht gefunden', { status: 404 }); + } + + + console.log('📥 DELETE-Request empfangen:', mockList); + mockList.splice(index, 1); + console.log('📄 Datei:', filename); + console.log('🔁 gelöscht', mockList); + return json({ success: true, deleted: name }); +}; + +// export async function DELETE({ params }) { +// const vorgang = params.vorgang; + +// const object_list = await new Promise((resolve, reject) => { +// const res = []; +// const items_str = client.listObjects('tatort', vorgang, true); + +// items_str.on('data', (obj) => { +// res.push(obj.name); +// }); + +// items_str.on('error', reject); + +// items_str.on('end', async () => { +// resolve(res); +// }); +// }); + +// await client.removeObjects('tatort', object_list); + +// return new Response(null, { status: 204 }); +// } -- 2.43.0 From f5136c292401f05fef21185b5bc79768822e24d8 Mon Sep 17 00:00:00 2001 From: mina Date: Tue, 8 Jul 2025 14:48:06 +0200 Subject: [PATCH 05/10] zwischenstand: bug delete tatort --- src/lib/components/EditableItem.svelte | 6 +- src/routes/(angemeldet)/list/+page.svelte | 21 +++-- src/routes/(angemeldet)/tatorte/+page.svelte | 14 +-- .../list/[vorgang]/+page.server.ts | 1 + .../(token-based)/list/[vorgang]/+page.svelte | 94 +++++++++++++++---- src/routes/api/list/[[vorgang]]/+server.ts | 89 ++++++++++-------- src/routes/api/tatort/+server.ts | 39 +++++++- 7 files changed, 186 insertions(+), 78 deletions(-) diff --git a/src/lib/components/EditableItem.svelte b/src/lib/components/EditableItem.svelte index e5405d8..d762761 100644 --- a/src/lib/components/EditableItem.svelte +++ b/src/lib/components/EditableItem.svelte @@ -18,7 +18,6 @@ let names = list.map((l: ListItem) => l.name); let localName = $state(currentName); - //let names = list; let wasCancelled = $state(false); // Automatisch berechneter Fehler @@ -51,10 +50,11 @@ // Speichern, wenn gültig und zurück an Eltern function commitIfValid() { - if (!validateName(localName) && !wasCancelled && localName != currentName) { + if (!error && !wasCancelled && localName != currentName) { editedName = localName.trim(); onSave(editedName, currentName); //Eltern benachrichtigen } else { + localName = currentName; resetEdit(); } } @@ -74,7 +74,7 @@ commitIfValid(); } else if (event.key === 'Escape') { event.preventDefault(); - editedName = currentName; + localName = currentName; resetEdit(); } } diff --git a/src/routes/(angemeldet)/list/+page.svelte b/src/routes/(angemeldet)/list/+page.svelte index e6b27b9..ab4dc3b 100644 --- a/src/routes/(angemeldet)/list/+page.svelte +++ b/src/routes/(angemeldet)/list/+page.svelte @@ -1,6 +1,7 @@ +
Hallo

Vorgang {vorgang}

@@ -133,14 +193,11 @@
{#if admin} (editingId = i)} - variant="crimename" - existings={crimesList} - save={(e) => console.log('Gespeichert:', e)} - deleteItem={(e) => console.log('Gelöscht:', e)} + list={crimesList} + bind:editedName={names[i]} + currentName={item.name} + onSave={handleSave} + onDelete={handleDelete} > {:else} {/if}
+
{item.name}