diff --git a/src/lib/components/Button.svelte b/src/lib/components/Button.svelte
index 17974f3..2a2d25a 100644
--- a/src/lib/components/Button.svelte
+++ b/src/lib/components/Button.svelte
@@ -1,3 +1,31 @@
+
+
+{#if href}
+
+
+{:else}
+
+{/if}
+
-
-
-
-{#if href}
-
-
-{:else}
-
-{/if}
diff --git a/src/lib/components/EditableItem.svelte b/src/lib/components/EditableItem.svelte
index 33c49c9..8a3c07b 100644
--- a/src/lib/components/EditableItem.svelte
+++ b/src/lib/components/EditableItem.svelte
@@ -16,7 +16,6 @@
onDelete = () => {}
} = $props();
- let names = list.map((l: ListItem) => l.name);
let localName = $state(currentName);
let wasCancelled = $state(false);
@@ -46,6 +45,8 @@
function commitIfValid() {
if (!error && !wasCancelled && localName != currentName) {
editedName = localName.trim();
+ inputRef?.blur();
+ isEditing = false;
onSave(editedName, currentName);
} else {
localName = currentName;
diff --git a/src/lib/config.ts b/src/lib/config.ts
index 0775514..2e2bf34 100644
--- a/src/lib/config.ts
+++ b/src/lib/config.ts
@@ -1,3 +1,3 @@
import { readFileSync } from 'fs';
-export default JSON.parse(readFileSync('./config.json').toString());
+export default JSON.parse(readFileSync('./config_prod.json').toString());
diff --git a/src/lib/data/tatort.db b/src/lib/data/tatort.db
index a1e5df7..4fd1b06 100644
Binary files a/src/lib/data/tatort.db and b/src/lib/data/tatort.db differ
diff --git a/src/routes/(token-based)/list/[vorgang]/+page.server.ts b/src/routes/(token-based)/list/[vorgang]/+page.server.ts
deleted file mode 100644
index b8b54e0..0000000
--- a/src/routes/(token-based)/list/[vorgang]/+page.server.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { getVorgangByToken, getCrimesListByToken } from '$lib/server/vorgangService';
-import type { PageServerLoad } from './$types';
-
-export const load: PageServerLoad = async ({fetch, params, url }) => {
- const vorgangToken = params.vorgang;
- const vorgangPIN = url.searchParams.get('pin');
-
- const adminRes = await fetch(`/api/user`)
-const user = await adminRes.json()
-
- const crimesList = await getCrimesListByToken(vorgangToken); // TatortList zum Vorgang
- const vorgangObjekt = getVorgangByToken(vorgangToken); //einzelner Vorgang //TypeScript darf nicht undefined sein
-let vorgangName:string;
- if(vorgangObjekt){
-vorgangName = vorgangObjekt.name;
- }else{
- vorgangName = '';
- }
-
- return {
- crimesList, //crimesList
- vorgangPIN, //caseToken
- vorgangName, //caseId?
- vorgangObjekt,
- user
- };
-};
-
-
-// Ersetze diese Verbindung zum Server durch API Endpunkte
-
diff --git a/src/routes/(token-based)/list/[vorgang]/+page.svelte b/src/routes/(token-based)/list/[vorgang]/+page.svelte
index 143a061..31d2abb 100644
--- a/src/routes/(token-based)/list/[vorgang]/+page.svelte
+++ b/src/routes/(token-based)/list/[vorgang]/+page.svelte
@@ -9,77 +9,59 @@
import ModalContent from '$lib/components/Modal/ModalContent.svelte';
import ModalFooter from '$lib/components/Modal/ModalFooter.svelte';
import Cube from '$lib/icons/Cube.svelte';
-
import EditableItem from '$lib/components/EditableItem.svelte';
-
- import { invalidate } from '$app/navigation';
- import { page } from '$app/stores';
+ import { invalidate, invalidateAll } from '$app/navigation';
//Seite für die Tatort-Liste
let { data } = $props();
- console.log('tatorte: debug ', data);
+ console.log('tatorte: debug ', data); //zur besseren Nachvollziehbarkeit noch drin gelassen, kann vorm merge gelöscht werden
interface ListItem {
+ //sollte Typ Vorgang sein, aber der einfachheit ist es noch ListItem, damit die Komponente EditableItem für Vorgang und Tatort eingesetzt werden kann
name: string;
size: number;
lastModified: string | number | Date;
show_button?: boolean;
+ prefix?: string;
// add other properties as needed
}
- let vorgang: string = data.vorgangName; // let vorgang = data.caseId;
+ let vorgangName: string = data.vorgang.vorgangName; // let vorgang = data.caseId;
let crimesList: ListItem[] = $state(data.crimesList);
- const vorgangPIN: string = data.vorgangPIN; //caseToken?? // const token: string | null = data.caseToken;
+ const vorgangPIN: string = data.vorgang.vorgangPIN; //caseToken?? // const token: string | null = data.caseToken;
+ let vorgangToken: string = data.vorgang.vorgangToken;
//Variablen für Modal
let open = $state(false);
let inProgress = $state(false);
let err = $state(false);
- function uploadSuccessful() {
- open = false;
- }
- //Variabeln für EditableItem
- let names: string[] = $state(crimesList.map((l) => l.name));
- let editedName: string = $state('');
- let currentName: string = $state('');
-
- let editingId: number;
-
- // let admin = data?.user?.admin;
- let admin = true;
-
- let rename_input;
-
- $effect(() => {
- console.log('rename_input hat sich geändert:', rename_input);
- });
+ //Variable um nur admin UI anzuzeigen
+ let admin = data?.user?.admin;
async function handleSave(newName: string, oldName: string) {
- console.log('Eltern, speichern erfolgreich', newName, oldName);
+ open = true;
+ console.log('Eltern, speichern erfolgreich', newName, oldName); //zur besseren Nachvollziehbarkeit noch drin gelassen, kann vorm merge gelöscht werden
try {
- const res = await fetch(`/api/list/${vorgang}/${oldName}`, {
+ const res = await fetch(`/api/list/${vorgangToken}/${oldName}`, {
+ //irgendwas stimmt hier nicht, vorgangToken führt zu Fehler in API,
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
- body: JSON.stringify({ vorgang, oldName, newName })
+ body: JSON.stringify({ vorgangToken, oldName, newName })
});
- const clone = res.clone();
- const data = await res.json();
- let message = data.message;
- let error = !data.success;
-
- console.log('Tatort Update: ', message);
if (!res.ok) {
- const msg = await clone.text();
+ const msg = await res.text();
console.error('❌ Fehler beim Speichern:', msg);
} else {
- console.log('✅ Erfolgreich gespeichert:', newName);
- await invalidate('');
- currentName = newName;
+ await invalidate(`/api/list/${vorgangToken}`);
+ await invalidateAll();
+ crimesList = data.crimesList;
+ console.log('✅ Erfolgreich gespeichert:', crimesList, data.crimesList, newName); //zur besseren Nachvollziehbarkeit noch drin gelassen, kann vorm merge gelöscht werden
+ open = false;
}
} catch (err) {
console.error('⚠️ Netzwerkfehler:', err);
@@ -87,7 +69,7 @@
}
async function handleDelete(tatort: string) {
- let url = new URL($page.url);
+ let url = new URL(data.url);
url.pathname += `/${tatort}`;
console.log('Delete tatort: ', `/api${url.pathname}`, url.pathname);
@@ -97,7 +79,7 @@
headers: {
'Content-Type': 'application/json'
},
- body: JSON.stringify({ vorgang, tatort })
+ body: JSON.stringify({ vorgangToken, tatort })
});
if (!res.ok) {
@@ -105,255 +87,67 @@
console.error('❌ Fehler beim Löschen:', msg);
} else {
console.log('🗑️ Erfolgreich gelöscht:', url.pathname);
+ await invalidate(`/api/list/${vorgangToken}`);
+ await invalidateAll();
+ crimesList = data.crimesList;
}
} catch (err) {
console.error('⚠️ Netzwerkfehler beim Löschen:', err);
}
}
- // function defocus_element(i: number) {
- // let item = crimesList[i];
- // let text_field_id = `label__${item.name}`;
+ function constructMailToLink() {
+ const subject = 'Link zum Tatvorgang';
- // let text_field = document.getElementById(text_field_id);
- // if (text_field) {
- // text_field.setAttribute('contenteditable', 'false');
- // text_field.textContent = item.name;
- // }
+ const link = data.url.origin + data.url.pathname;
+ const body = `Hallo,
- // // reshow button
- // crimesList[i].show_button = true;
- // return;
- // }
+ hier ist der Link zum Tatvorgang:
+ ${link}
- // async function handleEditFieldInput(ev: KeyboardEvent, listItemIndex: number) {
- // let item = crimesList[listItemIndex];
- // if (ev.key == 'Escape') {
- // let text_field_id = `label__${item.name}`;
+ Der Zugangs-PIN wird zur Sicherheit über einen zweiten Kommunikationskanal übermittelt.
- // let text_field = document.getElementById(text_field_id);
- // if (text_field) {
- // text_field.setAttribute('contenteditable', 'false');
- // text_field.textContent = item.name;
- // }
+ Mit freundlichen Grüßen,
+ `;
- // // reshow button
- // item.show_button = true;
- // return;
- // }
- // if (ev.key == 'Enter') {
- // let name_field = ev.currentTarget as HTMLElement | null;
- // let new_name = name_field
- // ? name_field.textContent || (name_field as any).innerText || ''
- // : '';
+ const mailtoLink = `mailto:?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`;
- // if (new_name == '') {
- // alert('Bitte einen gültigen Namen eingeben.');
- // ev.preventDefault();
- // return;
- // }
+ return mailtoLink;
+ }
- // // actual upload
- // // -------------
-
- // // to prevent from item being selected
- // ev.preventDefault();
-
- // // construct PUT URL
- // const url = $page.url.pathname.split('?')[0];
-
- // let data_obj: { new_name: string; old_name: string } = { new_name: '', old_name: '' };
- // data_obj['new_name'] = new_name;
- // data_obj['old_name'] =
- // ev.currentTarget && (ev.currentTarget as HTMLElement).id
- // ? (ev.currentTarget as HTMLElement).id.split('__')[1]
- // : '';
-
- // open = true;
- // inProgress = true;
-
- // const response = await fetch(url, { method: 'PUT', body: JSON.stringify(data_obj) });
-
- // inProgress = false;
-
- // if (!response.ok) {
- // err = true;
- // if (response.status == 400) {
- // let json_res = await response.json();
- // return;
- // }
- // throw new Error(`Fehlgeschlagen: ${response.status}`);
- // } else {
- // uploadSuccessful();
- // setTimeout(() => {
- // window.location.reload();
- // }, 500);
- // }
-
- // // --- upload finished ---
-
- // return;
- // }
- // }
-
- // function constructMailToLink() {
- // const subject = 'Link zum Tatvorgang';
- // const link = $page.url.toString().split('?')[0];
- // const body = `Hallo,
-
- // hier ist der Link zum Tatvorgang:
- // ${link}
-
- // Der Zugangs-PIN wird zur Sicherheit über einen zweiten Kommunikationskanal übermittelt.
-
- // Mit freundlichen Grüßen,
- // `;
-
- // const mailtoLink = `mailto:?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`;
-
- // return mailtoLink;
- // }
+ function closeModal() {
+ open = false;
+ }
-{#if vorgang}
+{#if data.vorgang && data.crimesList}
-
Vorgang {vorgang}
+
Vorgang {vorgangName}
-
+ {#if admin}
+ Zugangs-PIN: {vorgangPIN}
+
+ {/if}
- {#each crimesList as item, crimeListItemIndex}
-
-
+ {#each data.crimesList as item, crimeListItemIndex}
-
{#if admin}
Fehler beim Umbenennen
{/if}
-
+
{/if}
diff --git a/src/routes/(token-based)/list/[vorgang]/+page.ts b/src/routes/(token-based)/list/[vorgang]/+page.ts
new file mode 100644
index 0000000..ab4cfaf
--- /dev/null
+++ b/src/routes/(token-based)/list/[vorgang]/+page.ts
@@ -0,0 +1,27 @@
+import { redirect } from '@sveltejs/kit';
+
+export async function load({fetch, params, url}){
+ const vorgangResponse = await fetch(`/api/list`);
+ const vorgangList = await vorgangResponse.json()
+ const vorgangToken = params.vorgang;
+ const crimesListResponse = await fetch(`/api/list/${vorgangToken}`)
+ const crimesList = await crimesListResponse.json();
+ const vorgang = vorgangList.find(v => v.vorgangToken === vorgangToken); //vorgang sollte ein eigener Typ werden, und dann kann man es hier vernünftig typisieren
+ if(!vorgang || !crimesList){
+ throw new Error(`Fehlgeschlagen, es wurden keine Daten zum token gefunden`);
+ }
+
+ //Variabeln für EditableItem
+ const crimeNames: string[] = crimesList.map((l) => l.name);
+
+ if (crimesList.length === 0) {
+ throw redirect(302, '/upload'); // weiterleiten auf die hinzufügen seite
+ }
+ return {
+ vorgang,
+ vorgangList,
+ crimesList,
+ url,
+ crimeNames
+ }
+}
diff --git a/src/routes/(token-based)/list/[vorgang]/+server.ts b/src/routes/(token-based)/list/[vorgang]/+server.ts
deleted file mode 100644
index b422976..0000000
--- a/src/routes/(token-based)/list/[vorgang]/+server.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import { client } from '$lib/minio';
-import { json } from '@sveltejs/kit';
-
-
-// rename operation for crimes
-export async function PUT({ request }: {request: Request}) {
- const data = await request.json();
-
- // Vorgang
- const vorgangToken = request.url.split('/').at(-1);
-
- // prepare copy, incl. check if new name exists already
- const crimeOldName = data["old_name"];
- const crimeS3FullBucketPathOld = `/tatort/${vorgangToken}/${crimeOldName}`;
- const crimeNewName = `${vorgangToken}/${data["new_name"]}`;
-
- try {
- await client.statObject('tatort', crimeNewName);
- return json({ msg: 'Die Datei existiert bereits.' }, { status: 400 });
- } catch (error) {
- // continue operation
- console.log(error, 'continue operation');
- }
-
- // actual copy operation
- await client.copyObject('tatort', crimeNewName, crimeS3FullBucketPathOld)
-
- // delete
- await client.removeObject('tatort', `${vorgangToken}/${crimeOldName}`)
-
- // return success or failure
-
- return json({ success: 'success' }, { status: 200 });
-};
diff --git a/src/routes/api/list/[vorgang]/[tatort]/+server.ts b/src/routes/api/list/[vorgang]/[tatort]/+server.ts
index e48da78..28db96c 100644
--- a/src/routes/api/list/[vorgang]/[tatort]/+server.ts
+++ b/src/routes/api/list/[vorgang]/[tatort]/+server.ts
@@ -1,5 +1,5 @@
import { BUCKET, client } from '$lib/minio';
-import { json, type RequestHandler } from '@sveltejs/kit';
+import { json } from '@sveltejs/kit';
import { getVorgangByName } from '$lib/server/vorgangService';
export async function GET() {
@@ -36,12 +36,13 @@ export async function DELETE({ request }: { request: Request }) {
}
// rename operation for crimes
-export async function PUT({ params, request }: { params: RequestHandler; request: Request }) {
+export async function PUT({ params, request }) {
const data = await request.json();
// Vorgang
- const vorgangName = params.vorgang;
- const vorgangToken = getVorgangByName(vorgangName)?.token;
+ const vorgangToken = params.vorgang;
+ //const vorgangToken = getVorgangByName(vorgangName)?.token;
+
// prepare copy, incl. check if new name exists already
const crimeOldName = data['oldName'];